Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
593 mikedld 8
$Revision: 2465 $
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
2434 Serge 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
2434 Serge 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:
2434 Serge 42
        push    ecx
43
        mov     eax, ebx
44
        shl     eax, 16
45
        or      eax, 0x80000000
46
        shl     ecx, 8
47
        or      eax, ecx
48
        pop     ecx
49
        or      eax, edx
50
        and     eax, 0xFFFFFFFC
51
        ret
261 hidnplayr 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:
2434 Serge 67
        call    config_cmd
68
        push    dx
69
        mov     dx, 0xCF8
70
        out     dx, eax
71
        pop     dx
261 hidnplayr 72
 
2434 Serge 73
        xor     eax, eax
74
        and     dx, 0x03
75
        add     dx, 0xCFC
261 hidnplayr 76
;   and     dx, 0xFFC
2434 Serge 77
        in      al, dx
78
        ret
261 hidnplayr 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:
2434 Serge 94
        call    config_cmd
95
        push    dx
96
        mov     dx, 0xCF8
97
        out     dx, eax
98
        pop     dx
261 hidnplayr 99
 
2434 Serge 100
        xor     eax, eax
101
        and     dx, 0x02
102
        add     dx, 0xCFC
261 hidnplayr 103
;   and     dx, 0xFFC
2434 Serge 104
        in      ax, dx
105
        ret
261 hidnplayr 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:
2434 Serge 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
129
        in      eax, dx
130
        pop     edx
131
        ret
261 hidnplayr 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:
2434 Serge 146
        push    ax
147
        call    config_cmd
148
        push    dx
149
        mov     dx, 0xCF8
150
        out     dx, eax
151
        pop     dx
152
        pop     ax
261 hidnplayr 153
 
2434 Serge 154
        and     dx, 0x03
155
        add     dx, 0xCFC
156
        out     dx, al
157
        ret
261 hidnplayr 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:
2434 Serge 172
        push    ax
173
        call    config_cmd
174
        push    dx
175
        mov     dx, 0xCF8
176
        out     dx, eax
177
        pop     dx
178
        pop     ax
261 hidnplayr 179
 
2434 Serge 180
        and     dx, 0x02
181
        add     dx, 0xCFC
182
        out     dx, ax
183
        ret
261 hidnplayr 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:
2434 Serge 198
        push    eax
199
        push    ecx
261 hidnplayr 200
 
2434 Serge 201
        mov     ecx, 2
261 hidnplayr 202
 
2434 Serge 203
        in      al, 0x61
204
        and     al, 0x10
205
        mov     ah, al
206
        cld
261 hidnplayr 207
 
208
dcnt1:
2434 Serge 209
        in      al, 0x61
210
        and     al, 0x10
211
        cmp     al, ah
212
        jz      dcnt1
261 hidnplayr 213
 
2434 Serge 214
        mov     ah, al
215
        loop    dcnt1
261 hidnplayr 216
 
2434 Serge 217
        pop     ecx
218
        pop     eax
261 hidnplayr 219
 
2434 Serge 220
        ret
261 hidnplayr 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:
2434 Serge 240
        xor     eax, eax
241
        mov     [hdrtype], al
242
        mov     [pci_data], eax
261 hidnplayr 243
 
2434 Serge 244
        xor     ebx, ebx     ; ebx = bus# 0 .. 255
261 hidnplayr 245
 
246
sb_bus_loop:
2434 Serge 247
        xor     ecx, ecx     ; ecx = devfn# 0 .. 254  ( not 255? )
261 hidnplayr 248
 
249
sb_devf_loop:
2434 Serge 250
        mov     eax, ecx
251
        and     eax, 0x07
261 hidnplayr 252
 
2434 Serge 253
        cmp     eax, 0
254
        jne     sb_001
261 hidnplayr 255
 
2434 Serge 256
        mov     edx, PCI_HEADER_TYPE
257
        call    pcibios_read_config_byte
258
        mov     [hdrtype], al
259
        jmp     sb_002
261 hidnplayr 260
 
261
sb_001:
2434 Serge 262
        mov     al, [hdrtype]
263
        and     al, 0x80
264
        cmp     al, 0x80
265
        jne     sb_inc_devf
261 hidnplayr 266
 
267
sb_002:
2434 Serge 268
        mov     edx, PCI_VENDOR_ID
269
        call    pcibios_read_config_dword
270
        mov     [vendor_device], eax
271
        cmp     eax, 0xffffffff
272
        je      sb_empty
273
        cmp     eax, 0
274
        jne     sb_check_vendor
261 hidnplayr 275
 
276
sb_empty:
2434 Serge 277
        mov     [hdrtype], byte 0
278
        jmp     sb_inc_devf
261 hidnplayr 279
 
280
sb_check_vendor:
281
    ; iterate though PCICards until end or match found
2434 Serge 282
        mov     esi, PCICards
261 hidnplayr 283
 
284
sb_check:
2434 Serge 285
        cmp     [esi], dword 0
286
        je      sb_inc_devf            ; Quit if at last entry
287
        cmp     eax, [esi]
288
        je      sb_got_card
289
        add     esi, PCICARDS_ENTRY_SIZE
290
        jmp     sb_check
261 hidnplayr 291
 
292
sb_got_card:
293
    ; indicate that we have found the card
2434 Serge 294
        mov     [pci_data], eax
295
        mov     [pci_dev], ecx
296
        mov     [pci_bus], ebx
261 hidnplayr 297
 
298
    ; Define the driver functions
2434 Serge 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
308
        mov     eax, [esi+20]
309
        mov     [drvr_cable], eax
310
        pop     eax
261 hidnplayr 311
 
2434 Serge 312
        mov     edx, PCI_BASE_ADDRESS_0
261 hidnplayr 313
 
314
sb_reg_check:
2434 Serge 315
        call    pcibios_read_config_dword
316
        mov     [io_addr], eax
317
        and     eax, PCI_BASE_ADDRESS_IO_MASK
318
        cmp     eax, 0
319
        je      sb_inc_reg
320
        mov     eax, [io_addr]
321
        and     eax, PCI_BASE_ADDRESS_SPACE_IO
322
        cmp     eax, 0
323
        je      sb_inc_reg
261 hidnplayr 324
 
2434 Serge 325
        mov     eax, [io_addr]
326
        and     eax, PCI_BASE_ADDRESS_IO_MASK
327
        mov     [io_addr], eax
261 hidnplayr 328
 
329
sb_exit1:
2434 Serge 330
        ret
261 hidnplayr 331
 
332
sb_inc_reg:
2434 Serge 333
        add     edx, 4
334
        cmp     edx, PCI_BASE_ADDRESS_5
335
        jbe     sb_reg_check
261 hidnplayr 336
 
337
sb_inc_devf:
2434 Serge 338
        inc     ecx
339
        cmp     ecx, 255
340
        jb      sb_devf_loop
341
        inc     ebx
342
        cmp     ebx, 256
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
2434 Serge 347
        xor     eax, eax
348
        mov     [io_addr], eax
261 hidnplayr 349
 
350
sb_exit2:
2434 Serge 351
        ret