Subversion Repositories Kolibri OS

Rev

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

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