Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) 2010 KolibriOS team.     All rights reserved.  ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;  HT.inc                                                      ;;                                                    ;;
  7. ;;                                                              ;;
  8. ;;  AMD HyperTransport bus control                              ;;
  9. ;;                                                              ;;
  10. ;;                  art_zh  <kolibri@jerdev.co.uk>              ;;
  11. ;;                                                              ;;
  12. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  13.  
  14. $Revision: 1554 $
  15.  
  16. NB_MISC_INDEX   equ     0xF0000060      ; NB Misc indirect access
  17. NB_MISC_DATA    equ     0xF0000064
  18. PCIEIND_INDEX   equ     0xF00000E0      ; PCIe Core indirect config space access
  19. HTIU_NB_INDEX   equ     0xF0000094      ; HyperTransport indirect config space access
  20.  
  21. ;=============================================================================
  22. ;
  23. ; This code is a part of Kolibri-A and will only work with AMD RS760+ chipsets
  24. ;
  25. ;=============================================================================
  26.  
  27. org $-OS_BASE   ; physical addresses needed at initial stage
  28.  
  29. align 4
  30.  
  31. ;------------------------------------------
  32. ;       params:   al = nbconfig register#
  33. ;       returns: eax = register content
  34. ;
  35. rs7xx_nbconfig_read_pci:
  36.         and     eax, 0x0FC               ; leave register# only
  37.         or      eax, 0x80000000          ; bdf = 0:0.0
  38.         mov     dx,  0x0CF8              ; write to index reg
  39.         out     dx, eax
  40.         add     dl, 4
  41.         in      eax, dx
  42.         ret
  43. align 4
  44.  
  45. rs7xx_nbconfig_flush_pci:
  46.         mov     eax, 0x0B0              ; a scratch reg
  47.         mov     dx,  0xCF8
  48.         out     dx,  eax
  49.         ret
  50.  
  51. align 4
  52.  
  53. ;------------------------------------------
  54. ;       params:   al = nbconfig register#
  55. ;                ebx = register content
  56. ;
  57. rs7xx_nbconfig_write_pci:
  58.         and     eax, 0x0FC               ; leave register# only
  59.         or      eax, 0x80000000          ; bdf = 0:0.0
  60.         mov     dx,  0x0CF8              ; write to index reg
  61.         out     dx, eax
  62.         add     dl, 4
  63.         mov     eax, ebx
  64.         out     dx, eax
  65.         ret
  66.  
  67. ;***************************************************************************
  68. ;   Function
  69. ;      rs7xx_unlock_bar3:     unlocks the BAR3 register of nbconfig that
  70. ;                             makes pcie config address space visible
  71. ;   -----------------------
  72. ;   in: nothing      out: nothing      destroys:   eax ebx edx
  73. ;
  74. ;***************************************************************************
  75. align 4
  76. rs7xx_unlock_bar3:
  77.         mov     eax, NB_MISC_INDEX
  78.         mov     ebx, 0x080                      ; NBMISCIND:0x0; write-enable
  79.         call    rs7xx_nbconfig_write_pci        ; set index
  80.         mov     eax, NB_MISC_DATA
  81.         call    rs7xx_nbconfig_read_pci         ; read data
  82.         mov     ebx, eax
  83.         and     ebx, 0xFFFFFFF7                 ; clear bit3
  84.         mov     eax, NB_MISC_DATA
  85.         call    rs7xx_nbconfig_write_pci        ; write it back
  86.         mov     eax, NB_MISC_INDEX
  87.         xor     ebx, ebx                        ; reg#0; write-locked
  88.         call    rs7xx_nbconfig_write_pci        ; set index
  89.         ret
  90.  
  91.  
  92.  
  93. ;***************************************************************************
  94. ;   Function
  95. ;      rs7xx_pcie_init:
  96. ;
  97. ;   Description
  98. ;       PCIe extended (memory-mapped) config space detection
  99. ;
  100. ;***************************************************************************
  101.  
  102. align 4
  103.  
  104. rs7xx_pcie_init:
  105.         call    rs7xx_unlock_bar3
  106.         mov     al, 0x7C                       ; NB_IOC_CFG_CNTL
  107.         call    rs7xx_nbconfig_read_pci
  108.         mov     ebx, eax
  109. ;       call    rs7xx_nbconfig_flush_pci
  110.         test    ebx, 0x20000000                 ; BAR3 locked?
  111.         jz      $
  112.         mov     al, 0x84                        ; NB_PCI_ARB
  113.         call    rs7xx_nbconfig_read_pci
  114.         shr     eax,16
  115.         and     ax, 7                           ; the Bus range lays here:
  116.         jnz     @f
  117.         mov     ax, 8                                   ; 1=2Mb,  2=4MB,  3=8MB,  4=16MB
  118. @@:
  119.         mov     word[PCIe_bus_range-OS_BASE], ax        ; 5=32Mb, 6=64MB, 7=128Mb, 8=256Mb
  120.         mov     cl, al
  121.         call    rs7xx_nbconfig_flush_pci
  122.         dec     cl                              ; <4M ?
  123.         jz      @f
  124.         dec     cl                              ; one PDE needed anyway
  125. @@:
  126.         mov     ebx, 1
  127.         shl     ebx, cl
  128.         mov     word[mmio_pcie_cfg_pdes-OS_BASE], bx    ; 1..64 PDE(s) needed,
  129.         shl     ebx, 22
  130.         mov     dword[mmio_pcie_cfg_lim-OS_BASE], ebx   ; or 4..256Mb space to map
  131.         dec     dword[mmio_pcie_cfg_lim-OS_BASE]
  132.  
  133.         mov     al, 0x1C                        ; NB_BAR3_PCIEXP_MMCFG
  134.         call    rs7xx_nbconfig_read_pci
  135.         mov     ebx, eax
  136.         call    rs7xx_nbconfig_flush_pci
  137.         mov     eax, ebx
  138.         and     eax, 0xFFE00000                 ; valid bits [31..21]
  139.         jz      $                               ; invalid map!
  140. .addr_found:
  141.         mov     dword[mmio_pcie_cfg_addr-OS_BASE], eax  ; physical address (lower 32 bits)
  142.         add     dword[mmio_pcie_cfg_lim-OS_BASE],  eax
  143.  
  144. ; ---- common mapping procedure ----
  145. ; (eax = phys. address of PCIe conf.space)
  146. ;
  147. map_pcie_pages:
  148.         or      eax, (PG_NOCACHE + PG_SHARED + PG_LARGE + PG_UW)  ;  UW is unsafe, fix it!
  149.         mov     ecx, PCIe_CONFIG_SPACE                  ; linear address
  150.         mov     ebx, ecx
  151.         shr     ebx, 20
  152.         add     ebx, (sys_pgdir - OS_BASE)              ; PgDir entry @
  153.         mov     dl, byte[mmio_pcie_cfg_pdes-OS_BASE]    ; 1 page = 4M in address space
  154.         cmp     dl, 0x34        ; =(USER_DMA_BUFFER - PCIe_CONFIG_SPACE) / 4M
  155.         jb      @f
  156.         mov     dl, 0x33
  157.         mov     byte[mmio_pcie_cfg_pdes-OS_BASE], dl
  158. @@:
  159.         xor     dx,  dx                         ; PDEs counter
  160. .write_pde:
  161.         mov     dword[ebx], eax                 ; map 4 buses
  162.         add     bx,  4                          ; new PDE
  163.         add     eax, 0x400000                   ; +4M phys.
  164.         add     ecx, 0x400000                   ; +4M lin.
  165.         cmp     dl, byte[mmio_pcie_cfg_pdes-OS_BASE]
  166.         jae     .pcie_cfg_mapped
  167.         inc     dl
  168.         jmp     .write_pde
  169. ;        mov     eax, cr3
  170. ;        mov     cr3, eax                        ; flush TLB
  171. .pcie_cfg_mapped:
  172.         ret     ; <<< OK >>>
  173.  
  174. ; ---- stepping 10h CPUs and Fusion APUs: the configspace is stored in MSR_C001_0058 ----
  175. align 4
  176. fusion_pcie_init:
  177.         mov     ecx, 0xC0010058
  178.         rdmsr
  179.         or      edx, edx
  180.         jnz     $                               ; PCIe is in the upper memory. Stop.
  181.         xchg    dl, al
  182.         mov     dword[mmio_pcie_cfg_addr-OS_BASE], eax  ; store the physical address
  183.         mov     ecx, edx
  184.         and     dl, 1
  185.         jz      $                               ; bit[0] = 1 means no PCIe mapping allowed. Stop.
  186.         shr     cl, 2                           ; ecx = log2(number of buses)
  187.         mov     word[PCIe_bus_range-OS_BASE], cx       
  188.         sub     cl, 2
  189.         jae     @f
  190.         xor     cl, cl
  191. @@:
  192.         shl     edx, cl                         ; edx = number of 4M pages to map
  193.         mov     word[mmio_pcie_cfg_pdes-OS_BASE], dx   
  194.         shl     edx, 22
  195.         dec     edx
  196.         add     edx, eax                        ; the upper configspace limit
  197.         mov     dword[mmio_pcie_cfg_lim-OS_BASE], edx
  198.  
  199.         jmp     map_pcie_pages  
  200.  
  201. ; ================================================================================
  202.  
  203. org OS_BASE+$   ; back to the linear address space
  204.  
  205. ;--------------------------------------------------------------
  206. align 4
  207. rs780_read_misc:
  208. ;  in: eax(al) - reg#           out: eax = NBMISCIND data
  209.         push    edx
  210.         mov     edx, NB_MISC_INDEX
  211.         and     eax, 0x07F
  212.         mov     [edx], eax
  213.         add     dl, 4
  214.         mov     eax, [edx]
  215.         pop     edx
  216.         ret
  217.  
  218. ;-------------------------------------------
  219. align 4
  220. rs780_write_misc:
  221. ;  in: eax(al) - reg#     ebx = NBMISCIND data
  222.         push    edx
  223.         mov     edx, NB_MISC_INDEX
  224.         and     eax, 0x07F
  225.         or      eax, 0x080              ; set WE
  226.         mov     [edx], eax
  227.         add     dl, 4
  228.         mov     [edx], ebx
  229.         sub     dl, 4
  230.         xor     eax,   eax
  231.         mov     [edx], eax              ; safety last
  232.         pop     edx
  233.         ret
  234.  
  235. ;-------------------------------------------------------------
  236. align 4
  237. rs780_read_pcieind:
  238. ;  in: ah = bridge#, al = reg#           out: eax = PCIEIND data
  239.         push    edx
  240.         xor     edx, edx
  241.         mov     ah,  dl                 ; bridge# :     0 = Core+GFX;   0x10 = Core+SB
  242.         and     dl,  15                 ;            0x20 = Core+GPP;  2..12 = a PortBridge
  243.         shl     edx, 15                 ; device#
  244.         add     edx, PCIEIND_INDEX      ; full bdf-address
  245.         and     eax, 0x30FF
  246.         or      al,  al
  247.         jnz     @f
  248.         shl     eax, 4                  ; set bits 17..16 for a Core bridge
  249. @@:
  250.         mov     [edx], eax
  251.         add     dl,  4
  252.         mov     eax, [edx]
  253.         pop     edx
  254.         ret
  255.  
  256. ;-------------------------------------------
  257. align 4
  258. rs780_write_pcieind:
  259. ;  in: ah = bridge#, al = reg#,  ebx = PCIEIND data
  260.         push    edx
  261.         xor     edx, edx
  262.         mov     ah,  dl                 ; bridge# :     0 = Core+GFX;   0x10 = Core+SB
  263.         and     dl,  15                 ;            0x20 = Core+GPP;  2..12 = a PortBridge
  264.         shl     edx, 15                 ; device#
  265.         add     edx, PCIEIND_INDEX      ; full bdf-address
  266.         and     eax, 0x30FF
  267.         or      al,  al
  268.         jnz     @f
  269.         shl     eax, 4                  ; set bits 17..16 for a Core bridge
  270. @@:
  271.         mov     [edx], eax
  272.         add     dl,  4
  273.         mov     [edx], ebx
  274.         sub     dl,  4
  275.         xor     eax,   eax
  276.         mov     [edx], eax              ; safety last
  277.         pop     edx
  278.         ret
  279.  
  280. ;------------------------------------------------
  281. align 4
  282. rs780_read_htiu:
  283. ; in:  al = reg#  |  out: eax = HTIU data
  284. ;------------------------------------------------
  285.         push    edx
  286.         mov     edx,  HTIU_NB_INDEX
  287.         and     eax, 0x07F
  288.         mov     [edx], eax
  289.         add     dl,  4
  290.         mov     eax, [edx]
  291.         pop     edx
  292.         ret
  293. ;------------------------------------------------
  294. align 4
  295. rs780_write_htiu:
  296. ; in:  al = reg#; ebx = data
  297. ;------------------------------------------------
  298.         push    edx
  299.         mov     edx,  HTIU_NB_INDEX
  300.         and     eax, 0x07F
  301.         or      eax, 0x100
  302.         mov     [edx], eax
  303.         add     dl,  4
  304.         mov     [edx], ebx
  305.         sub     dl,  4
  306.         xor     eax,   eax
  307.         mov     [edx], eax
  308.         pop     edx
  309.         ret
  310.  
  311. ;------------------------------------------------
  312. align 4
  313. sys_rdmsr:
  314. ;  in: [esp+8] = MSR#
  315. ; out: [esp+8] = MSR[63:32]
  316. ;        [eax] = MSR[31: 0]
  317. ;------------------------------------------------
  318.         push    ecx edx
  319.         mov     ecx, [esp+16]
  320.         rdmsr
  321.         mov     [esp+16], edx
  322.         pop     edx ecx
  323.         ret
  324.  
  325.  
  326.  
  327.