Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
261 hidnplayr 1
;***************************************************************************
2
;
3
;  PCI CODE FOLLOWS
4
;
5
;  the following functions provide access to the PCI interface.
6
;  These functions are used by scan_bus, and also some ethernet drivers
7
;
8
;***************************************************************************
9
 
10
; PCI Bus defines
11
PCI_HEADER_TYPE             equ     0x0e  ;8 bit
12
PCI_BASE_ADDRESS_0          equ     0x10  ;32 bit
13
PCI_BASE_ADDRESS_5          equ     0x24  ;32 bits
14
PCI_BASE_ADDRESS_SPACE_IO   equ     0x01
15
PCI_VENDOR_ID               equ     0x00  ;16 bit
16
PCI_BASE_ADDRESS_IO_MASK    equ     0xFFFFFFFC
17
 
18
;***************************************************************************
19
;   Function
20
;      config_cmd
21
;
22
;   Description
23
;       creates a command dword  for use with the PCI bus
24
;       bus # in ebx
25
;      devfn in ecx
26
;       where in edx
27
;
28
;      command dword returned in eax
29
;       Only eax destroyed
30
;***************************************************************************
31
config_cmd:
32
    push    ecx
33
    mov     eax, ebx
34
    shl     eax, 16
35
    or      eax, 0x80000000
36
    shl     ecx, 8
37
    or      eax, ecx
38
    pop     ecx
39
    or      eax, edx
40
    and     eax, 0xFFFFFFFC
41
    ret
42
 
43
;***************************************************************************
44
;   Function
45
;      pcibios_read_config_byte
46
;
47
;   Description
48
;       reads a byte from the PCI config space
49
;       bus # in ebx
50
;      devfn in ecx
51
;       where in edx ( ls 16 bits significant )
52
;
53
;      byte returned in al ( rest of eax zero )
54
;       Only eax/edx destroyed
55
;***************************************************************************
56
pcibios_read_config_byte:
57
    call    config_cmd
58
    push    dx
59
    mov     dx, 0xCF8
60
    out     dx, eax
61
    pop     dx
62
 
63
    xor     eax, eax
64
    and     dx, 0x03
65
    add     dx, 0xCFC
66
;   and     dx, 0xFFC
67
    in      al, dx
68
    ret
69
 
70
;***************************************************************************
71
;   Function
72
;      pcibios_read_config_word
73
;
74
;   Description
75
;       reads a word from the PCI config space
76
;       bus # in ebx
77
;      devfn in ecx
78
;       where in edx ( ls 16 bits significant )
79
;
80
;      word returned in ax ( rest of eax zero )
81
;       Only eax/edx destroyed
82
;***************************************************************************
83
pcibios_read_config_word:
84
    call    config_cmd
85
    push    dx
86
    mov     dx, 0xCF8
87
    out     dx, eax
88
    pop     dx
89
 
90
    xor     eax, eax
91
    and     dx, 0x02
92
    add     dx, 0xCFC
93
;   and     dx, 0xFFC
94
    in      ax, dx
95
    ret
96
 
97
;***************************************************************************
98
;   Function
99
;      pcibios_read_config_dword
100
;
101
;   Description
102
;       reads a dword from the PCI config space
103
;       bus # in ebx
104
;      devfn in ecx
105
;       where in edx ( ls 16 bits significant )
106
;
107
;      dword returned in eax
108
;       Only eax/edx destroyed
109
;***************************************************************************
110
pcibios_read_config_dword:
111
    push    edx
112
    call    config_cmd
113
    push    dx
114
    mov     dx, 0xCF8
115
    out     dx, eax
116
    pop     dx
117
    xor     eax, eax
118
    mov     dx, 0xCFC
119
    in      eax, dx
120
    pop     edx
121
    ret
122
 
123
;***************************************************************************
124
;   Function
125
;      pcibios_write_config_byte
126
;
127
;   Description
128
;       write a byte in al to the PCI config space
129
;       bus # in ebx
130
;      devfn in ecx
131
;       where in edx ( ls 16 bits significant )
132
;
133
;       Only eax/edx destroyed
134
;***************************************************************************
135
pcibios_write_config_byte:
136
    push    ax
137
    call    config_cmd
138
    push    dx
139
    mov     dx, 0xCF8
140
    out     dx, eax
141
    pop     dx
142
    pop     ax
143
 
144
    and     dx, 0x03
145
    add     dx, 0xCFC
146
    out     dx, al
147
    ret
148
 
149
;***************************************************************************
150
;   Function
151
;      pcibios_write_config_word
152
;
153
;   Description
154
;       write a word in ax to the PCI config space
155
;       bus # in ebx
156
;      devfn in ecx
157
;       where in edx ( ls 16 bits significant )
158
;
159
;       Only eax/edx destroyed
160
;***************************************************************************
161
pcibios_write_config_word:
162
    push    ax
163
    call    config_cmd
164
    push    dx
165
    mov     dx, 0xCF8
166
    out     dx, eax
167
    pop     dx
168
    pop     ax
169
 
170
    and     dx, 0x02
171
    add     dx, 0xCFC
172
    out     dx, ax
173
    ret
174
 
175
;***************************************************************************
176
;   Function
177
;      delay_us
178
;
179
;   Description
180
;       delays for 30 to 60 us
181
;
182
;        I would prefer this routine to be able to delay for
183
;       a selectable number of microseconds, but this works for now.
184
;
185
;       If you know a better way to do 2us delay, pleae tell me!
186
;***************************************************************************
187
delay_us:
188
    push    eax
189
    push    ecx
190
 
191
    mov     ecx,2
192
 
193
    in      al,0x61
194
    and     al,0x10
195
    mov     ah,al
196
    cld
197
 
198
dcnt1:
199
    in      al,0x61
200
    and     al,0x10
201
    cmp     al,ah
202
    jz      dcnt1
203
 
204
    mov     ah,al
205
    loop    dcnt1
206
 
207
    pop     ecx
208
    pop     eax
209
 
210
    ret
211
 
212
;***************************************************************************
213
;   Function
214
;      scan_bus
215
;
216
;   Description
217
;       Scans the PCI bus for a supported device
218
;        If a supported device is found, the drvr_ variables are initialised
219
;       to that drivers functions ( as defined in the PCICards table)
220
;
221
;        io_addr   holds card I/O space. 32 bit, but only LS 16 bits valid
222
;        pci_data  holds the PCI vendor + device code
223
;       pci_dev   holds PCI bus dev #
224
;       pci_bus   holds PCI bus #
225
;
226
;        io_addr will be zero if no card found
227
;
228
;***************************************************************************
229
scan_bus:
230
    xor     eax, eax
231
    mov     [hdrtype], al
232
    mov     [pci_data], eax
233
 
234
    xor     ebx, ebx         ; ebx = bus# 0 .. 255
235
 
236
sb_bus_loop:
237
    xor     ecx, ecx         ; ecx = devfn# 0 .. 254  ( not 255? )
238
 
239
sb_devf_loop:
240
    mov     eax, ecx
241
    and     eax, 0x07
242
 
243
    cmp     eax, 0
244
    jne     sb_001
245
 
246
    mov     edx, PCI_HEADER_TYPE
247
    call    pcibios_read_config_byte
248
    mov     [hdrtype], al
249
    jmp     sb_002
250
 
251
sb_001:
252
    mov     al, [hdrtype]
253
    and     al, 0x80
254
    cmp     al, 0x80
255
    jne     sb_inc_devf
256
 
257
sb_002:
258
    mov     edx, PCI_VENDOR_ID
259
    call    pcibios_read_config_dword
260
    mov     [vendor_device], eax
261
    cmp     eax, 0xffffffff
262
    je      sb_empty
263
    cmp     eax, 0
264
    jne     sb_check_vendor
265
 
266
sb_empty:
267
    mov     [hdrtype], byte 0
268
    jmp     sb_inc_devf
269
 
270
sb_check_vendor:
271
    ; iterate though PCICards until end or match found
272
    mov     esi, PCICards
273
 
274
sb_check:
275
    cmp     [esi], dword 0
276
    je      sb_inc_devf                ; Quit if at last entry
277
    cmp     eax, [esi]
278
    je      sb_got_card
279
    add     esi, PCICARDS_ENTRY_SIZE
280
    jmp     sb_check
281
 
282
sb_got_card:
283
    ; indicate that we have found the card
284
    mov     [pci_data], eax
285
    mov     [pci_dev], ecx
286
    mov     [pci_bus], ebx
287
 
288
    ; Define the driver functions
289
    push    eax
290
    mov     eax, [esi+4]
291
    mov     [drvr_probe], eax
292
    mov     eax, [esi+8]
293
    mov     [drvr_reset], eax
294
    mov     eax, [esi+12]
295
    mov     [drvr_poll], eax
296
    mov     eax, [esi+16]
297
    mov     [drvr_transmit], eax
298
    pop     eax
299
 
300
    mov     edx, PCI_BASE_ADDRESS_0
301
 
302
sb_reg_check:
303
    call    pcibios_read_config_dword
304
    mov     [io_addr], eax
305
    and     eax, PCI_BASE_ADDRESS_IO_MASK
306
    cmp     eax, 0
307
    je      sb_inc_reg
308
    mov     eax, [io_addr]
309
    and     eax, PCI_BASE_ADDRESS_SPACE_IO
310
    cmp     eax, 0
311
    je      sb_inc_reg
312
 
313
    mov     eax, [io_addr]
314
    and     eax, PCI_BASE_ADDRESS_IO_MASK
315
    mov     [io_addr], eax
316
 
317
sb_exit1:
318
    ret
319
 
320
sb_inc_reg:
321
    add     edx, 4
322
    cmp     edx, PCI_BASE_ADDRESS_5
323
    jbe     sb_reg_check
324
 
325
sb_inc_devf:
326
    inc     ecx
327
    cmp     ecx, 255
328
    jb      sb_devf_loop
329
    inc     ebx
330
    cmp     ebx, 256
331
    jb      sb_bus_loop
332
 
333
    ; We get here if we didn't find our card
334
    ; set io_addr to 0 as an indication
335
    xor     eax, eax
336
    mov     [io_addr], eax
337
 
338
sb_exit2:
339
    ret