Rev 1612 | Rev 1629 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
431 | serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
586 | serge | 2 | ;; ;; |
1602 | art_zh | 3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
431 | serge | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; ;; |
||
586 | serge | 7 | ;; PCI32.INC ;; |
8 | ;; ;; |
||
9 | ;; 32 bit PCI driver code ;; |
||
10 | ;; ;; |
||
11 | ;; Version 0.3 April 9, 2007 ;; |
||
12 | ;; Version 0.2 December 21st, 2002 ;; |
||
13 | ;; ;; |
||
14 | ;; Author: Victor Prodan, victorprodan@yahoo.com ;; |
||
15 | ;; Mihailov Ilia, ghost.nsk@gmail.com ;; |
||
16 | ;; Credits: ;; |
||
17 | ;; Ralf Brown ;; |
||
18 | ;; Mike Hibbett, mikeh@oceanfree.net ;; |
||
19 | ;; ;; |
||
20 | ;; See file COPYING for details ;; |
||
21 | ;; ;; |
||
431 | serge | 22 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ha | 23 | |
750 | victor | 24 | $Revision: 1614 $ |
1 | ha | 25 | |
26 | ;*************************************************************************** |
||
27 | ; Function |
||
28 | ; pci_api: |
||
29 | ; |
||
30 | ; Description |
||
31 | ; entry point for system PCI calls |
||
32 | ;*************************************************************************** |
||
1603 | art_zh | 33 | ;mmio_pci_addr equ 0x400 ; set actual PCI address here to activate user-MMIO |
1 | ha | 34 | |
1591 | lrz | 35 | iglobal |
36 | align 4 |
||
37 | f62call: |
||
1602 | art_zh | 38 | dd pci_fn_0 |
39 | dd pci_fn_1 |
||
40 | dd pci_fn_2 |
||
41 | dd pci_service_not_supported ;3 |
||
1591 | lrz | 42 | dd pci_read_reg ;4 byte |
1603 | art_zh | 43 | dd pci_read_reg ;5 word |
44 | dd pci_read_reg ;6 dword |
||
45 | dd pci_service_not_supported ;7 |
||
46 | dd pci_write_reg ;8 byte |
||
47 | dd pci_write_reg ;9 word |
||
48 | dd pci_write_reg ;10 dword |
||
1591 | lrz | 49 | if defined mmio_pci_addr |
50 | dd pci_mmio_init ;11 |
||
51 | dd pci_mmio_map ;12 |
||
52 | dd pci_mmio_unmap ;13 |
||
53 | end if |
||
1602 | art_zh | 54 | |
1591 | lrz | 55 | endg |
1370 | art_zh | 56 | |
1602 | art_zh | 57 | align 4 |
1591 | lrz | 58 | |
1 | ha | 59 | pci_api: |
60 | |||
1602 | art_zh | 61 | ;cross |
1614 | serge | 62 | mov eax,ebx |
1602 | art_zh | 63 | mov ebx,ecx |
64 | mov ecx,edx |
||
65 | |||
1614 | serge | 66 | align 4 |
67 | pci_api_drv: |
||
68 | |||
69 | cmp [pci_access_enabled],1 |
||
70 | jne pci_service_not_supported |
||
71 | |||
72 | movzx edx, al |
||
73 | |||
1591 | lrz | 74 | if defined mmio_pci_addr |
1614 | serge | 75 | cmp al, 13 |
1603 | art_zh | 76 | ja pci_service_not_supported |
1591 | lrz | 77 | else |
1614 | serge | 78 | cmp al, 10 |
1603 | art_zh | 79 | ja pci_service_not_supported |
1602 | art_zh | 80 | end if |
1603 | art_zh | 81 | |
82 | call dword [f62call+edx*4] |
||
83 | mov dword [esp+32],eax |
||
84 | ret |
||
1602 | art_zh | 85 | ;; ============================================ |
1591 | lrz | 86 | |
1602 | art_zh | 87 | pci_fn_0: |
88 | ; PCI function 0: get pci version (AH.AL) |
||
89 | movzx eax,word [BOOT_VAR+0x9022] |
||
1348 | art_zh | 90 | ret |
1 | ha | 91 | |
1602 | art_zh | 92 | pci_fn_1: |
93 | ; PCI function 1: get last bus in AL |
||
94 | mov al,[BOOT_VAR+0x9021] |
||
1348 | art_zh | 95 | ret |
1 | ha | 96 | |
1602 | art_zh | 97 | pci_fn_2: |
98 | ; PCI function 2: get pci access mechanism |
||
99 | mov al,[BOOT_VAR+0x9020] |
||
1348 | art_zh | 100 | ret |
1 | ha | 101 | |
1602 | art_zh | 102 | pci_service_not_supported: |
103 | or eax,-1 |
||
1603 | art_zh | 104 | mov dword [esp+32],eax |
1348 | art_zh | 105 | ret |
1 | ha | 106 | |
107 | ;*************************************************************************** |
||
108 | ; Function |
||
109 | ; pci_make_config_cmd |
||
110 | ; |
||
111 | ; Description |
||
112 | ; creates a command dword for use with the PCI bus |
||
1602 | art_zh | 113 | ; bus # in ah |
114 | ; device+func in bh (dddddfff) |
||
115 | ; register in bl |
||
1 | ha | 116 | ; |
1602 | art_zh | 117 | ; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 ) |
1 | ha | 118 | ;*************************************************************************** |
119 | |||
120 | align 4 |
||
121 | |||
122 | pci_make_config_cmd: |
||
1602 | art_zh | 123 | shl eax,8 ; move bus to bits 16-23 |
124 | mov ax,bx ; combine all |
||
125 | and eax,0xffffff |
||
126 | or eax,0x80000000 |
||
1 | ha | 127 | ret |
128 | |||
129 | ;*************************************************************************** |
||
130 | ; Function |
||
131 | ; pci_read_reg: |
||
132 | ; |
||
133 | ; Description |
||
134 | ; read a register from the PCI config space into EAX/AX/AL |
||
1602 | art_zh | 135 | ; IN: ah=bus,device+func=bh,register address=bl |
136 | ; number of bytes to read (1,2,4) coded into AL, bits 0-1 |
||
586 | serge | 137 | ; (0 - byte, 1 - word, 2 - dword) |
1 | ha | 138 | ;*************************************************************************** |
139 | |||
140 | align 4 |
||
141 | |||
142 | pci_read_reg: |
||
1348 | art_zh | 143 | cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use? |
144 | je pci_read_reg_2 |
||
1 | ha | 145 | |
1348 | art_zh | 146 | ; mechanism 1 |
1602 | art_zh | 147 | push esi ; save register size into ESI |
148 | mov esi,eax |
||
1348 | art_zh | 149 | and esi,3 |
1 | ha | 150 | |
1348 | art_zh | 151 | call pci_make_config_cmd |
1602 | art_zh | 152 | mov ebx,eax |
1348 | art_zh | 153 | ; get current state |
154 | mov dx,0xcf8 |
||
155 | in eax, dx |
||
156 | push eax |
||
157 | ; set up addressing to config data |
||
158 | mov eax,ebx |
||
159 | and al,0xfc ; make address dword-aligned |
||
160 | out dx,eax |
||
161 | ; get requested DWORD of config data |
||
162 | mov dl,0xfc |
||
163 | and bl,3 |
||
164 | or dl,bl ; add to port address first 2 bits of register address |
||
1 | ha | 165 | |
1602 | art_zh | 166 | or esi,esi |
167 | jz pci_read_byte1 |
||
168 | cmp esi,1 |
||
169 | jz pci_read_word1 |
||
170 | cmp esi,2 |
||
171 | jz pci_read_dword1 |
||
172 | jmp pci_fin_read1 |
||
1 | ha | 173 | |
1602 | art_zh | 174 | pci_read_byte1: |
1348 | art_zh | 175 | in al,dx |
1602 | art_zh | 176 | jmp pci_fin_read1 |
177 | pci_read_word1: |
||
1348 | art_zh | 178 | in ax,dx |
1602 | art_zh | 179 | jmp pci_fin_read1 |
180 | pci_read_dword1: |
||
1348 | art_zh | 181 | in eax,dx |
1602 | art_zh | 182 | jmp pci_fin_read1 |
183 | pci_fin_read1: |
||
1348 | art_zh | 184 | ; restore configuration control |
185 | xchg eax,[esp] |
||
186 | mov dx,0xcf8 |
||
187 | out dx,eax |
||
1 | ha | 188 | |
1348 | art_zh | 189 | pop eax |
1602 | art_zh | 190 | pop esi |
1348 | art_zh | 191 | ret |
1 | ha | 192 | pci_read_reg_2: |
193 | |||
1602 | art_zh | 194 | test bh,128 ;mech#2 only supports 16 devices per bus |
195 | jnz pci_read_reg_err |
||
1 | ha | 196 | |
1602 | art_zh | 197 | push esi ; save register size into ESI |
198 | mov esi,eax |
||
1348 | art_zh | 199 | and esi,3 |
1 | ha | 200 | |
1602 | art_zh | 201 | push eax |
1348 | art_zh | 202 | ;store current state of config space |
203 | mov dx,0xcf8 |
||
204 | in al,dx |
||
205 | mov ah,al |
||
206 | mov dl,0xfa |
||
207 | in al,dx |
||
1 | ha | 208 | |
1348 | art_zh | 209 | xchg eax,[esp] |
210 | ; out 0xcfa,bus |
||
211 | mov al,ah |
||
212 | out dx,al |
||
213 | ; out 0xcf8,0x80 |
||
214 | mov dl,0xf8 |
||
215 | mov al,0x80 |
||
216 | out dx,al |
||
217 | ; compute addr |
||
1602 | art_zh | 218 | shr bh,3 ; func is ignored in mechanism 2 |
219 | or bh,0xc0 |
||
220 | mov dx,bx |
||
1 | ha | 221 | |
1602 | art_zh | 222 | or esi,esi |
223 | jz pci_read_byte2 |
||
224 | cmp esi,1 |
||
225 | jz pci_read_word2 |
||
226 | cmp esi,2 |
||
227 | jz pci_read_dword2 |
||
228 | jmp pci_fin_read2 |
||
1 | ha | 229 | |
1602 | art_zh | 230 | pci_read_byte2: |
1348 | art_zh | 231 | in al,dx |
1602 | art_zh | 232 | jmp pci_fin_read2 |
233 | pci_read_word2: |
||
1348 | art_zh | 234 | in ax,dx |
1602 | art_zh | 235 | jmp pci_fin_read2 |
236 | pci_read_dword2: |
||
1348 | art_zh | 237 | in eax,dx |
1 | ha | 238 | ; jmp pci_fin_read2 |
1602 | art_zh | 239 | pci_fin_read2: |
1 | ha | 240 | |
1348 | art_zh | 241 | ; restore configuration space |
242 | xchg eax,[esp] |
||
243 | mov dx,0xcfa |
||
244 | out dx,al |
||
245 | mov dl,0xf8 |
||
246 | mov al,ah |
||
247 | out dx,al |
||
1 | ha | 248 | |
1348 | art_zh | 249 | pop eax |
1602 | art_zh | 250 | pop esi |
1348 | art_zh | 251 | ret |
1 | ha | 252 | |
1602 | art_zh | 253 | pci_read_reg_err: |
254 | xor eax,eax |
||
255 | dec eax |
||
256 | ret |
||
1 | ha | 257 | |
258 | |||
259 | ;*************************************************************************** |
||
260 | ; Function |
||
261 | ; pci_write_reg: |
||
262 | ; |
||
263 | ; Description |
||
264 | ; write a register from ECX/CX/CL into the PCI config space |
||
1602 | art_zh | 265 | ; IN: ah=bus,device+func=bh,register address (dword aligned)=bl, |
266 | ; value to write in ecx |
||
267 | ; number of bytes to write (1,2,4) coded into AL, bits 0-1 |
||
586 | serge | 268 | ; (0 - byte, 1 - word, 2 - dword) |
1 | ha | 269 | ;*************************************************************************** |
270 | |||
271 | align 4 |
||
272 | |||
273 | pci_write_reg: |
||
1348 | art_zh | 274 | cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use? |
275 | je pci_write_reg_2 |
||
1 | ha | 276 | |
1348 | art_zh | 277 | ; mechanism 1 |
1602 | art_zh | 278 | push esi ; save register size into ESI |
279 | mov esi,eax |
||
280 | and esi,3 |
||
1 | ha | 281 | |
1348 | art_zh | 282 | call pci_make_config_cmd |
1602 | art_zh | 283 | mov ebx,eax |
1348 | art_zh | 284 | ; get current state into ecx |
285 | mov dx,0xcf8 |
||
286 | in eax, dx |
||
287 | push eax |
||
288 | ; set up addressing to config data |
||
289 | mov eax,ebx |
||
290 | and al,0xfc ; make address dword-aligned |
||
291 | out dx,eax |
||
292 | ; write DWORD of config data |
||
293 | mov dl,0xfc |
||
294 | and bl,3 |
||
295 | or dl,bl |
||
296 | mov eax,ecx |
||
1 | ha | 297 | |
1602 | art_zh | 298 | or esi,esi |
299 | jz pci_write_byte1 |
||
300 | cmp esi,1 |
||
301 | jz pci_write_word1 |
||
302 | cmp esi,2 |
||
303 | jz pci_write_dword1 |
||
304 | jmp pci_fin_write1 |
||
305 | |||
306 | pci_write_byte1: |
||
1348 | art_zh | 307 | out dx,al |
1602 | art_zh | 308 | jmp pci_fin_write1 |
309 | pci_write_word1: |
||
1348 | art_zh | 310 | out dx,ax |
1602 | art_zh | 311 | jmp pci_fin_write1 |
312 | pci_write_dword1: |
||
1348 | art_zh | 313 | out dx,eax |
1602 | art_zh | 314 | jmp pci_fin_write1 |
315 | pci_fin_write1: |
||
1 | ha | 316 | |
1348 | art_zh | 317 | ; restore configuration control |
318 | pop eax |
||
319 | mov dl,0xf8 |
||
320 | out dx,eax |
||
1 | ha | 321 | |
1348 | art_zh | 322 | xor eax,eax |
1602 | art_zh | 323 | pop esi |
324 | |||
1348 | art_zh | 325 | ret |
1 | ha | 326 | pci_write_reg_2: |
327 | |||
1602 | art_zh | 328 | test bh,128 ;mech#2 only supports 16 devices per bus |
329 | jnz pci_write_reg_err |
||
1 | ha | 330 | |
331 | |||
1602 | art_zh | 332 | push esi ; save register size into ESI |
1348 | art_zh | 333 | mov esi,eax |
1602 | art_zh | 334 | and esi,3 |
1 | ha | 335 | |
1348 | art_zh | 336 | push eax |
337 | ;store current state of config space |
||
338 | mov dx,0xcf8 |
||
339 | in al,dx |
||
340 | mov ah,al |
||
341 | mov dl,0xfa |
||
342 | in al,dx |
||
343 | xchg eax,[esp] |
||
344 | ; out 0xcfa,bus |
||
345 | mov al,ah |
||
346 | out dx,al |
||
347 | ; out 0xcf8,0x80 |
||
348 | mov dl,0xf8 |
||
349 | mov al,0x80 |
||
350 | out dx,al |
||
351 | ; compute addr |
||
352 | shr bh,3 ; func is ignored in mechanism 2 |
||
353 | or bh,0xc0 |
||
354 | mov dx,bx |
||
355 | ; write register |
||
356 | mov eax,ecx |
||
1 | ha | 357 | |
1602 | art_zh | 358 | or esi,esi |
359 | jz pci_write_byte2 |
||
360 | cmp esi,1 |
||
361 | jz pci_write_word2 |
||
362 | cmp esi,2 |
||
363 | jz pci_write_dword2 |
||
364 | jmp pci_fin_write2 |
||
365 | |||
366 | pci_write_byte2: |
||
1348 | art_zh | 367 | out dx,al |
1602 | art_zh | 368 | jmp pci_fin_write2 |
369 | pci_write_word2: |
||
1348 | art_zh | 370 | out dx,ax |
1602 | art_zh | 371 | jmp pci_fin_write2 |
372 | pci_write_dword2: |
||
1348 | art_zh | 373 | out dx,eax |
1602 | art_zh | 374 | jmp pci_fin_write2 |
375 | pci_fin_write2: |
||
1348 | art_zh | 376 | ; restore configuration space |
377 | pop eax |
||
378 | mov dx,0xcfa |
||
379 | out dx,al |
||
380 | mov dl,0xf8 |
||
381 | mov al,ah |
||
382 | out dx,al |
||
1 | ha | 383 | |
1348 | art_zh | 384 | xor eax,eax |
1602 | art_zh | 385 | pop esi |
1348 | art_zh | 386 | ret |
1 | ha | 387 | |
1602 | art_zh | 388 | pci_write_reg_err: |
389 | xor eax,eax |
||
390 | dec eax |
||
391 | ret |
||
586 | serge | 392 | |
1370 | art_zh | 393 | if defined mmio_pci_addr ; must be set above |
1348 | art_zh | 394 | ;*************************************************************************** |
395 | ; Function |
||
1603 | art_zh | 396 | ; pci_mmio_init |
1348 | art_zh | 397 | ; |
398 | ; Description |
||
1602 | art_zh | 399 | ; IN: bx = device's PCI bus address (bbbbbbbbdddddfff) |
1358 | art_zh | 400 | ; Returns eax = user heap space available (bytes) |
1348 | art_zh | 401 | ; Error codes |
402 | ; eax = -1 : PCI user access blocked, |
||
403 | ; eax = -2 : device not registered for uMMIO service |
||
404 | ; eax = -3 : user heap initialization failure |
||
405 | ;*************************************************************************** |
||
406 | pci_mmio_init: |
||
1603 | art_zh | 407 | cmp bx, mmio_pci_addr |
1348 | art_zh | 408 | jz @f |
409 | mov eax,-2 |
||
410 | ret |
||
411 | @@: |
||
412 | call init_heap ; (if not initialized yet) |
||
413 | or eax,eax |
||
414 | jz @f |
||
415 | ret |
||
416 | @@: |
||
417 | mov eax,-3 |
||
418 | ret |
||
419 | |||
420 | |||
421 | ;*************************************************************************** |
||
422 | ; Function |
||
1603 | art_zh | 423 | ; pci_mmio_map |
1348 | art_zh | 424 | ; |
425 | ; Description |
||
426 | ; maps a block of PCI memory to user-accessible linear address |
||
427 | ; |
||
428 | ; WARNING! This VERY EXPERIMENTAL service is for one chosen PCI device only! |
||
429 | ; The target device address should be set in kernel var mmio_pci_addr |
||
430 | ; |
||
1602 | art_zh | 431 | ; IN: ah = BAR#; |
432 | ; IN: ebx = block size (bytes); |
||
433 | ; IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages); |
||
1348 | art_zh | 434 | ; |
435 | ; Returns eax = MMIO block's linear address in the userspace (if no error) |
||
436 | ; |
||
437 | ; |
||
438 | ; Error codes |
||
439 | ; eax = -1 : user access to PCI blocked, |
||
440 | ; eax = -2 : an invalid BAR register referred |
||
441 | ; eax = -3 : no i/o space on that BAR |
||
442 | ; eax = -4 : a port i/o BAR register referred |
||
443 | ; eax = -5 : dynamic userspace allocation problem |
||
444 | ;*************************************************************************** |
||
445 | |||
446 | pci_mmio_map: |
||
447 | and edx,0x0ffff |
||
1602 | art_zh | 448 | cmp ah,6 |
1603 | art_zh | 449 | jc .bar_0_5 |
450 | jz .bar_rom |
||
1348 | art_zh | 451 | mov eax,-2 |
452 | ret |
||
1353 | art_zh | 453 | .bar_rom: |
454 | mov ah, 8 ; bar6 = Expansion ROM base address |
||
455 | .bar_0_5: |
||
1348 | art_zh | 456 | push ecx |
1602 | art_zh | 457 | add ebx, 4095 |
458 | and ebx,-4096 |
||
459 | push ebx |
||
460 | mov bl, ah ; bl = BAR# (0..5), however bl=8 for BAR6 |
||
461 | shl bl, 1 |
||
462 | shl bl, 1 |
||
463 | add bl, 0x10 ; now bl = BAR offset in PCI config. space |
||
1354 | diamond | 464 | mov ax, mmio_pci_addr |
1602 | art_zh | 465 | mov bh, al ; bh = dddddfff |
466 | mov al, 2 ; al : DW to read |
||
467 | call pci_read_reg |
||
1348 | art_zh | 468 | or eax, eax |
469 | jnz @f |
||
470 | mov eax,-3 ; empty I/O space |
||
471 | jmp mmio_ret_fail |
||
472 | @@: |
||
473 | test eax, 1 |
||
474 | jz @f |
||
475 | mov eax,-4 ; damned ports (not MMIO space) |
||
476 | jmp mmio_ret_fail |
||
477 | @@: |
||
1602 | art_zh | 478 | pop ecx ; ecx = block size, bytes (expanded to whole page) |
1348 | art_zh | 479 | mov ebx, ecx ; user_alloc destroys eax, ecx, edx, but saves ebx |
1602 | art_zh | 480 | and eax, 0xFFFFFFF0 |
1462 | art_zh | 481 | push eax ; store MMIO physical address + keep 2DWords in the stack |
1348 | art_zh | 482 | stdcall user_alloc, ecx |
1602 | art_zh | 483 | or eax, eax |
1348 | art_zh | 484 | jnz mmio_map_over |
485 | mov eax,-5 ; problem with page allocation |
||
486 | |||
487 | mmio_ret_fail: |
||
488 | pop ecx |
||
489 | pop edx |
||
490 | ret |
||
491 | |||
492 | mmio_map_over: |
||
493 | mov ecx, ebx ; ecx = size (bytes, expanded to whole page) |
||
494 | shr ecx, 12 ; ecx = number of pages |
||
495 | mov ebx, eax ; ebx = linear address |
||
1602 | art_zh | 496 | pop eax ; eax = MMIO start |
497 | pop edx ; edx = MMIO shift (pages) |
||
1348 | art_zh | 498 | shl edx, 12 ; edx = MMIO shift (bytes) |
499 | add eax, edx ; eax = uMMIO physical address |
||
1602 | art_zh | 500 | or eax, PG_SHARED |
501 | or eax, PG_UW |
||
502 | or eax, PG_NOCACHE |
||
1348 | art_zh | 503 | mov edi, ebx |
504 | call commit_pages |
||
505 | mov eax, edi |
||
506 | ret |
||
507 | |||
508 | ;*************************************************************************** |
||
509 | ; Function |
||
1603 | art_zh | 510 | ; pci_mmio_unmap_page |
1348 | art_zh | 511 | ; |
512 | ; Description |
||
513 | ; unmaps the linear space previously tied to a PCI memory block |
||
514 | ; |
||
515 | ; IN: ebx = linear address of space previously allocated by pci_mmio_map |
||
516 | ; returns eax = 1 if successfully unmapped |
||
517 | ; |
||
518 | ; Error codes |
||
519 | ; eax = -1 if no user PCI access allowed, |
||
520 | ; eax = 0 if unmapping failed |
||
521 | ;*************************************************************************** |
||
522 | |||
523 | pci_mmio_unmap: |
||
1602 | art_zh | 524 | stdcall user_free, ebx |
1348 | art_zh | 525 | ret |
526 | |||
1354 | diamond | 527 | end if |
1348 | art_zh | 528 | |
586 | serge | 529 | ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
1375 | Lrz | 530 | uglobal |
531 | align 4 |
||
586 | serge | 532 | ; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1) |
533 | pci_emu_dat: times 30*10 db 0 |
||
1375 | Lrz | 534 | endg |
586 | serge | 535 | ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
536 | align 4 |
||
537 | sys_pcibios: |
||
594 | diamond | 538 | cmp [pci_access_enabled], 1 |
1348 | art_zh | 539 | jne .unsupported_func |
540 | cmp [pci_bios_entry], 0 |
||
594 | diamond | 541 | jz .emulate_bios |
586 | serge | 542 | |
1348 | art_zh | 543 | push ds |
544 | mov ax, pci_data_sel |
||
545 | mov ds, ax |
||
546 | mov eax, ebp |
||
547 | mov ah, 0B1h |
||
548 | call pword [cs:pci_bios_entry] |
||
549 | pop ds |
||
586 | serge | 550 | |
551 | jmp .return |
||
552 | ;-=-=-=-=-=-=-=-= |
||
553 | .emulate_bios: |
||
554 | cmp ebp, 1 ; PCI_FUNCTION_ID |
||
555 | jnz .not_PCI_BIOS_PRESENT |
||
556 | mov edx, 'PCI ' |
||
1348 | art_zh | 557 | mov al, [OS_BASE+0x2F0000 + 0x9020] |
558 | mov bx, [OS_BASE+0x2F0000 + 0x9022] |
||
559 | mov cl, [OS_BASE+0x2F0000 + 0x9021] |
||
560 | xor ah, ah |
||
594 | diamond | 561 | jmp .return_abcd |
586 | serge | 562 | |
563 | .not_PCI_BIOS_PRESENT: |
||
564 | cmp ebp, 2 ; FIND_PCI_DEVICE |
||
565 | jne .not_FIND_PCI_DEVICE |
||
594 | diamond | 566 | mov ebx, pci_emu_dat |
567 | ..nxt: cmp [ebx], dx |
||
586 | serge | 568 | jne ..no |
594 | diamond | 569 | cmp [ebx + 2], cx |
586 | serge | 570 | jne ..no |
594 | diamond | 571 | dec si |
586 | serge | 572 | jns ..no |
594 | diamond | 573 | mov bx, [ebx + 4] |
1348 | art_zh | 574 | xor ah, ah |
594 | diamond | 575 | jmp .return_ab |
576 | ..no: cmp word[ebx], 0 |
||
586 | serge | 577 | je ..dev_not_found |
594 | diamond | 578 | add ebx, 10 |
586 | serge | 579 | jmp ..nxt |
580 | ..dev_not_found: |
||
581 | mov ah, 0x86 ; DEVICE_NOT_FOUND |
||
594 | diamond | 582 | jmp .return_a |
586 | serge | 583 | |
584 | .not_FIND_PCI_DEVICE: |
||
585 | cmp ebp, 3 ; FIND_PCI_CLASS_CODE |
||
586 | jne .not_FIND_PCI_CLASS_CODE |
||
587 | mov esi, pci_emu_dat |
||
594 | diamond | 588 | shl ecx, 8 |
1348 | art_zh | 589 | ..nxt2: cmp [esi], ecx |
586 | serge | 590 | jne ..no2 |
591 | mov bx, [esi] |
||
1348 | art_zh | 592 | xor ah, ah |
594 | diamond | 593 | jmp .return_ab |
586 | serge | 594 | ..no2: cmp dword[esi], 0 |
594 | diamond | 595 | je ..dev_not_found |
586 | serge | 596 | add esi, 10 |
597 | jmp ..nxt2 |
||
598 | |||
599 | .not_FIND_PCI_CLASS_CODE: |
||
600 | cmp ebp, 8 ; READ_CONFIG_* |
||
601 | jb .not_READ_CONFIG |
||
602 | cmp ebp, 0x0A |
||
603 | ja .not_READ_CONFIG |
||
1602 | art_zh | 604 | mov eax, ebp |
605 | mov ah, bh |
||
606 | mov edx, edi |
||
607 | mov bh, bl |
||
608 | mov bl, dl |
||
609 | call pci_read_reg |
||
610 | mov ecx, eax |
||
586 | serge | 611 | xor ah, ah ; SUCCESSFUL |
594 | diamond | 612 | jmp .return_abc |
586 | serge | 613 | .not_READ_CONFIG: |
614 | cmp ebp, 0x0B ; WRITE_CONFIG_* |
||
615 | jb .not_WRITE_CONFIG |
||
616 | cmp ebp, 0x0D |
||
617 | ja .not_WRITE_CONFIG |
||
1348 | art_zh | 618 | lea eax, [ebp+1] |
1602 | art_zh | 619 | mov ah, bh |
620 | mov edx, edi |
||
621 | mov bh, bl |
||
622 | mov bl, dl |
||
586 | serge | 623 | call pci_write_reg |
624 | xor ah, ah ; SUCCESSFUL |
||
594 | diamond | 625 | jmp .return_abc |
586 | serge | 626 | .not_WRITE_CONFIG: |
627 | .unsupported_func: |
||
628 | mov ah, 0x81 ; FUNC_NOT_SUPPORTED |
||
1375 | Lrz | 629 | .return:mov dword[esp + 4 ], edi |
630 | mov dword[esp + 8], esi |
||
594 | diamond | 631 | .return_abcd: |
1375 | Lrz | 632 | mov dword[esp + 24], edx |
594 | diamond | 633 | .return_abc: |
1375 | Lrz | 634 | mov dword[esp + 28], ecx |
594 | diamond | 635 | .return_ab: |
1375 | Lrz | 636 | mov dword[esp + 20], ebx |
594 | diamond | 637 | .return_a: |
1375 | Lrz | 638 | mov dword[esp + 32], eax |
586 | serge | 639 | ret |