Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) 2010-17 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.  
  117.         shr     cl, 2
  118.         mov     word[PCIe_bus_range-OS_BASE], cx
  119.         sub     cl, 2
  120.         jae     @f
  121.         xor     cl, cl
  122. @@:
  123.         shl     edx, cl                         ; edx = number of 4M pages to map
  124.         mov     word[mmio_pcie_cfg_pdes-OS_BASE], dx
  125.         shl     edx, 22
  126.         dec     edx
  127.         add     edx, eax                        ; the upper configspace limit
  128.         mov     dword[mmio_pcie_cfg_lim-OS_BASE], edx
  129.  
  130. ; ---- large pages mapping  ----
  131. ; (eax = phys. address of PCIe conf.space)
  132. ;
  133. .map_pcie_pages:
  134.         or      eax, (PG_NOCACHE + PG_SHARED + PG_LARGE + PG_UW)  ;  UW is unsafe!
  135.         mov     ecx, PCIe_CONFIG_SPACE                  ; linear address
  136.         mov     ebx, ecx
  137.         shr     ebx, 20
  138.         add     ebx, (sys_pgdir - OS_BASE)              ; PgDir entry @
  139.         mov     dl, byte[mmio_pcie_cfg_pdes-OS_BASE]    ; 1 page = 4M in address space
  140.         cmp     dl, 0x34        ; =(USER_DMA_BUFFER - PCIe_CONFIG_SPACE) / 4M
  141.         jb      @f
  142.         mov     dl, 0x33
  143.         mov     byte[mmio_pcie_cfg_pdes-OS_BASE], dl
  144. @@:
  145.         xor     dx,  dx                         ; PDEs counter
  146. .write_pde:
  147.         mov     dword[ebx], eax                 ; map 4 buses
  148.         add     bx,  4                          ; new PDE
  149.         add     eax, 0x400000                   ; +4M phys.
  150.         add     ecx, 0x400000                   ; +4M lin.
  151.         cmp     dl, byte[mmio_pcie_cfg_pdes-OS_BASE]
  152.         jae     .pcie_cfg_mapped
  153.         inc     dl
  154.         jmp     .write_pde
  155.  
  156. .pcie_cfg_mapped:
  157.  
  158. create_mmio_pte:
  159.         mov     ecx, mmio_pte                           ; physical address
  160.         or      ecx, (PG_NOCACHE + PG_SHARED + PG_UW)
  161.         mov     ebx, FUSION_MMIO                        ; linear address
  162.         shr     ebx, 20
  163.         add     ebx, (sys_pgdir - OS_BASE)              ; PgDir entry @
  164.         mov     dword[ebx], ecx                         ; Fusion MMIO tables
  165.  
  166. ; ---- map APIC regs  ----
  167. .map_apic_mmio:
  168.         mov     ecx, 0x01B      ; APIC BAR
  169.         rdmsr
  170.         and     eax, 0xFFFFF000                         ; physical address
  171.         or      eax, (PG_NOCACHE + PG_SHARED + PG_UW)
  172.         mov     ebx, mmio_pte
  173.         mov     [ebx], eax
  174.  
  175. ; ---- map GPU MMRegs  ----
  176. .map_gpu_mmr:
  177.         mov     eax, [mmio_pcie_cfg_addr-OS_BASE]       ; PCIe space
  178. ;       add     eax, 0x08018                            ; b:0, d:1, f:0, reg=18 << fam.14h GPU BAR
  179.         add     eax, 0x08024                            ; b:0, d:1, f:0, reg=24 << fam.16h GPU BAR
  180.         mov     eax, [eax]
  181.  
  182.         xor     al, al                                  ; physical address
  183.         or      eax, (PG_NOCACHE + PG_SHARED + PG_UW)
  184. @@:
  185.         add   bl, 4
  186.         mov     [ebx], eax
  187.         add   eax, 0x01000
  188.         cmp   bl, 16*4    ; map 15 pages
  189.         jb    @b
  190.  
  191.         ret     ; <<< OK >>>
  192.  
  193. ; ================================================================================
  194.  
  195. org OS_BASE+$   ; back to the linear address space
  196.  
  197. ;--------------------------------------------------------------
  198. align 4
  199. rs780_read_misc:
  200. ;  in: eax(al) - reg#           out: eax = NBMISCIND data
  201.         push    edx
  202.         mov     edx, NB_MISC_INDEX
  203.         and     eax, 0x07F
  204.         mov     [edx], eax
  205.         add     dl, 4
  206.         mov     eax, [edx]
  207.         pop     edx
  208.         ret
  209.  
  210. ;-------------------------------------------
  211. align 4
  212. rs780_write_misc:
  213. ;  in: eax(al) - reg#     ebx = NBMISCIND data
  214.         push    edx
  215.         mov     edx, NB_MISC_INDEX
  216.         and     eax, 0x07F
  217.         or      eax, 0x080              ; set WE
  218.         mov     [edx], eax
  219.         add     dl, 4
  220.         mov     [edx], ebx
  221.         sub     dl, 4
  222.         xor     eax,   eax
  223.         mov     [edx], eax              ; safety last
  224.         pop     edx
  225.         ret
  226.  
  227. ;-------------------------------------------------------------
  228. align 4
  229. rs780_read_pcieind:
  230. ;  in: ah = bridge#, al = reg#           out: eax = PCIEIND data
  231.         push    edx
  232.         xor     edx, edx
  233.         mov     ah,  dl                 ; bridge# :     0 = Core+GFX;   0x10 = Core+SB
  234.         and     dl,  15                 ;            0x20 = Core+GPP;  2..12 = a PortBridge
  235.         shl     edx, 15                 ; device#
  236.         add     edx, PCIEIND_INDEX      ; full bdf-address
  237.         and     eax, 0x30FF
  238.         or      al,  al
  239.         jnz     @f
  240.         shl     eax, 4                  ; set bits 17..16 for a Core bridge
  241. @@:
  242.         mov     [edx], eax
  243.         add     dl,  4
  244.         mov     eax, [edx]
  245.         pop     edx
  246.         ret
  247.  
  248. ;-------------------------------------------
  249. align 4
  250. rs780_write_pcieind:
  251. ;  in: ah = bridge#, al = reg#,  ebx = PCIEIND data
  252.         push    edx
  253.         xor     edx, edx
  254.         mov     ah,  dl                 ; bridge# :     0 = Core+GFX;   0x10 = Core+SB
  255.         and     dl,  15                 ;            0x20 = Core+GPP;  2..12 = a PortBridge
  256.         shl     edx, 15                 ; device#
  257.         add     edx, PCIEIND_INDEX      ; full bdf-address
  258.         and     eax, 0x30FF
  259.         or      al,  al
  260.         jnz     @f
  261.         shl     eax, 4                  ; set bits 17..16 for a Core bridge
  262. @@:
  263.         mov     [edx], eax
  264.         add     dl,  4
  265.         mov     [edx], ebx
  266.         sub     dl,  4
  267.         xor     eax,   eax
  268.         mov     [edx], eax              ; safety last
  269.         pop     edx
  270.         ret
  271.  
  272. ;------------------------------------------------
  273. align 4
  274. rs780_read_htiu:
  275. ; in:  al = reg#  |  out: eax = HTIU data
  276. ;------------------------------------------------
  277.         push    edx
  278.         mov     edx,  HTIU_NB_INDEX
  279.         and     eax, 0x07F
  280.         mov     [edx], eax
  281.         add     dl,  4
  282.         mov     eax, [edx]
  283.         pop     edx
  284.         ret
  285. ;------------------------------------------------
  286. align 4
  287. rs780_write_htiu:
  288. ; in:  al = reg#; ebx = data
  289. ;------------------------------------------------
  290.         push    edx
  291.         mov     edx,  HTIU_NB_INDEX
  292.         and     eax, 0x07F
  293.         or      eax, 0x100
  294.         mov     [edx], eax
  295.         add     dl,  4
  296.         mov     [edx], ebx
  297.         sub     dl,  4
  298.         xor     eax,   eax
  299.         mov     [edx], eax
  300.         pop     edx
  301.         ret
  302.  
  303. ;------------------------------------------------
  304. align 4
  305. sys_rdmsr:
  306. ;  in: [esp+8] = MSR#
  307. ; out: [esp+8] = MSR[63:32]
  308. ;        [eax] = MSR[31: 0]
  309. ;------------------------------------------------
  310.         push    ecx edx
  311.         mov     ecx, [esp+16]
  312.         rdmsr
  313.         mov     [esp+16], edx
  314.         pop     edx ecx
  315.         ret
  316.  
  317. ;------------------------------------------------
  318. uglobal
  319.  
  320. align 4
  321. diff16 "apic_data : ", 0, $
  322. apic_data:
  323.  
  324.     .counter dd ?
  325.     .ticks   dd ?
  326.     .t_freq  dd ?
  327.     .gpu_r6998 dd ?
  328. endg
  329.  
  330. apic_timer_reset:
  331.         mov     eax, [pll_frequency.osc]
  332.         shr     eax, 1                                  ; default prescaler - fix it !!
  333.         mov     [apic_data.t_freq], eax
  334.         shr     eax, 4                                  ; 16 per second
  335.         mov     [apic_data.ticks], eax
  336.  
  337.         mov     ebx, LAPIC_BAR+ 0x320
  338.         mov     edx, [ebx]
  339.         and     edx, 0xFFFEFF00
  340.         or      edx, 0x0002003F                         ; int vector + restart
  341. ;--     mov     [ebx], edx
  342.         mov     dword [LAPIC_BAR + 0x380], eax          ; load APICTIC
  343.  
  344. ; ret
  345.  
  346. init_hw_cursor:
  347.         call    alloc_page                       ; eax = phys. addr
  348.         push    eax
  349.         or      eax, (PG_NOCACHE + PG_SHARED + PG_UW)    
  350.         mov     [mmio_pte + OS_BASE + 15*4], eax ; mapped to the end of GPU MMRegs
  351.         mov     edi, GPU_CURSOR                  ; lin. addr
  352.         invlpg  [edi]
  353.         xor     ecx, ecx
  354. .fill64pix:
  355.         xor     ebx, ebx
  356.         mov     eax, 0x80000000                 ; black, non-transparent
  357. .check_pix:
  358.         cmp     ebx, ecx
  359.         jbe     @f
  360.         xor     eax, eax                        ; transparent
  361. @@:
  362.         mov     [edi + ebx*4], eax
  363.         inc     ebx
  364.         cmp     bl, 64
  365.         jb      .check_pix
  366.         inc     ecx
  367.         cmp     ecx, 16
  368.         je      @f
  369. ;       add     edi, 64*4                       ; evergreen cursor is 64x64pix
  370.         add     edi, 128*4                      ; si cursor is 128x128pix
  371.         jmp     .fill64pix
  372. @@:
  373.         pop     eax
  374.         mov     dword[GPU_MMR + 0x0699C], eax        ; cur_surface_addr
  375.         mov     dword[GPU_MMR + 0x069A0], 0x000F000F ; cur_size    = 16x16
  376.         mov     dword[GPU_MMR + 0x069A4], 0          ; cur_adr_hi
  377.         mov     dword[GPU_MMR + 0x069A8], 0x02000100 ; cur_pos     = 512,256
  378.         mov     dword[GPU_MMR + 0x069AC], 0          ; cur_hotspot = 0,0
  379.  
  380.         mov     dword[GPU_MMR + 0x06998], 0x00000301 ; set it!
  381.  
  382.  
  383.  
  384.         ret
  385.  
  386.  
  387. apic_timer_int:
  388.         push    eax
  389.         inc     dword [apic_data.counter]
  390. ;        mov     eax,  [apic_data.ticks]
  391. ;        mov     dword [LAPIC_BAR + 0x380], eax          ; reload APICTIC
  392.         mov     dword [LAPIC_BAR + 0x0B0], 0            ; end of interrupt
  393. ;        mov     dword [LAPIC_BAR + 0x420], 0x3F            ; end of interrupt
  394.         pop     eax
  395.         iretd
  396.  
  397.  
  398.