Subversion Repositories Kolibri OS

Rev

Rev 586 | Rev 594 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. 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: 593 $
  25.  
  26.  
  27. ;***************************************************************************
  28. ;   Function
  29. ;      pci_api:
  30. ;
  31. ;   Description
  32. ;       entry point for system PCI calls
  33. ;***************************************************************************
  34.  
  35. align 4
  36.  
  37. pci_api:
  38.  
  39.         cmp  [pci_access_enabled],1
  40.         jne  no_pci_access_for_applications
  41.  
  42.         or al,al
  43.         jnz pci_fn_1
  44.         ; PCI function 0: get pci version (AH.AL)
  45.         movzx eax,word [BOOT_VAR+0x9022]
  46.         ret
  47.  
  48. pci_fn_1:
  49.         cmp al,1
  50.         jnz pci_fn_2
  51.  
  52.         ; PCI function 1: get last bus in AL
  53.         mov al,[BOOT_VAR+0x9021]
  54.         ret
  55.  
  56. pci_fn_2:
  57.         cmp al,2
  58.         jne pci_fn_3
  59.         ; PCI function 2: get pci access mechanism
  60.         mov al,[BOOT_VAR+0x9020]
  61.         ret
  62. pci_fn_3:
  63.  
  64.         cmp al,4
  65.         jz pci_read_reg   ;byte
  66.         cmp al,5
  67.         jz pci_read_reg   ;word
  68.         cmp al,6
  69.         jz pci_read_reg   ;dword
  70.  
  71.         cmp al,8
  72.         jz pci_write_reg  ;byte
  73.         cmp al,9
  74.         jz pci_write_reg  ;word
  75.         cmp al,10
  76.         jz pci_write_reg  ;dword
  77.  
  78.       no_pci_access_for_applications:
  79.  
  80.         mov eax,-1
  81.  
  82.         ret
  83.  
  84. ;***************************************************************************
  85. ;   Function
  86. ;      pci_make_config_cmd
  87. ;
  88. ;   Description
  89. ;       creates a command dword  for use with the PCI bus
  90. ;       bus # in ah
  91. ;       device+func in bh (dddddfff)
  92. ;       register in bl
  93. ;
  94. ;      command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
  95. ;***************************************************************************
  96.  
  97. align 4
  98.  
  99. pci_make_config_cmd:
  100.     shl     eax,8          ; move bus to bits 16-23
  101.     mov     ax,bx          ; combine all
  102.     and     eax,0xffffff
  103.     or      eax,0x80000000
  104.     ret
  105.  
  106. ;***************************************************************************
  107. ;   Function
  108. ;      pci_read_reg:
  109. ;
  110. ;   Description
  111. ;       read a register from the PCI config space into EAX/AX/AL
  112. ;       IN: ah=bus,device+func=bh,register address=bl
  113. ;           number of bytes to read (1,2,4) coded into AL, bits 0-1
  114. ;           (0 - byte, 1 - word, 2 - dword)
  115. ;***************************************************************************
  116.  
  117. align 4
  118.  
  119. pci_read_reg:
  120.         cmp     byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
  121.         je      pci_read_reg_2
  122.  
  123.                 ; mechanism 1
  124.         push    esi   ; save register size into ESI
  125.         mov     esi,eax
  126.         and     esi,3
  127.  
  128.         call    pci_make_config_cmd
  129.         mov     ebx,eax
  130.                 ; get current state
  131.         mov     dx,0xcf8
  132.         in      eax, dx
  133.         push    eax
  134.                 ; set up addressing to config data
  135.         mov     eax,ebx
  136.         and     al,0xfc ; make address dword-aligned
  137.         out     dx,eax
  138.                 ; get requested DWORD of config data
  139.         mov     dl,0xfc
  140.         and     bl,3
  141.         or      dl,bl    ; add to port address first 2 bits of register address
  142.  
  143.         or      esi,esi
  144.         jz      pci_read_byte1
  145.         cmp     esi,1
  146.         jz      pci_read_word1
  147.         cmp     esi,2
  148.         jz      pci_read_dword1
  149.         jmp     pci_fin_read1
  150.  
  151. pci_read_byte1:
  152.         in      al,dx
  153.         jmp pci_fin_read1
  154. pci_read_word1:
  155.         in      ax,dx
  156.         jmp pci_fin_read1
  157. pci_read_dword1:
  158.         in      eax,dx
  159.         jmp     pci_fin_read1
  160. pci_fin_read1:
  161.                 ; restore configuration control
  162.         xchg    eax,[esp]
  163.         mov     dx,0xcf8
  164.         out     dx,eax
  165.  
  166.         pop     eax
  167.         pop     esi
  168.         ret
  169. pci_read_reg_2:
  170.  
  171.         test    bh,128  ;mech#2 only supports 16 devices per bus
  172.         jnz     pci_read_reg_err
  173.  
  174.         push esi   ; save register size into ESI
  175.         mov esi,eax
  176.         and esi,3
  177.  
  178.         push    eax
  179.                 ;store current state of config space
  180.         mov     dx,0xcf8
  181.         in      al,dx
  182.         mov     ah,al
  183.         mov     dl,0xfa
  184.         in      al,dx
  185.  
  186.         xchg    eax,[esp]
  187.                 ; out 0xcfa,bus
  188.         mov     al,ah
  189.         out     dx,al
  190.                 ; out 0xcf8,0x80
  191.         mov     dl,0xf8
  192.         mov     al,0x80
  193.         out     dx,al
  194.                 ; compute addr
  195.         shr     bh,3 ; func is ignored in mechanism 2
  196.         or      bh,0xc0
  197.         mov     dx,bx
  198.  
  199.         or      esi,esi
  200.         jz      pci_read_byte2
  201.         cmp     esi,1
  202.         jz      pci_read_word2
  203.         cmp     esi,2
  204.         jz      pci_read_dword2
  205.         jmp     pci_fin_read2
  206.  
  207. pci_read_byte2:
  208.         in      al,dx
  209.         jmp pci_fin_read2
  210. pci_read_word2:
  211.         in      ax,dx
  212.         jmp pci_fin_read2
  213. pci_read_dword2:
  214.         in      eax,dx
  215. ;       jmp pci_fin_read2
  216. pci_fin_read2:
  217.  
  218.                 ; restore configuration space
  219.         xchg    eax,[esp]
  220.         mov     dx,0xcfa
  221.         out     dx,al
  222.         mov     dl,0xf8
  223.         mov     al,ah
  224.         out     dx,al
  225.  
  226.         pop     eax
  227.         pop     esi
  228.         ret
  229.  
  230. pci_read_reg_err:
  231.         xor     eax,eax
  232.         dec     eax
  233.         ret
  234.  
  235.  
  236. ;***************************************************************************
  237. ;   Function
  238. ;      pci_write_reg:
  239. ;
  240. ;   Description
  241. ;       write a register from ECX/CX/CL into the PCI config space
  242. ;       IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
  243. ;           value to write in ecx
  244. ;           number of bytes to write (1,2,4) coded into AL, bits 0-1
  245. ;           (0 - byte, 1 - word, 2 - dword)
  246. ;***************************************************************************
  247.  
  248. align 4
  249.  
  250. pci_write_reg:
  251.         cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
  252.         je pci_write_reg_2
  253.  
  254.                 ; mechanism 1
  255.         push    esi   ; save register size into ESI
  256.         mov     esi,eax
  257.         and     esi,3
  258.  
  259.         call    pci_make_config_cmd
  260.         mov     ebx,eax
  261.                 ; get current state into ecx
  262.         mov     dx,0xcf8
  263.         in      eax, dx
  264.         push    eax
  265.                 ; set up addressing to config data
  266.         mov     eax,ebx
  267.         and     al,0xfc ; make address dword-aligned
  268.         out     dx,eax
  269.                 ; write DWORD of config data
  270.         mov     dl,0xfc
  271.         and     bl,3
  272.         or      dl,bl
  273.         mov     eax,ecx
  274.  
  275.         or      esi,esi
  276.         jz      pci_write_byte1
  277.         cmp     esi,1
  278.         jz      pci_write_word1
  279.         cmp     esi,2
  280.         jz      pci_write_dword1
  281.         jmp     pci_fin_write1
  282.  
  283. pci_write_byte1:
  284.         out     dx,al
  285.         jmp pci_fin_write1
  286. pci_write_word1:
  287.         out     dx,ax
  288.         jmp pci_fin_write1
  289. pci_write_dword1:
  290.         out     dx,eax
  291.         jmp     pci_fin_write1
  292. pci_fin_write1:
  293.  
  294.                 ; restore configuration control
  295.         pop     eax
  296.         mov     dl,0xf8
  297.         out     dx,eax
  298.  
  299.         xor     eax,eax
  300.         pop     esi
  301.  
  302.         ret
  303. pci_write_reg_2:
  304.  
  305.         test    bh,128  ;mech#2 only supports 16 devices per bus
  306.         jnz     pci_write_reg_err
  307.  
  308.  
  309.         push esi   ; save register size into ESI
  310.         mov esi,eax
  311.         and esi,3
  312.  
  313.         push    eax
  314.                 ;store current state of config space
  315.         mov     dx,0xcf8
  316.         in      al,dx
  317.         mov     ah,al
  318.         mov     dl,0xfa
  319.         in      al,dx
  320.         xchg    eax,[esp]
  321.                 ; out 0xcfa,bus
  322.         mov     al,ah
  323.         out     dx,al
  324.                 ; out 0xcf8,0x80
  325.         mov     dl,0xf8
  326.         mov     al,0x80
  327.         out     dx,al
  328.                 ; compute addr
  329.         shr     bh,3 ; func is ignored in mechanism 2
  330.         or      bh,0xc0
  331.         mov     dx,bx
  332.                 ; write register
  333.         mov     eax,ecx
  334.  
  335.         or      esi,esi
  336.         jz      pci_write_byte2
  337.         cmp     esi,1
  338.         jz      pci_write_word2
  339.         cmp     esi,2
  340.         jz      pci_write_dword2
  341.         jmp     pci_fin_write2
  342.  
  343. pci_write_byte2:
  344.         out     dx,al
  345.         jmp pci_fin_write2
  346. pci_write_word2:
  347.         out     dx,ax
  348.         jmp pci_fin_write2
  349. pci_write_dword2:
  350.         out     dx,eax
  351.         jmp     pci_fin_write2
  352. pci_fin_write2:
  353.                 ; restore configuration space
  354.         pop     eax
  355.         mov     dx,0xcfa
  356.         out     dx,al
  357.         mov     dl,0xf8
  358.         mov     al,ah
  359.         out     dx,al
  360.  
  361.         xor     eax,eax
  362.         pop     esi
  363.         ret
  364.  
  365. pci_write_reg_err:
  366.         xor     eax,eax
  367.         dec     eax
  368.         ret
  369.  
  370. ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  371.  
  372. ; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
  373. pci_emu_dat:    times   30*10 db 0
  374.  
  375. ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  376. align 4
  377. sys_pcibios:
  378.         cmp     [pci_access_enabled], 1
  379.         jne     .unsupported_func
  380.         mov     edi, [pci_bios_entry]
  381.         test    edi, edi
  382.         jz      .emulate_bios
  383.         xchg    ebx, eax
  384.         xchg    ecx, eax
  385.         xchg    edx, eax
  386.         xchg    esi, eax
  387.         mov     edi, eax
  388.  
  389.         push ds
  390.         mov ax, pci_data_sel
  391.         mov ds, ax
  392.         mov eax, ebp
  393.         call pword [cs:pci_bios_entry]
  394.         pop ds
  395.  
  396.         jmp     .return
  397.         ;-=-=-=-=-=-=-=-=
  398. .emulate_bios:
  399.         cmp     ebp, 1                  ; PCI_FUNCTION_ID
  400.         jnz     .not_PCI_BIOS_PRESENT
  401.         mov     edx, 'PCI '
  402.         xor     ah, ah
  403.         mov     al, [OS_BASE+0x2F0000 + 0x9020]
  404.         mov     bx, [OS_BASE+0x2F0000 + 0x9022]
  405.         mov     cl, [OS_BASE+0x2F0000 + 0x9021]
  406.         jmp     .return
  407.  
  408. .not_PCI_BIOS_PRESENT:
  409.         cmp     ebp, 2                  ; FIND_PCI_DEVICE
  410.         jne     .not_FIND_PCI_DEVICE
  411.         mov     esi, pci_emu_dat
  412. ..nxt:  cmp     [esi], cx
  413.         jne     ..no
  414.         cmp     [esi + 2], bx
  415.         jne     ..no
  416.         dec     dx
  417.         jns     ..no
  418.         mov     bx, [esi + 4]
  419.         xor     ah, ah
  420.         jmp     .return
  421. ..no:   cmp     word[esi], 0
  422.         je      ..dev_not_found
  423.         add     esi, 10
  424.         jmp     ..nxt
  425. ..dev_not_found:
  426.         mov     ah, 0x86                ; DEVICE_NOT_FOUND
  427.         jmp     .return
  428.  
  429. .not_FIND_PCI_DEVICE:
  430.         cmp     ebp, 3                  ; FIND_PCI_CLASS_CODE
  431.         jne     .not_FIND_PCI_CLASS_CODE
  432.         mov     esi, pci_emu_dat
  433.         shl     ebx, 8
  434. ..nxt2: cmp     [esi], ebx
  435.         jne     ..no2
  436.         mov     bx, [esi]
  437.         xor     ah, ah
  438.         jmp     .return
  439. ..no2:  cmp     dword[esi], 0
  440.         je      ..dev_not_found2
  441.         add     esi, 10
  442.         jmp     ..nxt2
  443. ..dev_not_found2:
  444.         mov     ah, 0x86                ; DEVICE_NOT_FOUND
  445.         jmp     .return
  446.  
  447. .not_FIND_PCI_CLASS_CODE:
  448.         cmp     ebp, 8                  ; READ_CONFIG_*
  449.         jb      .not_READ_CONFIG
  450.         cmp     ebp, 0x0A
  451.         ja      .not_READ_CONFIG
  452.         mov     ebx, esi
  453.         mov     bh, al
  454.         mov     edx, ebp
  455.         mov     al, dl
  456.         call    pci_read_reg
  457.         mov     ecx, eax
  458.         xor     ah, ah                  ; SUCCESSFUL
  459.         jmp     .return
  460. .not_READ_CONFIG:
  461.         cmp     ebp, 0x0B               ; WRITE_CONFIG_*
  462.         jb      .not_WRITE_CONFIG
  463.         cmp     ebp, 0x0D
  464.         ja      .not_WRITE_CONFIG
  465.         mov     ecx, ebx
  466.         mov     ebx, esi
  467.         mov     bh, al
  468.         mov     edx, ebp
  469.         inc     edx
  470.         mov     al, dl
  471.         call    pci_write_reg
  472.         xor     ah, ah                  ; SUCCESSFUL
  473.         jmp     .return
  474. .not_WRITE_CONFIG:
  475. .unsupported_func:
  476.         mov     ah, 0x81                ; FUNC_NOT_SUPPORTED
  477. .return:mov     dword[esp + 8 ], edi
  478.         mov     dword[esp + 12], esi
  479.         mov     dword[esp + 24], ebx
  480.         mov     dword[esp + 28], edx
  481.         mov     dword[esp + 32], ecx
  482.         mov     dword[esp + 36], eax
  483.         ret
  484.