kolibrios-fun/drivers/pci.inc
hidnplayr ade341318e Interpret 64-bit PCI BAR's properly.
git-svn-id: svn://kolibrios.org@7250 a494cfbc-eb01-0410-851d-a64ba20cac60
2018-04-21 08:29:06 +00:00

200 lines
6.6 KiB
PHP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2018. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
struct PCI_header
vendor_id dw ? ; 0x00
device_id dw ? ; 0x02
command dw ? ; 0x04
status dw ? ; 0x06
revision_id db ? ; 0x08
prog_if db ? ; 0x09
subclass db ? ; 0x0A
class_code db ? ; 0x0B
cache_line_size db ? ; 0x0C
latency_timer db ? ; 0x0D
header_type db ? ; 0x0E
bist db ? ; 0x0F
ends
struct PCI_header00 PCI_header
base_addr_0 dd ? ; 0x10
base_addr_1 dd ? ; 0x14
base_addr_2 dd ? ; 0x18
base_addr_3 dd ? ; 0x1C
base_addr_4 dd ? ; 0x20
base_addr_5 dd ? ; 0x24
cardbus_cis_ptr dd ? ; 0x28
subsys_vendor dw ? ; 0x2C
subsys_id dw ? ; 0x2E
exp_rom_addr dd ? ; 0x30
cap_ptr db ? ; 0x34
rb 7 ; reserved
interrupt_line db ? ; 0x3C
interrupt_pin db ? ; 0x3D
min_grant db ? ; 0x3E
max_latency db ? ; 0x3F
ends
struct PCI_header01 PCI_header
base_addr_0 dd ? ; 0x10
base_addr_1 dd ? ; 0x14
prim_bus_nr db ? ; 0x18
sec_bus_nr db ? ; 0x19
sub_bus_nr db ? ; 0x1A
sec_lat_tmr db ? ; 0x1B
io_base db ? ; 0x1C
io_limit db ? ; 0x1D
sec_status dw ? ; 0x1E
mem_base dw ? ; 0x20
mem_limit dw ? ; 0x22
pref_mem_base dw ? ; 0x24
pref_mem_limit dw ? ; 0x26
pref_base_up dd ? ; 0x28
pref_limit_up dd ? ; 0x2C
io_base_up dw ? ; 0x30
io_limit_up dw ? ; 0x32
cap_ptr db ? ; 0x34
rb 3 ; reserved
exp_rom_addr dd ? ; 0x38
interrupt_line db ? ; 0x3C
interrupt_pin db ? ; 0x3E
bridge_ctrl dw ? ; 0x3F
ends
struct PCI_header02 PCI_header
base_addr dd ? ; 0x10
cap_list_offs db ? ; 0x14
rb 1 ; reserved
sec_stat dw ? ; 0x16
pci_bus_nr db ? ; 0x18
cardbus_bus_nr db ? ; 0x19
sub_bus_nr db ? ; 0x1A
cardbus_lat_tmr db ? ; 0x1B
mbar_0 dd ? ; 0x1C
mlimit_0 dd ? ; 0x20
mbar_1 dd ? ; 0x24
mlimit_1 dd ? ; 0x28
iobar_0 dd ? ; 0x2C
iolimit_0 dd ? ; 0x30
iobar_1 dd ? ; 0x34
iolimit_1 dd ? ; 0x38
interrupt_line db ? ; 0x3C
interrupt_pin db ? ; 0x3D
bridge_ctrl dw ? ; 0x3E
subs_did dw ? ; 0x40
subs_vid dw ? ; 0x42
legacy_bar dd ? ; 0x44
ends
; Base address bits
PCI_BASE_ADDRESS_SPACE_IO = 0x01
PCI_BASE_ADDRESS_IO_MASK = 0xFFFFFFFC
PCI_BASE_ADDRESS_MEM_MASK = 0xFFFFFFF0
PCI_BASE_ADDRESS_MEM_TYPE_MASK = 0x00000006
PCI_BASE_ADDRESS_MEM_TYPE_32 = 0x0
PCI_BASE_ADDRESS_MEM_TYPE_RESERVED = 0x02
PCI_BASE_ADDRESS_MEM_TYPE_64 = 0x4
; command bits
PCI_CMD_PIO = 0x01 ; bit0: io space control
PCI_CMD_MMIO = 0x02 ; bit1: memory space control
PCI_CMD_MASTER = 0x04 ; bit2: device acts as a PCI master
PCI_CMD_INTX_DISABLE = 0x400 ; INTx emulation disable
; status bits
PCI_STATUS_CAPA = 0x10 ; bit4: new capabilities available
if used PCI_find_io
proc PCI_find_io stdcall bus, dev
push esi
xor eax, eax
mov esi, PCI_header00.base_addr_0
.check:
invoke PciRead32, [bus], [dev], esi
test eax, PCI_BASE_ADDRESS_IO_MASK
jz .inc
test eax, PCI_BASE_ADDRESS_SPACE_IO
jz .inc
and eax, PCI_BASE_ADDRESS_IO_MASK
pop esi
ret
.inc:
add esi, 4
cmp esi, PCI_header00.base_addr_5
jbe .check
pop esi
xor eax, eax
ret
endp
end if
if used PCI_find_mmio
proc PCI_find_mmio stdcall bus, dev
push esi ebx
mov esi, PCI_header00.base_addr_0
.check:
invoke PciRead32, [bus], [dev], esi
DEBUGF 1, "BAR: 0x%x\n", eax
mov ebx, eax
test eax, PCI_BASE_ADDRESS_SPACE_IO ; MMIO address?
jnz .next
and ebx, PCI_BASE_ADDRESS_MEM_TYPE_MASK
cmp bl, PCI_BASE_ADDRESS_MEM_TYPE_64
je .is64
cmp bl, PCI_BASE_ADDRESS_MEM_TYPE_32
jne .next
; Ok, we have a 32-bit BAR.
and eax, PCI_BASE_ADDRESS_MEM_MASK
pop ebx esi
DEBUGF 1, "32-bit MMIO address found: 0x%x\n", eax
ret
.is64:
; Ok, we have a 64-bit BAR, check if the upper 32-bits are 0, then we can use it..
push eax
add esi, 4
cmp esi, PCI_header00.base_addr_5
ja .fail
invoke PciRead32, [bus], [dev], esi
test eax, eax
pop eax
jnz .next
and eax, PCI_BASE_ADDRESS_MEM_MASK
pop ebx esi
DEBUGF 1, "64-bit MMIO address found: 0x00000000%x\n", eax
ret
.next:
add esi, 4
cmp esi, PCI_header00.base_addr_5
jbe .check
.fail:
xor eax, eax
pop ebx esi
DEBUGF 1, "No usable MMIO addresses found!\n"
ret
endp
end if