mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-12-24 23:56:49 +03:00
6cb25c9e01
git-svn-id: svn://kolibrios.org@1678 a494cfbc-eb01-0410-851d-a64ba20cac60
288 lines
7.5 KiB
PHP
288 lines
7.5 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) 2010 KolibriOS team. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;; ;;
|
|
;; AMD HyperTransport bus control ;;
|
|
;; ;;
|
|
;; art_zh <kolibri@jerdev.co.uk> ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
$Revision: 1554 $
|
|
|
|
NB_MISC_INDEX equ 0xF0000060 ; NB Misc indirect access
|
|
NB_MISC_DATA equ 0xF0000064
|
|
PCIEIND_INDEX equ 0xF00000E0 ; PCIe Core indirect config space access
|
|
HTIU_NB_INDEX equ 0xF0000094 ; HyperTransport indirect config space access
|
|
|
|
;=============================================================================
|
|
;
|
|
; This code is a part of Kolibri-A and will only work with AMD RS760+ chipsets
|
|
;
|
|
;=============================================================================
|
|
align 4
|
|
|
|
;------------------------------------------
|
|
; params: al = nbconfig register#
|
|
; returns: eax = register content
|
|
;
|
|
rs7xx_nbconfig_read_pci:
|
|
and eax, 0x0FC ; leave register# only
|
|
or eax, 0x80000000 ; bdf = 0:0.0
|
|
mov dx, 0x0CF8 ; write to index reg
|
|
out dx, eax
|
|
add dl, 4
|
|
in eax, dx
|
|
ret
|
|
align 4
|
|
|
|
rs7xx_nbconfig_flush_pci:
|
|
mov eax, 0x0B0 ; a scratch reg
|
|
mov dx, 0xCF8
|
|
out dx, eax
|
|
ret
|
|
|
|
align 4
|
|
|
|
;------------------------------------------
|
|
; params: al = nbconfig register#
|
|
; ebx = register content
|
|
;
|
|
rs7xx_nbconfig_write_pci:
|
|
and eax, 0x0FC ; leave register# only
|
|
or eax, 0x80000000 ; bdf = 0:0.0
|
|
mov dx, 0x0CF8 ; write to index reg
|
|
out dx, eax
|
|
add dl, 4
|
|
mov eax, ebx
|
|
out dx, eax
|
|
ret
|
|
|
|
;***************************************************************************
|
|
; Function
|
|
; rs7xx_unlock_bar3: unlocks the BAR3 register of nbconfig that
|
|
; makes pcie config address space visible
|
|
; -----------------------
|
|
; in: nothing out: nothing destroys: eax ebx edx
|
|
;
|
|
;***************************************************************************
|
|
align 4
|
|
rs7xx_unlock_bar3:
|
|
mov eax, NB_MISC_INDEX
|
|
mov ebx, 0x080 ; reg#0; write-enable
|
|
call rs7xx_nbconfig_write_pci ; set index
|
|
mov eax, NB_MISC_DATA
|
|
call rs7xx_nbconfig_read_pci ; read data
|
|
mov ebx, eax
|
|
and ebx, 0xFFFFFFF7 ; clear bit3
|
|
mov eax, NB_MISC_DATA
|
|
call rs7xx_nbconfig_write_pci ; write it back
|
|
mov eax, NB_MISC_INDEX
|
|
xor ebx, ebx ; reg#0; write-locked
|
|
call rs7xx_nbconfig_write_pci ; set index
|
|
ret
|
|
|
|
;--------------------------------------------------------------
|
|
align 4
|
|
rs780_read_misc:
|
|
; in: eax(al) - reg# out: eax = NBMISCIND data
|
|
push edx
|
|
mov edx, NB_MISC_INDEX
|
|
and eax, 0x07F
|
|
mov [edx], eax
|
|
add dl, 4
|
|
mov eax, [edx]
|
|
pop edx
|
|
ret
|
|
|
|
;-------------------------------------------
|
|
align 4
|
|
rs780_write_misc:
|
|
; in: eax(al) - reg# ebx = NBMISCIND data
|
|
push edx
|
|
mov edx, NB_MISC_INDEX
|
|
and eax, 0x07F
|
|
or eax, 0x080 ; set WE
|
|
mov [edx], eax
|
|
add dl, 4
|
|
mov [edx], ebx
|
|
sub dl, 4
|
|
xor eax, eax
|
|
mov [edx], eax ; safety last
|
|
pop edx
|
|
ret
|
|
|
|
;-------------------------------------------------------------
|
|
align 4
|
|
rs780_read_pcieind:
|
|
; in: ah = bridge#, al = reg# out: eax = PCIEIND data
|
|
push edx
|
|
xor edx, edx
|
|
mov ah, dl ; bridge# : 0 = Core+GFX; 0x10 = Core+SB
|
|
and dl, 15 ; 0x20 = Core+GPP; 2..12 = a PortBridge
|
|
shl edx, 15 ; device#
|
|
add edx, PCIEIND_INDEX ; full bdf-address
|
|
and eax, 0x30FF
|
|
or al, al
|
|
jnz @f
|
|
shl eax, 4 ; set bits 17..16 for a Core bridge
|
|
@@:
|
|
mov [edx], eax
|
|
add dl, 4
|
|
mov eax, [edx]
|
|
pop edx
|
|
ret
|
|
|
|
;-------------------------------------------
|
|
align 4
|
|
rs780_write_pcieind:
|
|
; in: ah = bridge#, al = reg#, ebx = PCIEIND data
|
|
push edx
|
|
xor edx, edx
|
|
mov ah, dl ; bridge# : 0 = Core+GFX; 0x10 = Core+SB
|
|
and dl, 15 ; 0x20 = Core+GPP; 2..12 = a PortBridge
|
|
shl edx, 15 ; device#
|
|
add edx, PCIEIND_INDEX ; full bdf-address
|
|
and eax, 0x30FF
|
|
or al, al
|
|
jnz @f
|
|
shl eax, 4 ; set bits 17..16 for a Core bridge
|
|
@@:
|
|
mov [edx], eax
|
|
add dl, 4
|
|
mov [edx], ebx
|
|
sub dl, 4
|
|
xor eax, eax
|
|
mov [edx], eax ; safety last
|
|
pop edx
|
|
ret
|
|
|
|
;------------------------------------------------
|
|
align 4
|
|
rs780_read_htiu:
|
|
; in: al = reg# | out: eax = HTIU data
|
|
;------------------------------------------------
|
|
push edx
|
|
mov edx, HTIU_NB_INDEX
|
|
and eax, 0x07F
|
|
mov [edx], eax
|
|
add dl, 4
|
|
mov eax, [edx]
|
|
pop edx
|
|
ret
|
|
;------------------------------------------------
|
|
align 4
|
|
rs780_write_htiu:
|
|
; in: al = reg#; ebx = data
|
|
;------------------------------------------------
|
|
push edx
|
|
mov edx, HTIU_NB_INDEX
|
|
and eax, 0x07F
|
|
or eax, 0x100
|
|
mov [edx], eax
|
|
add dl, 4
|
|
mov [edx], ebx
|
|
sub dl, 4
|
|
xor eax, eax
|
|
mov [edx], eax
|
|
pop edx
|
|
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 .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 $
|
|
|
|
|
|
|
|
|
|
|