Subversion Repositories Kolibri OS

Rev

Rev 261 | Go to most recent revision | Details | Compare with Previous | 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
302 hidnplayr 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
261 hidnplayr 14
PCI_BASE_ADDRESS_SPACE_IO   equ     0x01
302 hidnplayr 15
PCI_VENDOR_ID		    equ     0x00  ;16 bit
261 hidnplayr 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
302 hidnplayr 35
    or	    eax, 0x80000000
261 hidnplayr 36
    shl     ecx, 8
302 hidnplayr 37
    or	    eax, ecx
261 hidnplayr 38
    pop     ecx
302 hidnplayr 39
    or	    eax, edx
261 hidnplayr 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
302 hidnplayr 67
    in	    al, dx
261 hidnplayr 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
302 hidnplayr 94
    in	    ax, dx
261 hidnplayr 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
302 hidnplayr 119
    in	    eax, dx
261 hidnplayr 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
 
302 hidnplayr 193
    in	    al,0x61
261 hidnplayr 194
    and     al,0x10
195
    mov     ah,al
196
    cld
197
 
198
dcnt1:
302 hidnplayr 199
    in	    al,0x61
261 hidnplayr 200
    and     al,0x10
201
    cmp     al,ah
302 hidnplayr 202
    jz	    dcnt1
261 hidnplayr 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
 
302 hidnplayr 234
    xor     ebx, ebx	     ; ebx = bus# 0 .. 255
261 hidnplayr 235
 
236
sb_bus_loop:
302 hidnplayr 237
    xor     ecx, ecx	     ; ecx = devfn# 0 .. 254  ( not 255? )
261 hidnplayr 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
302 hidnplayr 262
    je	    sb_empty
261 hidnplayr 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
302 hidnplayr 276
    je	    sb_inc_devf 	       ; Quit if at last entry
261 hidnplayr 277
    cmp     eax, [esi]
302 hidnplayr 278
    je	    sb_got_card
261 hidnplayr 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
302 hidnplayr 298
    mov     eax, [esi+20]
299
    mov     [drvr_cable], eax
261 hidnplayr 300
    pop     eax
301
 
302
    mov     edx, PCI_BASE_ADDRESS_0
303
 
304
sb_reg_check:
305
    call    pcibios_read_config_dword
306
    mov     [io_addr], eax
307
    and     eax, PCI_BASE_ADDRESS_IO_MASK
308
    cmp     eax, 0
302 hidnplayr 309
    je	    sb_inc_reg
261 hidnplayr 310
    mov     eax, [io_addr]
311
    and     eax, PCI_BASE_ADDRESS_SPACE_IO
312
    cmp     eax, 0
302 hidnplayr 313
    je	    sb_inc_reg
261 hidnplayr 314
 
315
    mov     eax, [io_addr]
316
    and     eax, PCI_BASE_ADDRESS_IO_MASK
317
    mov     [io_addr], eax
318
 
319
sb_exit1:
320
    ret
321
 
322
sb_inc_reg:
323
    add     edx, 4
324
    cmp     edx, PCI_BASE_ADDRESS_5
325
    jbe     sb_reg_check
326
 
327
sb_inc_devf:
328
    inc     ecx
329
    cmp     ecx, 255
302 hidnplayr 330
    jb	    sb_devf_loop
261 hidnplayr 331
    inc     ebx
332
    cmp     ebx, 256
302 hidnplayr 333
    jb	    sb_bus_loop
261 hidnplayr 334
 
335
    ; We get here if we didn't find our card
336
    ; set io_addr to 0 as an indication
337
    xor     eax, eax
338
    mov     [io_addr], eax
339
 
340
sb_exit2:
341
    ret