Subversion Repositories Kolibri OS

Rev

Rev 302 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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