Subversion Repositories Kolibri OS

Rev

Rev 3531 | Rev 3934 | 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. ;      fusion_pcie_init:
  96. ;
  97. ;   Description
  98. ;       PCIe extended  config space detection and mapping
  99. ;
  100. ;***************************************************************************
  101.  
  102. align 4
  103.  
  104.  
  105.  
  106. ; ---- stepping 10h CPUs and Fusion APUs: the configspace is stored in MSR_C001_0058 ----
  107. align 4
  108. fusion_pcie_init:
  109.         mov     ecx, 0xC0010058
  110.         rdmsr
  111.         or      edx, edx
  112.         jnz     $                               ; PCIe is in the upper memory. Stop.
  113.         xchg    dl, al
  114.         mov     dword[mmio_pcie_cfg_addr-OS_BASE], eax  ; store the physical address
  115.         mov     ecx, edx
  116.         and     dl, 1
  117.         jz      $                               ; bit[0] = 1 means no PCIe mapping allowed. Stop.
  118.         shr     cl, 2                           ; ecx = log2(number of buses)
  119.         mov     word[PCIe_bus_range-OS_BASE], cx
  120.         sub     cl, 2
  121.         jae     @f
  122.         xor     cl, cl
  123. @@:
  124.         shl     edx, cl                         ; edx = number of 4M pages to map
  125.         mov     word[mmio_pcie_cfg_pdes-OS_BASE], dx
  126.         shl     edx, 22
  127.         dec     edx
  128.         add     edx, eax                        ; the upper configspace limit
  129.         mov     dword[mmio_pcie_cfg_lim-OS_BASE], edx
  130.  
  131. ; ---- large pages mapping  ----
  132. ; (eax = phys. address of PCIe conf.space)
  133. ;
  134. .map_pcie_pages:
  135.         or      eax, (PG_NOCACHE + PG_SHARED + PG_LARGE + PG_UW)  ;  UW is unsafe!
  136.         mov     ecx, PCIe_CONFIG_SPACE                  ; linear address
  137.         mov     ebx, ecx
  138.         shr     ebx, 20
  139.         add     ebx, (sys_pgdir - OS_BASE)              ; PgDir entry @
  140.         mov     dl, byte[mmio_pcie_cfg_pdes-OS_BASE]    ; 1 page = 4M in address space
  141.         cmp     dl, 0x34        ; =(USER_DMA_BUFFER - PCIe_CONFIG_SPACE) / 4M
  142.         jb      @f
  143.         mov     dl, 0x33
  144.         mov     byte[mmio_pcie_cfg_pdes-OS_BASE], dl
  145. @@:
  146.         xor     dx,  dx                         ; PDEs counter
  147. .write_pde:
  148.         mov     dword[ebx], eax                 ; map 4 buses
  149.         add     bx,  4                          ; new PDE
  150.         add     eax, 0x400000                   ; +4M phys.
  151.         add     ecx, 0x400000                   ; +4M lin.
  152.         cmp     dl, byte[mmio_pcie_cfg_pdes-OS_BASE]
  153.         jae     .pcie_cfg_mapped
  154.         inc     dl
  155.         jmp     .write_pde
  156.  
  157. .pcie_cfg_mapped:
  158.  
  159. create_mmio_pte:
  160.         mov     ecx, mmio_pte                           ; physical address
  161.         or      ecx, (PG_NOCACHE + PG_SHARED + PG_SW)
  162.         mov     ebx, FUSION_MMIO                        ; linear address
  163.         shr     ebx, 20
  164.         add     ebx, (sys_pgdir - OS_BASE)              ; PgDir entry @
  165.         mov     dword[ebx], ecx                         ; Fusion MMIO tables
  166.  
  167. ; ---- short page mapping  ----
  168. .map_apic_mmio:
  169.         mov     ecx, 0x01B      ; APIC BAR
  170.         rdmsr
  171.         and     eax, 0xFFFFF000                         ; physical address
  172.         or      eax, (PG_NOCACHE + PG_SHARED + PG_SW)
  173.         mov     dword[mmio_pte + 0], eax
  174.  
  175.         ret     ; <<< OK >>>
  176.  
  177. ; ================================================================================
  178.  
  179. org OS_BASE+$   ; back to the linear address space
  180.  
  181. ;--------------------------------------------------------------
  182. align 4
  183. rs780_read_misc:
  184. ;  in: eax(al) - reg#           out: eax = NBMISCIND data
  185.         push    edx
  186.         mov     edx, NB_MISC_INDEX
  187.         and     eax, 0x07F
  188.         mov     [edx], eax
  189.         add     dl, 4
  190.         mov     eax, [edx]
  191.         pop     edx
  192.         ret
  193.  
  194. ;-------------------------------------------
  195. align 4
  196. rs780_write_misc:
  197. ;  in: eax(al) - reg#     ebx = NBMISCIND data
  198.         push    edx
  199.         mov     edx, NB_MISC_INDEX
  200.         and     eax, 0x07F
  201.         or      eax, 0x080              ; set WE
  202.         mov     [edx], eax
  203.         add     dl, 4
  204.         mov     [edx], ebx
  205.         sub     dl, 4
  206.         xor     eax,   eax
  207.         mov     [edx], eax              ; safety last
  208.         pop     edx
  209.         ret
  210.  
  211. ;-------------------------------------------------------------
  212. align 4
  213. rs780_read_pcieind:
  214. ;  in: ah = bridge#, al = reg#           out: eax = PCIEIND data
  215.         push    edx
  216.         xor     edx, edx
  217.         mov     ah,  dl                 ; bridge# :     0 = Core+GFX;   0x10 = Core+SB
  218.         and     dl,  15                 ;            0x20 = Core+GPP;  2..12 = a PortBridge
  219.         shl     edx, 15                 ; device#
  220.         add     edx, PCIEIND_INDEX      ; full bdf-address
  221.         and     eax, 0x30FF
  222.         or      al,  al
  223.         jnz     @f
  224.         shl     eax, 4                  ; set bits 17..16 for a Core bridge
  225. @@:
  226.         mov     [edx], eax
  227.         add     dl,  4
  228.         mov     eax, [edx]
  229.         pop     edx
  230.         ret
  231.  
  232. ;-------------------------------------------
  233. align 4
  234. rs780_write_pcieind:
  235. ;  in: ah = bridge#, al = reg#,  ebx = PCIEIND data
  236.         push    edx
  237.         xor     edx, edx
  238.         mov     ah,  dl                 ; bridge# :     0 = Core+GFX;   0x10 = Core+SB
  239.         and     dl,  15                 ;            0x20 = Core+GPP;  2..12 = a PortBridge
  240.         shl     edx, 15                 ; device#
  241.         add     edx, PCIEIND_INDEX      ; full bdf-address
  242.         and     eax, 0x30FF
  243.         or      al,  al
  244.         jnz     @f
  245.         shl     eax, 4                  ; set bits 17..16 for a Core bridge
  246. @@:
  247.         mov     [edx], eax
  248.         add     dl,  4
  249.         mov     [edx], ebx
  250.         sub     dl,  4
  251.         xor     eax,   eax
  252.         mov     [edx], eax              ; safety last
  253.         pop     edx
  254.         ret
  255.  
  256. ;------------------------------------------------
  257. align 4
  258. rs780_read_htiu:
  259. ; in:  al = reg#  |  out: eax = HTIU data
  260. ;------------------------------------------------
  261.         push    edx
  262.         mov     edx,  HTIU_NB_INDEX
  263.         and     eax, 0x07F
  264.         mov     [edx], eax
  265.         add     dl,  4
  266.         mov     eax, [edx]
  267.         pop     edx
  268.         ret
  269. ;------------------------------------------------
  270. align 4
  271. rs780_write_htiu:
  272. ; in:  al = reg#; ebx = data
  273. ;------------------------------------------------
  274.         push    edx
  275.         mov     edx,  HTIU_NB_INDEX
  276.         and     eax, 0x07F
  277.         or      eax, 0x100
  278.         mov     [edx], eax
  279.         add     dl,  4
  280.         mov     [edx], ebx
  281.         sub     dl,  4
  282.         xor     eax,   eax
  283.         mov     [edx], eax
  284.         pop     edx
  285.         ret
  286.  
  287. ;------------------------------------------------
  288. align 4
  289. sys_rdmsr:
  290. ;  in: [esp+8] = MSR#
  291. ; out: [esp+8] = MSR[63:32]
  292. ;        [eax] = MSR[31: 0]
  293. ;------------------------------------------------
  294.         push    ecx edx
  295.         mov     ecx, [esp+16]
  296.         rdmsr
  297.         mov     [esp+16], edx
  298.         pop     edx ecx
  299.         ret
  300.  
  301. ;------------------------------------------------
  302. uglobal
  303.  
  304. align 4
  305. diff16 "apic_data : ", 0, $
  306. apic_data:
  307.  
  308.     .counter dd ?
  309.     .ticks   dd ?
  310.     .t_freq  dd ?
  311. endg
  312.  
  313. apic_timer_reset:
  314.         mov     eax, [pll_frequency.osc]
  315.         shr     eax, 1                                  ; default prescaler - fix it !!
  316.         mov     [apic_data.t_freq], eax
  317.         shr     eax, 4                                  ; 16 per second
  318.         mov     [apic_data.ticks], eax
  319.  
  320.         mov     ebx, LAPIC_BAR+ 0x320
  321.         mov     edx, [ebx]
  322.         and     edx, 0xFFFEFF00
  323.         or      edx, 0x0002003F                         ; int vector + restart
  324.         mov     [ebx], edx
  325.         mov     dword [LAPIC_BAR + 0x380], eax          ; load APICTIC
  326.         ret
  327.  
  328.  
  329. apic_timer_int:
  330.         push    eax
  331.         inc     dword [apic_data.counter]
  332. ;        mov     eax,  [apic_data.ticks]
  333. ;        mov     dword [LAPIC_BAR + 0x380], eax          ; reload APICTIC
  334.         mov     dword [LAPIC_BAR + 0x0B0], 0            ; end of interrupt
  335. ;        mov     dword [LAPIC_BAR + 0x420], 0x3F            ; end of interrupt
  336.         pop     eax
  337.         iretd
  338.  
  339.  
  340.