;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2010-2024. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; ;; ;; PCIe.INC ;; ;; ;; ;; Extended PCI express services ;; ;; ;; ;; art_zh ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;*************************************************************************** ; 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 >>>>>>>>>