Subversion Repositories Kolibri OS

Rev

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

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