3,6 → 3,7 |
;; Copyright (C) 2010 KolibriOS team. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; HT.inc ;; ;; |
;; ;; |
;; AMD HyperTransport bus control ;; |
;; ;; |
22,6 → 23,9 |
; This code is a part of Kolibri-A and will only work with AMD RS760+ chipsets |
; |
;============================================================================= |
|
org $-OS_BASE ; physical addresses needed at initial stage |
|
align 4 |
|
;------------------------------------------ |
71,7 → 75,7 |
align 4 |
rs7xx_unlock_bar3: |
mov eax, NB_MISC_INDEX |
mov ebx, 0x080 ; reg#0; write-enable |
mov ebx, 0x080 ; NBMISCIND:0x0; write-enable |
call rs7xx_nbconfig_write_pci ; set index |
mov eax, NB_MISC_DATA |
call rs7xx_nbconfig_read_pci ; read data |
84,6 → 88,90 |
call rs7xx_nbconfig_write_pci ; set index |
ret |
|
|
|
;*************************************************************************** |
; Function |
; rs7xx_pcie_init: |
; |
; Description |
; PCIe extended (memory-mapped) config space detection |
; |
;*************************************************************************** |
|
align 4 |
|
rs7xx_pcie_init: |
call rs7xx_unlock_bar3 |
mov al, 0x7C ; NB_IOC_CFG_CNTL |
call rs7xx_nbconfig_read_pci |
mov ebx, eax |
; call rs7xx_nbconfig_flush_pci |
test ebx, 0x20000000 ; BAR3 locked? |
jz $ |
mov al, 0x84 ; NB_PCI_ARB |
call rs7xx_nbconfig_read_pci |
shr eax,16 |
and ax, 7 ; the Bus range lays here: |
jnz @f |
mov ax, 8 ; 1=2Mb, 2=4MB, 3=8MB, 4=16MB |
@@: |
mov word[PCIe_bus_range-OS_BASE], ax ; 5=32Mb, 6=64MB, 7=128Mb, 8=256Mb |
mov cl, al |
call rs7xx_nbconfig_flush_pci |
dec cl ; <4M ? |
jz @f |
dec cl ; one PDE needed anyway |
@@: |
mov ebx, 1 |
shl ebx, cl |
mov word[mmio_pcie_cfg_pdes-OS_BASE], bx ; 1..64 PDE(s) needed, |
shl ebx, 22 |
mov dword[mmio_pcie_cfg_lim-OS_BASE], ebx ; or 4..256Mb space to map |
dec dword[mmio_pcie_cfg_lim-OS_BASE] |
|
mov al, 0x1C ; NB_BAR3_PCIEXP_MMCFG |
call rs7xx_nbconfig_read_pci |
mov ebx, eax |
call rs7xx_nbconfig_flush_pci |
mov eax, ebx |
and eax, 0xFFE00000 ; valid bits [31..21] |
jz $ ; NB BAR3 may be invisible! |
.addr_found: |
mov dword[mmio_pcie_cfg_addr-OS_BASE], eax ; physical address (lower 32 bits) |
add dword[mmio_pcie_cfg_lim-OS_BASE], eax |
|
or eax, (PG_NOCACHE + PG_SHARED + PG_LARGE + PG_UW) ; by the way, UW is unsafe! |
mov ecx, PCIe_CONFIG_SPACE ; linear address |
mov ebx, ecx |
shr ebx, 20 |
add ebx, (sys_pgdir - OS_BASE) ; PgDir entry @ |
mov dl, byte[mmio_pcie_cfg_pdes-OS_BASE] ; 1 page = 4M in address space |
cmp dl, 0x34 ; =(USER_DMA_BUFFER - PCIe_CONFIG_SPACE) / 4M |
jb @f |
mov dl, 0x33 |
mov byte[mmio_pcie_cfg_pdes-OS_BASE], dl |
@@: |
xor dx, dx ; PDEs counter |
.write_pde: |
mov dword[ebx], eax ; map 4 buses |
add bx, 4 ; new PDE |
add eax, 0x400000 ; +4M phys. |
add ecx, 0x400000 ; +4M lin. |
cmp dl, byte[mmio_pcie_cfg_pdes-OS_BASE] |
jae .pcie_cfg_mapped |
inc dl |
jmp .write_pde |
; mov eax, cr3 |
; mov cr3, eax ; flush TLB |
.pcie_cfg_mapped: |
ret ; <<< OK >>> |
|
|
; ================================================================================ |
|
org OS_BASE+$ ; back to the linear address space |
|
;-------------------------------------------------------------- |
align 4 |
rs780_read_misc: |
192,96 → 280,4 |
|
|
|
;*************************************************************************** |
; Function |
; rs7xx_pcie_init: |
; |
; Description |
; PCIe extended (memory-mapped) config space detection |
; |
;*************************************************************************** |
|
align 4 |
|
rs7xx_pcie_init: |
call rs7xx_unlock_bar3 |
mov al, 0x7C ; NB_IOC_CFG_CNTL |
call rs7xx_nbconfig_read_pci |
mov ebx, eax |
call rs7xx_nbconfig_flush_pci |
test ebx, 0x20000000 ; BAR3 locked? |
jz .rs7xx_pcie_blocked |
mov al, 0x84 ; NB_PCI_ARB |
call rs7xx_nbconfig_read_pci |
shr eax,16 |
and ax, 7 ; the Bus range lays here: |
jnz @f |
mov ax, 8 ; 1=2Mb, 2=4MB, 3=8MB, 4=16MB |
@@: |
mov [PCIe_bus_range], ax ; 5=32Mb, 6=64MB, 7=128Mb, 8=256Mb |
mov cl, al |
call rs7xx_nbconfig_flush_pci |
dec cl ; <4M ? |
jnz @f |
inc cl ; one PDE needed anyway |
@@: |
dec cl |
mov ebx, 1 |
shl ebx, cl |
mov [mmio_pcie_cfg_pdes], bx ; 1..64 PDE(s) needed, |
shl ebx, 22 |
mov [mmio_pcie_cfg_lim], ebx ; or 4..256Mb space to map |
dec [mmio_pcie_cfg_lim] |
|
mov al, 0x1C ; NB_BAR3_PCIEXP_MMCFG |
call rs7xx_nbconfig_read_pci |
mov ebx, eax |
call rs7xx_nbconfig_flush_pci |
mov eax, ebx |
and eax, 0xFFE00000 ; valid bits [31..21] |
jz .rs7xx_pcie_blocked ; NB BAR3 may be invisible! |
; try to get pcie ecfg address indirectly |
.addr_found: |
mov [mmio_pcie_cfg_addr], eax ; physical address (lower 32 bits) |
add [mmio_pcie_cfg_lim], eax |
|
or eax, (PG_SHARED + PG_LARGE + PG_UW) ; by the way, UW is unsafe! |
mov ecx, PCIe_CONFIG_SPACE ; linear address |
mov ebx, ecx |
shr ebx, 20 |
add ebx, sys_pgdir ; PgDir entry @ |
mov dl, byte[mmio_pcie_cfg_pdes] ; 1 page = 4M in address space |
cmp dl, (USER_DMA_BUFFER - PCIe_CONFIG_SPACE) / 4194304 |
jb @f |
mov dl, ((USER_DMA_BUFFER - PCIe_CONFIG_SPACE) / 4194304) - 1 |
mov byte[mmio_pcie_cfg_pdes], dl |
@@: |
xor dx, dx ; PDEs counter |
@@: |
mov dword[ebx], eax ; map 4 buses |
add bx, 4 ; new PDE |
add eax, 0x400000 ; +4M phys. |
add ecx, 0x400000 ; +4M lin. |
cmp dl, byte[mmio_pcie_cfg_pdes] |
jnc .pcie_cfg_mapped |
inc dl |
jmp @b |
mov eax, cr3 |
mov cr3, eax ; flush TLB |
.pcie_cfg_mapped: |
mov esi, boot_pcie_ok |
call boot_log |
ret ; <<< OK >>> |
.rs7xx_pcie_fail: |
mov esi, boot_rs7xx_fail |
call boot_log |
jmp $ |
.rs7xx_pcie_blocked: |
mov esi, boot_rs7xx_blkd |
call boot_log |
jmp $ |
|
|
|
|
|