120 lines
4.4 KiB
PHP
120 lines
4.4 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;; ;;
|
|
;; PCIe.INC ;;
|
|
;; ;;
|
|
;; Extended PCI express services ;;
|
|
;; ;;
|
|
;; art_zh <artem@jerdev.co.uk> ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
$Revision$
|
|
|
|
;***************************************************************************
|
|
; Function
|
|
; pci_ext_config:
|
|
;
|
|
; Description
|
|
; PCIe extended (memory-mapped) config space detection
|
|
;
|
|
; WARNINGs:
|
|
; 1) Very Experimental!
|
|
; 2) direct HT-detection (no ACPI or BIOS service used)
|
|
; 3) Only AMD/HT processors currently supported
|
|
;
|
|
;***************************************************************************
|
|
|
|
PCIe_CONFIG_SPACE = 0xF0000000 ; to be moved to const.inc
|
|
mmio_pcie_cfg_addr dd 0x0 ; intel pcie space may be defined here
|
|
mmio_pcie_cfg_lim dd 0x0 ; upper pcie space address
|
|
|
|
|
|
align 4
|
|
|
|
pci_ext_config:
|
|
|
|
mov ebx, [mmio_pcie_cfg_addr]
|
|
or ebx, ebx
|
|
jz @f
|
|
or ebx, 0x7FFFFFFF ; required by PCI-SIG standards
|
|
jnz .pcie_failed
|
|
add ebx, 0x0FFFFC
|
|
cmp ebx, [mmio_pcie_cfg_lim]; is the space limit correct?
|
|
ja .pcie_failed
|
|
jmp .pcie_cfg_mapped
|
|
@@:
|
|
mov ebx, [cpu_vendor]
|
|
cmp ebx, dword [AMD_str]
|
|
jne .pcie_failed
|
|
mov bx, 0xC184 ; dev = 24, fn = 01, reg = 84h
|
|
|
|
.check_HT_mmio:
|
|
mov cx, bx
|
|
mov ax, 0x0002 ; bus = 0, 1dword to read
|
|
call pci_read_reg
|
|
mov bx, cx
|
|
sub bl, 4
|
|
and al, 0x80 ; check the NP bit
|
|
jz .no_pcie_cfg
|
|
shl eax, 8 ; bus:[27..20], dev:[19:15]
|
|
or eax, 0x00007FFC ; fun:[14..12], reg:[11:2]
|
|
mov [mmio_pcie_cfg_lim], eax
|
|
mov cl, bl
|
|
mov ax, 0x0002 ; bus = 0, 1dword to read
|
|
call pci_read_reg
|
|
mov bx, cx
|
|
test al, 0x03 ; MMIO Base RW enabled?
|
|
jz .no_pcie_cfg
|
|
test al, 0x0C ; MMIO Base locked?
|
|
jnz .no_pcie_cfg
|
|
xor al, al
|
|
shl eax, 8
|
|
test eax, 0x000F0000 ; MMIO Base must be bus0-aligned
|
|
jnz .no_pcie_cfg
|
|
mov [mmio_pcie_cfg_addr], eax
|
|
add eax, 0x000FFFFC
|
|
sub eax, [mmio_pcie_cfg_lim]; MMIO must cover at least one bus
|
|
ja .no_pcie_cfg
|
|
|
|
; -- it looks like a true PCIe config space;
|
|
mov eax, [mmio_pcie_cfg_addr] ; physical address
|
|
or eax, (PG_SHARED + PG_LARGE + PG_USER)
|
|
mov ebx, PCIe_CONFIG_SPACE ; linear address
|
|
mov ecx, ebx
|
|
shr ebx, 20
|
|
add ebx, sys_pgdir ; PgDir entry @
|
|
@@:
|
|
mov dword[ebx], eax ; map 4 buses
|
|
invlpg [ecx]
|
|
cmp bl, 4
|
|
jz .pcie_cfg_mapped ; fix it later
|
|
add bl, 4 ; next PgDir entry
|
|
add eax, 0x400000 ; eax += 4M
|
|
add ecx, 0x400000
|
|
jmp @b
|
|
|
|
.pcie_cfg_mapped:
|
|
|
|
; -- glad to have the extended PCIe config field found
|
|
; mov esi, boot_pcie_ok
|
|
; call boot_log
|
|
ret ; <<<<<<<<<<< OK >>>>>>>>>>>
|
|
|
|
.no_pcie_cfg:
|
|
|
|
xor eax, eax
|
|
mov [mmio_pcie_cfg_addr], eax
|
|
mov [mmio_pcie_cfg_lim], eax
|
|
add bl, 12
|
|
cmp bl, 0xC0 ; MMIO regs lay below this offset
|
|
jb .check_HT_mmio
|
|
.pcie_failed:
|
|
; mov esi, boot_pcie_fail
|
|
; call boot_log
|
|
ret ; <<<<<<<<< FAILURE >>>>>>>>>
|
|
|