Subversion Repositories Kolibri OS

Rev

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

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