Subversion Repositories Kolibri OS

Rev

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