Subversion Repositories Kolibri OS

Rev

Rev 9567 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;                                                              ;;
  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. ;;                                                              ;;
  22. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23.  
  24. $Revision: 9910 $
  25.  
  26. ;***************************************************************************
  27. ;   Function
  28. ;      pci_api:
  29. ;
  30. ;   Description
  31. ;       entry point for system PCI calls
  32. ;***************************************************************************
  33. ;mmio_pci_addr  =  0x400               ; set actual PCI address here to activate user-MMIO
  34.  
  35. iglobal
  36. align 4
  37. f62call:
  38.         dd      pci_fn_0
  39.         dd      pci_fn_1
  40.         dd      pci_fn_2
  41.         dd      pci_service_not_supported       ;3
  42.         dd      pci_read_reg            ;4 byte
  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
  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
  54.  
  55. endg
  56.  
  57. align 4
  58.  
  59. pci_api:
  60. ;cross
  61.         mov     eax, ebx
  62.         mov     ebx, ecx
  63.         mov     ecx, edx
  64.  
  65.         cmp     [pci_access_enabled], 1
  66.         jne     pci_service_not_supported
  67.  
  68.         movzx   edx, al
  69.  
  70. if defined mmio_pci_addr
  71.         cmp     al, 13
  72.         ja      pci_service_not_supported
  73. else
  74.         cmp     al, 10
  75.         ja      pci_service_not_supported
  76. end if
  77.  
  78.         call    dword [f62call + edx*4]
  79.         mov     dword [esp + SYSCALL_STACK.eax], eax
  80.         ret
  81.  
  82.  
  83. align 4
  84. pci_api_drv:
  85.  
  86.         cmp     [pci_access_enabled], 1
  87.         jne     .fail
  88.  
  89.         cmp     eax, 2
  90.         ja      .fail
  91.  
  92.         jmp     dword [f62call + eax*4]
  93.  
  94. .fail:
  95.         or      eax, -1
  96.         ret
  97.  
  98.  
  99. ;; ============================================
  100.  
  101. pci_fn_0:
  102. ; PCI function 0: get pci version (AH.AL)
  103.         movzx   eax, [BOOT.pci_data.version]
  104.         ret
  105.  
  106. pci_fn_1:
  107. ; PCI function 1: get last bus in AL
  108.         mov     al, [BOOT.pci_data.last_bus]
  109.         ret
  110.  
  111. pci_fn_2:
  112. ; PCI function 2: get pci access mechanism
  113.         mov     al, [BOOT.pci_data.access_mechanism]
  114.         ret
  115.  
  116. pci_service_not_supported:
  117.         or      eax, -1
  118.         mov     dword [esp + SYSCALL_STACK.eax], eax
  119.         ret
  120.  
  121. ;***************************************************************************
  122. ;   Function
  123. ;      pci_make_config_cmd
  124. ;
  125. ;   Description
  126. ;       creates a command dword  for use with the PCI bus
  127. ;       bus # in ah
  128. ;       device+func in bh (dddddfff)
  129. ;       register in bl
  130. ;
  131. ;      command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
  132. ;***************************************************************************
  133.  
  134. align 4
  135.  
  136. pci_make_config_cmd:
  137.         shl     eax, 8     ; move bus to bits 16-23
  138.         mov     ax, bx     ; combine all
  139.         and     eax, 0xffffff
  140.         or      eax, 0x80000000
  141.         ret
  142.  
  143. ;***************************************************************************
  144. ;   Function
  145. ;      pci_read_reg:
  146. ;
  147. ;   Description
  148. ;       read a register from the PCI config space into EAX/AX/AL
  149. ;       IN: ah=bus,device+func=bh,register address=bl
  150. ;           number of bytes to read (1,2,4) coded into AL, bits 0-1
  151. ;           (0 - byte, 1 - word, 2 - dword)
  152. ;***************************************************************************
  153.  
  154. align 4
  155.  
  156. pci_read_reg:
  157.         push    ebx esi
  158.         cmp     [BOOT.pci_data.access_mechanism], 2; what mechanism will we use?
  159.         je      .pci_read_reg_2
  160.  
  161.                 ; mechanism 1
  162.         mov     esi, eax ; save register size into ESI
  163.         and     esi, 3
  164.  
  165.         call    pci_make_config_cmd
  166.         mov     ebx, eax
  167.         mov     dx, 0xcf8
  168.                 ; set up addressing to config data
  169.         mov     eax, ebx
  170.         and     al, 0xfc; make address dword-aligned
  171.         out     dx, eax
  172.                 ; get requested DWORD of config data
  173.         mov     dl, 0xfc
  174.         and     bl, 3
  175.         or      dl, bl   ; add to port address first 2 bits of register address
  176.  
  177.         or      esi, esi
  178.         jz      .byte1
  179.         cmp     esi, 1
  180.         jz      .word1
  181.         cmp     esi, 2
  182.         jz      .dword1
  183.         jmp     .fin_read1
  184.  
  185. .byte1:
  186.         in      al, dx
  187.         jmp     .fin_read1
  188. .word1:
  189.         in      ax, dx
  190.         jmp     .fin_read1
  191. .dword1:
  192.         in      eax, dx
  193. .fin_read1:
  194.         pop     esi ebx
  195.         ret
  196.  
  197. .pci_read_reg_2:
  198.  
  199.         test    bh, 128 ;mech#2 only supports 16 devices per bus
  200.         jnz     .pci_read_reg_err
  201.  
  202.         mov     esi, eax ; save register size into ESI
  203.         and     esi, 3
  204.  
  205.         mov     dx, 0xcfa
  206.  
  207.                 ; out 0xcfa,bus
  208.         mov     al, ah
  209.         out     dx, al
  210.                 ; out 0xcf8,0x80
  211.         mov     dl, 0xf8
  212.         mov     al, 0x80
  213.         out     dx, al
  214.                 ; compute addr
  215.         shr     bh, 3; func is ignored in mechanism 2
  216.         or      bh, 0xc0
  217.         mov     dx, bx
  218.  
  219.         or      esi, esi
  220.         jz      .byte2
  221.         cmp     esi, 1
  222.         jz      .word2
  223.         cmp     esi, 2
  224.         jz      .dword2
  225.         jmp     .fin_read2
  226.  
  227. .byte2:
  228.         in      al, dx
  229.         jmp     .fin_read2
  230. .word2:
  231.         in      ax, dx
  232.         jmp     .fin_read2
  233. .dword2:
  234.         in      eax, dx
  235. .fin_read2:
  236.  
  237.         pop     esi ebx
  238.         ret
  239.  
  240. .pci_read_reg_err:
  241.         xor     eax, eax
  242.         dec     eax
  243.         pop     esi ebx
  244.         ret
  245.  
  246.  
  247. ;***************************************************************************
  248. ;   Function
  249. ;      pci_write_reg:
  250. ;
  251. ;   Description
  252. ;       write a register from ECX/CX/CL into the PCI config space
  253. ;       IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
  254. ;           value to write in ecx
  255. ;           number of bytes to write (1,2,4) coded into AL, bits 0-1
  256. ;           (0 - byte, 1 - word, 2 - dword)
  257. ;***************************************************************************
  258.  
  259. align 4
  260.  
  261. pci_write_reg:
  262.         push    esi ebx
  263.         cmp     [BOOT.pci_data.access_mechanism], 2; what mechanism will we use?
  264.         je      pci_write_reg_2
  265.  
  266.                 ; mechanism 1
  267.         mov     esi, eax ; save register size into ESI
  268.         and     esi, 3
  269.  
  270.         call    pci_make_config_cmd
  271.         mov     ebx, eax
  272.         mov     dx, 0xcf8
  273.                 ; set up addressing to config data
  274.         mov     eax, ebx
  275.         and     al, 0xfc; make address dword-aligned
  276.         out     dx, eax
  277.                 ; write DWORD of config data
  278.         mov     dl, 0xfc
  279.         and     bl, 3
  280.         or      dl, bl
  281.         mov     eax, ecx
  282.  
  283.         or      esi, esi
  284.         jz      .byte1
  285.         cmp     esi, 1
  286.         jz      .word1
  287.         cmp     esi, 2
  288.         jz      .dword1
  289.         jmp     .fin_write1
  290.  
  291. .byte1:
  292.         out     dx, al
  293.         jmp     .fin_write1
  294. .word1:
  295.         out     dx, ax
  296.         jmp     .fin_write1
  297. .dword1:
  298.         out     dx, eax
  299. .fin_write1:
  300.  
  301.         xor     eax, eax
  302.         pop     ebx esi
  303.  
  304.         ret
  305. pci_write_reg_2:
  306.  
  307.         test    bh, 128 ;mech#2 only supports 16 devices per bus
  308.         jnz     .pci_write_reg_err
  309.  
  310.  
  311.         mov     esi, eax ; save register size into ESI
  312.         and     esi, 3
  313.  
  314.         mov     dx, 0xcfa
  315.                 ; out 0xcfa,bus
  316.         mov     al, ah
  317.         out     dx, al
  318.                 ; out 0xcf8,0x80
  319.         mov     dl, 0xf8
  320.         mov     al, 0x80
  321.         out     dx, al
  322.                 ; compute addr
  323.         shr     bh, 3; func is ignored in mechanism 2
  324.         or      bh, 0xc0
  325.         mov     dx, bx
  326.                 ; write register
  327.         mov     eax, ecx
  328.  
  329.         or      esi, esi
  330.         jz      .byte2
  331.         cmp     esi, 1
  332.         jz      .word2
  333.         cmp     esi, 2
  334.         jz      .dword2
  335.         jmp     .fin_write2
  336.  
  337. .byte2:
  338.         out     dx, al
  339.         jmp     .fin_write2
  340. .word2:
  341.         out     dx, ax
  342.         jmp     .fin_write2
  343. .dword2:
  344.         out     dx, eax
  345. .fin_write2:
  346.  
  347.         xor     eax, eax
  348.         pop     ebx esi
  349.         ret
  350.  
  351. .pci_write_reg_err:
  352.         xor     eax, eax
  353.         dec     eax
  354.         pop     ebx esi
  355.         ret
  356.  
  357. if defined mmio_pci_addr        ; must be set above
  358. ;***************************************************************************
  359. ;   Function
  360. ;      pci_mmio_init
  361. ;
  362. ;   Description
  363. ;       IN:  bx = device's PCI bus address (bbbbbbbbdddddfff)
  364. ;   Returns  eax = user heap space available (bytes)
  365. ;   Error codes
  366. ;       eax = -1 : PCI user access blocked,
  367. ;       eax = -2 : device not registered for uMMIO service
  368. ;       eax = -3 : user heap initialization failure
  369. ;***************************************************************************
  370. pci_mmio_init:
  371.         cmp     bx, mmio_pci_addr
  372.         jz      @f
  373.         mov     eax, -2
  374.         ret
  375. @@:
  376.         call    init_heap  ; (if not initialized yet)
  377.         or      eax, eax
  378.         jz      @f
  379.         ret
  380. @@:
  381.         mov     eax, -3
  382.         ret
  383.  
  384.  
  385. ;***************************************************************************
  386. ;   Function
  387. ;      pci_mmio_map
  388. ;
  389. ;   Description
  390. ;       maps a block of PCI memory to user-accessible linear address
  391. ;
  392. ;       WARNING! This VERY EXPERIMENTAL service is for one chosen PCI device only!
  393. ;       The target device address should be set in kernel var mmio_pci_addr
  394. ;
  395. ;       IN:  ah = BAR#;
  396. ;       IN: ebx = block size (bytes);
  397. ;       IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
  398. ;
  399. ;   Returns eax = MMIO block's linear address in the userspace (if no error)
  400. ;
  401. ;
  402. ;   Error codes
  403. ;       eax = -1 : user access to PCI blocked,
  404. ;       eax = -2 : an invalid BAR register referred
  405. ;       eax = -3 : no i/o space on that BAR
  406. ;       eax = -4 : a port i/o BAR register referred
  407. ;       eax = -5 : dynamic userspace allocation problem
  408. ;***************************************************************************
  409.  
  410. pci_mmio_map:
  411.         and     edx, 0x0ffff
  412.         cmp     ah, 6
  413.         jc      .bar_0_5
  414.         jz      .bar_rom
  415.         mov     eax, -2
  416.         ret
  417. .bar_rom:
  418.         mov     ah, 8   ; bar6 = Expansion ROM base address
  419. .bar_0_5:
  420.         push    ecx
  421.         add     ebx, 4095
  422.         and     ebx, -4096
  423.         push    ebx
  424.         mov     bl, ah  ; bl = BAR# (0..5), however bl=8 for BAR6
  425.         shl     bl, 1
  426.         shl     bl, 1
  427.         add     bl, 0x10; now bl = BAR offset in PCI config. space
  428.         mov     ax, mmio_pci_addr
  429.         mov     bh, al  ; bh = dddddfff
  430.         mov     al, 2   ; al : DW to read
  431.         call    pci_read_reg
  432.         or      eax, eax
  433.         jnz     @f
  434.         mov     eax, -3 ; empty I/O space
  435.         jmp     .mmio_ret_fail
  436. @@:
  437.         test    eax, 1
  438.         jz      @f
  439.         mov     eax, -4 ; damned ports (not MMIO space)
  440.         jmp     .mmio_ret_fail
  441. @@:
  442.         pop     ecx     ; ecx = block size, bytes (expanded to whole page)
  443.         mov     ebx, ecx; user_alloc destroys eax, ecx, edx, but saves ebx
  444.         and     eax, 0xFFFFFFF0
  445.         push    eax           ; store MMIO physical address + keep 2DWords in the stack
  446.         stdcall user_alloc, ecx
  447.         or      eax, eax
  448.         jnz     .mmio_map_over
  449.         mov     eax, -5 ; problem with page allocation
  450.  
  451. .mmio_ret_fail:
  452.         pop     ecx
  453.         pop     edx
  454.         ret
  455.  
  456. .mmio_map_over:
  457.         mov     ecx, ebx; ecx = size (bytes, expanded to whole page)
  458.         shr     ecx, 12 ; ecx = number of pages
  459.         mov     ebx, eax; ebx = linear address
  460.         pop     eax     ; eax = MMIO start
  461.         pop     edx     ; edx = MMIO shift (pages)
  462.         shl     edx, 12 ; edx = MMIO shift (bytes)
  463.         add     eax, edx; eax = uMMIO physical address
  464.         or      eax, PG_SHARED
  465.         or      eax, PG_UW
  466.         or      eax, PG_NOCACHE
  467.         mov     edi, ebx
  468.         call    commit_pages
  469.         mov     eax, edi
  470.         ret
  471.  
  472. ;***************************************************************************
  473. ;   Function
  474. ;      pci_mmio_unmap_page
  475. ;
  476. ;   Description
  477. ;       unmaps the linear space previously tied to a PCI memory block
  478. ;
  479. ;       IN: ebx = linear address of space previously allocated by pci_mmio_map
  480. ;       returns eax = 1 if successfully unmapped
  481. ;
  482. ;   Error codes
  483. ;       eax = -1 if no user PCI access allowed,
  484. ;       eax =  0 if unmapping failed
  485. ;***************************************************************************
  486.  
  487. pci_mmio_unmap:
  488.         stdcall user_free, ebx
  489.         ret
  490.  
  491. end if
  492.  
  493. ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  494. uglobal
  495. align 4
  496. ; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
  497. pci_emu_dat:
  498.                 times   30*10 db 0
  499. endg
  500. ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  501. align 4
  502. sys_pcibios:
  503.         cmp     [pci_access_enabled], 1
  504.         jne     .unsupported_func
  505.         cmp     [pci_bios_entry], 0
  506.         jz      .emulate_bios
  507.  
  508.         push    ds
  509.         mov     ax, pci_data_sel
  510.         mov     ds, ax
  511.         mov     eax, ebp
  512.         mov     ah, 0B1h
  513.         call    pword [cs:pci_bios_entry]
  514.         pop     ds
  515.  
  516.         jmp     .return
  517.         ;-=-=-=-=-=-=-=-=
  518. .emulate_bios:
  519.         cmp     ebp, 1                  ; PCI_FUNCTION_ID
  520.         jnz     .not_PCI_BIOS_PRESENT
  521.         mov     edx, 'PCI '
  522.         mov     al, [BOOT.pci_data.access_mechanism]
  523.         mov     bx, word[BOOT.pci_data.version]
  524.         mov     cl, [BOOT.pci_data.last_bus]
  525.         xor     ah, ah
  526.         jmp     .return_abcd
  527.  
  528. .not_PCI_BIOS_PRESENT:
  529.         cmp     ebp, 2                  ; FIND_PCI_DEVICE
  530.         jne     .not_FIND_PCI_DEVICE
  531.         mov     ebx, pci_emu_dat
  532. ..nxt:
  533.         cmp     [ebx], dx
  534.         jne     ..no
  535.         cmp     [ebx + 2], cx
  536.         jne     ..no
  537.         dec     si
  538.         jns     ..no
  539.         mov     bx, [ebx + 4]
  540.         xor     ah, ah
  541.         jmp     .return_ab
  542. ..no:
  543.         cmp     word[ebx], 0
  544.         je      ..dev_not_found
  545.         add     ebx, 10
  546.         jmp     ..nxt
  547. ..dev_not_found:
  548.         mov     ah, 0x86                ; DEVICE_NOT_FOUND
  549.         jmp     .return_a
  550.  
  551. .not_FIND_PCI_DEVICE:
  552.         cmp     ebp, 3                  ; FIND_PCI_CLASS_CODE
  553.         jne     .not_FIND_PCI_CLASS_CODE
  554.         mov     esi, pci_emu_dat
  555.         shl     ecx, 8
  556. ..nxt2:
  557.         cmp     [esi], ecx
  558.         jne     ..no2
  559.         mov     bx, [esi]
  560.         xor     ah, ah
  561.         jmp     .return_ab
  562. ..no2:
  563.         cmp     dword[esi], 0
  564.         je      ..dev_not_found
  565.         add     esi, 10
  566.         jmp     ..nxt2
  567.  
  568. .not_FIND_PCI_CLASS_CODE:
  569.         cmp     ebp, 8                  ; READ_CONFIG_*
  570.         jb      .not_READ_CONFIG
  571.         cmp     ebp, 0x0A
  572.         ja      .not_READ_CONFIG
  573.         mov     eax, ebp
  574.         mov     ah, bh
  575.         mov     edx, edi
  576.         mov     bh, bl
  577.         mov     bl, dl
  578.         call    pci_read_reg
  579.         mov     ecx, eax
  580.         xor     ah, ah                  ; SUCCESSFUL
  581.         jmp     .return_abc
  582. .not_READ_CONFIG:
  583.         cmp     ebp, 0x0B               ; WRITE_CONFIG_*
  584.         jb      .not_WRITE_CONFIG
  585.         cmp     ebp, 0x0D
  586.         ja      .not_WRITE_CONFIG
  587.         lea     eax, [ebp+1]
  588.         mov     ah, bh
  589.         mov     edx, edi
  590.         mov     bh, bl
  591.         mov     bl, dl
  592.         call    pci_write_reg
  593.         xor     ah, ah                  ; SUCCESSFUL
  594.         jmp     .return_abc
  595. .not_WRITE_CONFIG:
  596. .unsupported_func:
  597.         mov     ah, 0x81                ; FUNC_NOT_SUPPORTED
  598. .return:
  599.         mov     dword[esp + SYSCALL_STACK.edi], edi
  600.         mov     dword[esp + SYSCALL_STACK.esi], esi
  601. .return_abcd:
  602.         mov     dword[esp + SYSCALL_STACK.edx], edx
  603. .return_abc:
  604.         mov     dword[esp + SYSCALL_STACK.ecx], ecx
  605. .return_ab:
  606.         mov     dword[esp + SYSCALL_STACK.ebx], ebx
  607. .return_a:
  608.         mov     dword[esp + SYSCALL_STACK.eax], eax
  609.         ret
  610.  
  611. proc pci_enum
  612.         push    ebp
  613.         mov     ebp, esp
  614.         push    0
  615. virtual at ebp-4
  616. .devfn          db      ?
  617. .bus            db      ?
  618. end virtual
  619. .loop:
  620.         mov     ah, [.bus]
  621.         mov     al, 2
  622.         mov     bh, [.devfn]
  623.         mov     bl, 0
  624.         call    pci_read_reg
  625.         cmp     eax, 0xFFFFFFFF
  626.         jnz     .has_device
  627.         test    byte [.devfn], 7
  628.         jnz     .next_func
  629.         jmp     .no_device
  630. .has_device:
  631.         push    eax
  632.         movi    eax, sizeof.PCIDEV
  633.         call    malloc
  634.         pop     ecx
  635.         test    eax, eax
  636.         jz      .nomemory
  637.         mov     edi, eax
  638.         mov     [edi+PCIDEV.vendor_device_id], ecx
  639.         mov     eax, pcidev_list
  640.         mov     ecx, [eax+PCIDEV.bk]
  641.         mov     [edi+PCIDEV.bk], ecx
  642.         mov     [edi+PCIDEV.fd], eax
  643.         mov     [ecx+PCIDEV.fd], edi
  644.         mov     [eax+PCIDEV.bk], edi
  645.         mov     eax, dword [.devfn]
  646.         mov     dword [edi+PCIDEV.devfn], eax
  647.         mov     dword [edi+PCIDEV.owner], 0
  648.         mov     bh, al
  649.         mov     al, 2
  650.         mov     bl, 8
  651.         call    pci_read_reg
  652.         shr     eax, 8
  653.         mov     [edi+PCIDEV.class], eax
  654.         test    byte [.devfn], 7
  655.         jnz     .next_func
  656.         mov     ah, [.bus]
  657.         mov     al, 0
  658.         mov     bh, [.devfn]
  659.         mov     bl, 0Eh
  660.         call    pci_read_reg
  661.         test    al, al
  662.         js      .next_func
  663. .no_device:
  664.         or      byte [.devfn], 7
  665. .next_func:
  666.         inc     dword [.devfn]
  667.         mov     ah, [.bus]
  668.         cmp     ah, [BOOT.pci_data.last_bus]
  669.         jbe     .loop
  670. .nomemory:
  671.         leave
  672.         ret
  673. endp
  674.  
  675. ; Export for drivers. Just returns the pointer to the pci-devices list.
  676. proc get_pcidev_list
  677.         mov     eax, pcidev_list
  678.         ret
  679. endp
  680.  
  681.  
  682. align 4
  683. proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
  684.         push    ebx
  685.         xor     eax, eax
  686.         xor     ebx, ebx
  687.         mov     ah, byte [bus]
  688.         mov     al, 6
  689.         mov     bh, byte [devfn]
  690.         mov     bl, byte [reg]
  691.         call    pci_read_reg
  692.         pop     ebx
  693.         ret
  694. endp
  695.  
  696. align 4
  697. proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
  698.         push    ebx
  699.         xor     eax, eax
  700.         xor     ebx, ebx
  701.         mov     ah, byte [bus]
  702.         mov     al, 5
  703.         mov     bh, byte [devfn]
  704.         mov     bl, byte [reg]
  705.         call    pci_read_reg
  706.         pop     ebx
  707.         ret
  708. endp
  709.  
  710. align 4
  711. proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
  712.         push    ebx
  713.         xor     eax, eax
  714.         xor     ebx, ebx
  715.         mov     ah, byte [bus]
  716.         mov     al, 4
  717.         mov     bh, byte [devfn]
  718.         mov     bl, byte [reg]
  719.         call    pci_read_reg
  720.         pop     ebx
  721.         ret
  722. endp
  723.  
  724. align 4
  725. proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  726.         push    ebx
  727.         xor     eax, eax
  728.         xor     ebx, ebx
  729.         mov     ah, byte [bus]
  730.         mov     al, 8
  731.         mov     bh, byte [devfn]
  732.         mov     bl, byte [reg]
  733.         mov     ecx, [val]
  734.         call    pci_write_reg
  735.         pop     ebx
  736.         ret
  737. endp
  738.  
  739. align 4
  740. proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  741.         push    ebx
  742.         xor     eax, eax
  743.         xor     ebx, ebx
  744.         mov     ah, byte [bus]
  745.         mov     al, 9
  746.         mov     bh, byte [devfn]
  747.         mov     bl, byte [reg]
  748.         mov     ecx, [val]
  749.         call    pci_write_reg
  750.         pop     ebx
  751.         ret
  752. endp
  753.  
  754. align 4
  755. proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  756.         push    ebx
  757.         xor     eax, eax
  758.         xor     ebx, ebx
  759.         mov     ah, byte [bus]
  760.         mov     al, 10
  761.         mov     bh, byte [devfn]
  762.         mov     bl, byte [reg]
  763.         mov     ecx, [val]
  764.         call    pci_write_reg
  765.         pop     ebx
  766.         ret
  767. endp