summaryrefslogtreecommitdiffstats
path: root/private/ntos/boot/detect/i386/hwpcia.asm
blob: f888d204bb7f0144f7a064b24582e3b0e273f158 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
        title  "PCI bus Support Assembley Code"
;++
;
; Copyright (c) 1989  Microsoft Corporation
;
; Module Name:
;
;    hwpcia.asm
;
; Abstract:
;
;   Calls the PCI rom function to determine what type of PCI
;   support is prsent, if any.
;
;   Base code provided by Intel
;
; Author:
;
;--


.386p
        .xlist
include hwpci.inc
        .list

if DBG
        extrn   _BlPrint:PROC
endif

_DATA   SEGMENT PARA USE16 PUBLIC 'DATA'

if DBG
cr  equ 11

PciBIOSSig          db  'PCI: Scanning for "PCI "', cr, 0
PciBIOSSigNotFound  db  'PCI: BIOS "PCI " not found', cr, 0


PciInt              db  'PCI: Calling PCI_BIOS_PRESENT', cr, 0
PciIntFailed        db  'PCI: PCI_BIOS_PRESENT returned carry', cr, 0
PciIntAhFailed      db  'PCI: PCI_BIOS_PRESENT returned bad AH value', cr, 0
PciIDFailed         db  'PCI: PCI_BIOS_PRESENT invalid PCI id', cr, 0
PciInt10IdFailed    db  'PCI: PCI10_BIOS_PRESENT invalid PCI id', cr, 0

PciFound            db  'PCI BUS FOUND', cr, 0
endif

_DATA   ends


_TEXT   SEGMENT PARA USE16 PUBLIC 'CODE'
        ASSUME  CS: _TEXT

;++
;
; BOOLEAN
; HwGetPciSystemData (
;    PPCI_SYSTEM_DATA PciSystemData
;    )
;
; Routine Description:
;
;    This function retrieves the PCI System Data
;
; Arguments:
;
;    PciSystemData - Supplies a pointer to the structure which will
;                      receive the PCI System Data.
;
; Return Value:
;
;    True - PCI System Detected and System Data valid
;    False - PCI System Not Detected
;
;--

SystemInfoPointer     equ     [bp + 4]
BiosDateFound         equ     [bp + 6]

        public  _HwGetPciSystemData
_HwGetPciSystemData       proc
        push    bp                      ; The following INT 15H destroies
        mov     bp, sp                  ;   ALL the general registers.
        push    si
        push    di
        push    bx
;
; Set for no PCI buses present
;

        mov     bx, SystemInfoPointer
        mov     byte ptr [bx].NoBuses, 0

;
; Is the BIOS date >= 11/01/92?   If so, make the int-1a call
;
        push    ds
        cmp     byte ptr [BiosDateFound], 0
        jnz     gpci00

;
; A valid BIOS date was not found, check for "PCI " in bios code.
;

if DBG
        push    offset PciBIOSSig
        call    _BlPrint
        add     sp, 2
endif
        mov     bx, 0f000h
        mov     ds, bx
        mov     bx, 0fffch

spci05: cmp     dword ptr ds:[bx], ' ICP'   ; 'PCI ' found at this addr?
        je      short gpci00                ; found

        dec     bx                          ; next location
        jnz     short spci05                ; loop
        jmp     spci_notfound               ; wrapped, all done - not found

gpci00:
        pop     ds

if DBG
        push    offset PciInt
        call    _BlPrint
        add     sp, 2
endif
;
; Check for a PCI system.  Issue the PCI Present request.
;

        mov     ax, PCI_BIOS_PRESENT        ; Real Mode Presence Request
        int     PCI_INTERFACE_INT           ; Just Do It!

        jc      gpci10                      ; Carry Set => No PCI

        cmp     ah, 0                       ; If PCI Present AH == 0
        jne     gpci12                      ; AH != 0 => No PCI

        cmp     edx, " ICP"                 ; "PCI" Backwards (with a trailing space)
        jne     gpci14                      ; PCI Signature in EDX => PCI Exists

;
; Found PCI BIOS Version > 1.0
;
; The only thing left to do is squirrel the data away for the caller
;

        mov     dx, bx                              ; Save revision level
        mov     bx, SystemInfoPointer               ; Get caller's Pointer

        mov     byte ptr [bx].MajorRevision, dh
        mov     byte ptr [bx].MinorRevision, dl
        inc     cl                                  ; NoBuses = LastBus+1

if 0
;
; Some PIC BIOS returns very large number of NoBuses.  As a work-
; around we mask the value to 16, unless the BIOS also return CH as
; neg cl then we believe it.
;

        cmp     cl, 16
        jbe     short @f

        neg     ch
        inc     ch
        cmp     cl, ch
        je      short @f

        mov     cl, 16
@@:
endif


        mov     byte ptr [bx].NoBuses, cl
        mov     byte ptr [bx].HwMechanism, al
        jmp     Done                                ; We're done

if DBG
gpci10: mov     ax, offset PciIntFailed
        jmp     short gpci_oldbios

gpci12: mov     ax, offset PciIntAhFailed
        jmp     short gpci_oldbios

gpci14: mov     ax, offset PciIDFailed
gpci_oldbios:
        push    ax
        call    _BlPrint
        add     sp, 2

else

gpci10:
gpci12:
gpci14:

endif


    ;
    ; Look for BIOS Version 1.0,  This has a different function #
    ;

        mov     ax, PCI10_BIOS_PRESENT      ; Real Mode Presence Request
        int     PCI_INTERFACE_INT           ; Just Do It!

    ; Version 1.0 has "PCI " in dx and cx, the Version number in ax, and the
    ; carry flag cleared.  These are all the indications available.
    ;

        cmp     dx, "CP"                    ; "PC" Backwards
        jne     gpci50                      ; PCI Signature not in DX & CX => No PCI

        cmp     cx, " I"                    ; "I " Backwards
        jne     gpci50                      ; PCI Signature not in EDX => No PCI

;
; Found PCI BIOS Version 1.0
;
; The only thing left to do is squirrel the data away for the caller
;

        mov     bx, SystemInfoPointer       ; Get caller's Pointer

        mov     byte ptr [bx].MajorRevision, ah
        mov     byte ptr [bx].MinorRevision, al

    ;
    ;  The Version 1.0 BIOS is only on early HW that had couldn't support
    ;  Multi Function devices or multiple bus's.  So without reading any
    ;  device data, mark it as such.
    ;

        mov     byte ptr [bx].HwMechanism, 2
        mov     byte ptr [bx].NoBuses, 1
        jmp     Done


spci_notfound:
        pop     ds                      ; restore ds
if DBG
        push    offset PciBIOSSigNotFound
        call    _BlPrint
        add     sp, 2
endif
        jmp     gpci_exit


if DBG
gpci50: push    offset PciInt10IdFailed
        jmp     Done10

Done:   push    offset PciFound
Done10: call    _BlPrint
        add     sp, 2

else

; non-debug no prints
gpci50:
Done:

endif

gpci_exit:
        pop     bx
        pop     di
        pop     si
        pop     bp
        ret

_HwGetPciSystemData       endp

_TEXT   ends
        end