/kernel/branches/net/bus/pci/PCIe.inc |
---|
0,0 → 1,119 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) 2010 KolibriOS team. 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: 1463 $ |
;*************************************************************************** |
; 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 equ 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 >>>>>>>>> |
/kernel/branches/net/bus/pci/pci32.inc |
---|
32,63 → 32,91 |
;*************************************************************************** |
;mmio_pci_addr equ 0x400 ; set actual PCI address here to activate user-MMIO |
iglobal |
align 4 |
f62call: |
dd pci_fn_0 |
dd pci_fn_1 |
dd pci_fn_2 |
dd pci_service_not_supported ;3 |
dd pci_read_reg ;4 byte |
dd pci_read_reg ;5 word |
dd pci_read_reg ;6 dword |
dd pci_service_not_supported ;7 |
dd pci_write_reg ;8 byte |
dd pci_write_reg ;9 word |
dd pci_write_reg ;10 dword |
if defined mmio_pci_addr |
dd pci_mmio_init ;11 |
dd pci_mmio_map ;12 |
dd pci_mmio_unmap ;13 |
end if |
endg |
align 4 |
pci_api: |
;cross |
mov eax, ebx |
mov ebx, ecx |
mov ecx, edx |
cmp [pci_access_enabled],1 |
jne no_pci_access_for_applications |
jne pci_service_not_supported |
or al,al |
jnz pci_fn_1 |
movzx edx, al |
if defined mmio_pci_addr |
cmp al, 13 |
ja pci_service_not_supported |
else |
cmp al, 10 |
ja pci_service_not_supported |
end if |
call dword [f62call+edx*4] |
mov dword [esp+32], eax |
ret |
align 4 |
pci_api_drv: |
cmp [pci_access_enabled], 1 |
jne .fail |
cmp eax, 2 |
ja .fail |
jmp dword [f62call+eax*4] |
.fail: |
or eax, -1 |
ret |
;; ============================================ |
pci_fn_0: |
; PCI function 0: get pci version (AH.AL) |
movzx eax,word [BOOT_VAR+0x9022] |
ret |
pci_fn_1: |
cmp al,1 |
jnz pci_fn_2 |
; PCI function 1: get last bus in AL |
mov al,[BOOT_VAR+0x9021] |
ret |
pci_fn_2: |
cmp al,2 |
jne pci_fn_3 |
; PCI function 2: get pci access mechanism |
mov al,[BOOT_VAR+0x9020] |
ret |
pci_fn_3: |
cmp al,4 |
jz pci_read_reg ;byte |
cmp al,5 |
jz pci_read_reg ;word |
cmp al,6 |
jz pci_read_reg ;dword |
cmp al,8 |
jz pci_write_reg ;byte |
cmp al,9 |
jz pci_write_reg ;word |
cmp al,10 |
jz pci_write_reg ;dword |
if defined mmio_pci_addr |
cmp al,11 ; user-level MMIO functions |
jz pci_mmio_init |
cmp al,12 |
jz pci_mmio_map |
cmp al,13 |
jz pci_mmio_unmap |
end if |
no_pci_access_for_applications: |
pci_service_not_supported: |
or eax,-1 |
mov dword [esp+32], eax |
ret |
;*************************************************************************** |
464,6 → 492,7 |
@@: |
pop ecx ; ecx = block size, bytes (expanded to whole page) |
mov ebx, ecx ; user_alloc destroys eax, ecx, edx, but saves ebx |
and eax, 0xFFFFFFF0 |
push eax ; store MMIO physical address + keep 2DWords in the stack |
stdcall user_alloc, ecx |
or eax, eax |
516,7 → 545,8 |
uglobal |
align 4 |
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1) |
pci_emu_dat: times 30*10 db 0 |
pci_emu_dat: |
times 30*10 db 0 |
endg |
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
align 4 |
540,9 → 570,9 |
cmp ebp, 1 ; PCI_FUNCTION_ID |
jnz .not_PCI_BIOS_PRESENT |
mov edx, 'PCI ' |
mov al, [OS_BASE+0x2F0000 + 0x9020] |
mov bx, [OS_BASE+0x2F0000 + 0x9022] |
mov cl, [OS_BASE+0x2F0000 + 0x9021] |
mov al, [BOOT_VAR + 0x9020] |
mov bx, [BOOT_VAR + 0x9022] |
mov cl, [BOOT_VAR + 0x9021] |
xor ah, ah |
jmp .return_abcd |
550,7 → 580,8 |
cmp ebp, 2 ; FIND_PCI_DEVICE |
jne .not_FIND_PCI_DEVICE |
mov ebx, pci_emu_dat |
..nxt: cmp [ebx], dx |
..nxt: |
cmp [ebx], dx |
jne ..no |
cmp [ebx + 2], cx |
jne ..no |
559,7 → 590,8 |
mov bx, [ebx + 4] |
xor ah, ah |
jmp .return_ab |
..no: cmp word[ebx], 0 |
..no: |
cmp word[ebx], 0 |
je ..dev_not_found |
add ebx, 10 |
jmp ..nxt |
572,12 → 604,14 |
jne .not_FIND_PCI_CLASS_CODE |
mov esi, pci_emu_dat |
shl ecx, 8 |
..nxt2: cmp [esi], ecx |
..nxt2: |
cmp [esi], ecx |
jne ..no2 |
mov bx, [esi] |
xor ah, ah |
jmp .return_ab |
..no2: cmp dword[esi], 0 |
..no2: |
cmp dword[esi], 0 |
je ..dev_not_found |
add esi, 10 |
jmp ..nxt2 |
612,7 → 646,8 |
.not_WRITE_CONFIG: |
.unsupported_func: |
mov ah, 0x81 ; FUNC_NOT_SUPPORTED |
.return:mov dword[esp + 4 ], edi |
.return: |
mov dword[esp + 4 ], edi |
mov dword[esp + 8], esi |
.return_abcd: |
mov dword[esp + 24], edx |