forked from KolibriOS/kolibrios
Ivan Baravy
707e7037f0
* Detect last PCI bus via PCI Root Bridge IO protocol (uefi64kos only). * fastcall macro by Tomasz is much cleaner than eficall from osdev board. git-svn-id: svn://kolibrios.org@9227 a494cfbc-eb01-0410-851d-a64ba20cac60
320 lines
7.8 KiB
PHP
320 lines
7.8 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
$Revision$
|
|
|
|
; ACPI Generic Address Structure
|
|
struct GAS
|
|
ASID db ? ; address space id
|
|
BitWidth db ?
|
|
BitOffset db ?
|
|
AccessSize db ?
|
|
Address DQ ?
|
|
ends
|
|
|
|
ASID.SYSTEM_MEMORY = 0
|
|
ASID.SYSTEM_IO = 1
|
|
ASID.PCI_CONFIG = 2
|
|
ASID.PCI_EC = 3
|
|
ASID.PCI_SMBUS = 4
|
|
|
|
ACCESS_SIZE.UNDEFINED = 0
|
|
ACCESS_SIZE.BYTE = 1
|
|
ACCESS_SIZE.WORD = 2
|
|
ACCESS_SIZE.DWORD = 3
|
|
ACCESS_SIZE.QWORD = 4
|
|
|
|
struct ADDRESS_SPACE_RESOURCE_DESCRIPTOR
|
|
Type db ?
|
|
Length dw ?
|
|
ResourceType db ?
|
|
GeneralFlags db ?
|
|
SpecificFlags db ?
|
|
ends
|
|
|
|
struct QWORD_ADDRESS_SPACE_DESCRIPTOR ADDRESS_SPACE_RESOURCE_DESCRIPTOR
|
|
Granularity dq ?
|
|
RangeMinimum dq ?
|
|
RangeMaximum dq ?
|
|
TranslationOffset dq ?
|
|
AddressLength dq ?
|
|
ends
|
|
|
|
struct ACPI_RSDP
|
|
Signature DQ ?
|
|
Checksum db ?
|
|
OEMID rb 6
|
|
Revision db ?
|
|
RsdtAddress dd ?
|
|
; for Revision >= 2
|
|
Length dd ?
|
|
XsdtAddress DQ ?
|
|
ExtChecksum db ?
|
|
Reserved rb 3
|
|
ends
|
|
|
|
struct ACPI_TABLE ; DESCRIPTION_HEADER
|
|
Signature dd ?
|
|
Length dd ?
|
|
Revision db ?
|
|
Checksum db ?
|
|
OEMID rb 6
|
|
OEMTableID rb 8
|
|
OEMRevision rb 4
|
|
CreatorID rb 4
|
|
CreatorRevision rb 4
|
|
ends
|
|
|
|
struct ACPI_RSDT ACPI_TABLE
|
|
Entry rd (0x1000-sizeof.ACPI_TABLE)/4
|
|
ends
|
|
|
|
struct ACPI_HPET ACPI_TABLE
|
|
ID dd ?
|
|
Base GAS
|
|
SeqNumber db ?
|
|
MainCounterMinimum dw ?
|
|
PageProtectionOEM db ?
|
|
ends
|
|
|
|
struct ACPI_MADT ACPI_TABLE
|
|
Local_IC_Addr dd ?
|
|
Flags dd ?
|
|
IntController rb 0x1000-sizeof.ACPI_TABLE-ACPI_MADT.IntController
|
|
ends
|
|
|
|
struct ACPI_FADT ACPI_TABLE
|
|
FirmwareCtrl dd ?
|
|
DSDT dd ?
|
|
db ?
|
|
PreferredPMProfile db ?
|
|
SCI_INT dw ?
|
|
SMI_CMD dd ?
|
|
ACPI_ENABLE db ?
|
|
ACPI_DISABLE db ?
|
|
S4BIOS_REQ db ?
|
|
PSTATE_CNT db ?
|
|
PM1a_EVT_BLK dd ?
|
|
PM1b_EVT_BLK dd ?
|
|
PM1a_CNT_BLK dd ?
|
|
PM1b_CNT_BLK dd ?
|
|
PM2_CNT_BLK dd ?
|
|
PM_TMR_BLK dd ?
|
|
GPE0_BLK dd ?
|
|
GPE1_BLK dd ?
|
|
PM1_EVT_LEN db ?
|
|
PM1_CNT_LEN db ?
|
|
PM2_CNT_LEN db ?
|
|
PM_TMR_LEN db ?
|
|
GPE0_BLK_LEN db ?
|
|
GPE1_BLK_LEN db ?
|
|
GPE1_BASE db ?
|
|
CST_CNT db ?
|
|
P_LVL2_LAT dw ?
|
|
P_LVL3_LAT dw ?
|
|
FLUSH_SIZE dw ?
|
|
FLUSH_STRIDE dw ?
|
|
DUTY_OFFSET db ?
|
|
DUTY_WIDTH db ?
|
|
DAY_ALRM db ?
|
|
MON_ALRM db ?
|
|
CENTURY db ?
|
|
IAPC_BOOT_ARCH dw ?
|
|
db ?
|
|
Flags dd ?
|
|
RESET_REG GAS
|
|
RESET_VALUE db ?
|
|
ARM_BOOT_ARCH dw ?
|
|
FADT_Minor_Version db ?
|
|
X_FIRMWARE_CTRL DQ ?
|
|
X_DSDT DQ ?
|
|
X_PM1a_EVT_BLK GAS
|
|
X_PM1b_EVT_BLK GAS
|
|
X_PM1a_CNT_BLK GAS
|
|
X_PM1b_CNT_BLK GAS
|
|
X_PM2_CNT_BLK GAS
|
|
X_PM_TMR_BLK GAS
|
|
X_GPE0_BLK GAS
|
|
X_GPE1_BLK GAS
|
|
SLEEP_CONTROL_REG GAS
|
|
SLEEP_STATUS_REG GAS
|
|
HypervisorVendorID rb 8
|
|
ends
|
|
|
|
MAX_SSDTS = 32
|
|
|
|
iglobal
|
|
align 4
|
|
acpi_lapic_base dd 0xfee00000 ; default local apic base
|
|
endg
|
|
|
|
uglobal
|
|
align 4
|
|
acpi_dev_data rd 1
|
|
acpi_dev_size rd 1
|
|
|
|
acpi_rsdp_base rd 1
|
|
acpi_rsdt_base rd 1
|
|
acpi_rsdt_size rd 1
|
|
acpi_fadt_base rd 1
|
|
acpi_fadt_size rd 1
|
|
acpi_ssdt_base rd MAX_SSDTS
|
|
acpi_ssdt_size rd MAX_SSDTS
|
|
acpi_ssdt_cnt rd 1
|
|
acpi_madt_base rd 1
|
|
acpi_madt_size rd 1
|
|
acpi_ioapic_base rd MAX_IOAPICS
|
|
acpi_hpet_base rd 1
|
|
acpi_hpet_size rd 1
|
|
cpu_count rd 1
|
|
smpt rd 16
|
|
endg
|
|
|
|
align 4
|
|
; @returns ACPI Root System Description Pointer
|
|
acpi_get_root_ptr:
|
|
mov eax, [acpi_rsdp_base]
|
|
ret
|
|
|
|
align 4
|
|
rsdt_find: ;ecx= rsdt edx= SIG
|
|
push ebx
|
|
push esi
|
|
|
|
lea ebx, [ecx+ACPI_RSDT.Entry]
|
|
mov esi, [ecx+ACPI_RSDT.Length]
|
|
add esi, ecx
|
|
align 4
|
|
.next:
|
|
mov eax, [ebx]
|
|
cmp [eax], edx
|
|
je .done
|
|
|
|
add ebx, 4
|
|
cmp ebx, esi
|
|
jb .next
|
|
|
|
xor eax, eax
|
|
pop esi
|
|
pop ebx
|
|
ret
|
|
|
|
.done:
|
|
mov eax, [ebx]
|
|
pop esi
|
|
pop ebx
|
|
ret
|
|
|
|
align 4
|
|
check_acpi:
|
|
cmp [acpi_rsdp_base], 0
|
|
jz .done
|
|
stdcall map_io_mem, [acpi_rsdp_base], sizeof.ACPI_RSDP, \
|
|
PG_GLOBAL+PAT_WB+PG_READ
|
|
mov [acpi_rsdp_base], eax
|
|
.rsdp_done:
|
|
cmp [acpi_rsdt_base], 0
|
|
jz .rsdt_done
|
|
stdcall map_io_mem, [acpi_rsdt_base], [acpi_rsdt_size], \
|
|
PG_GLOBAL+PAT_WB+PG_READ
|
|
mov [acpi_rsdt_base], eax
|
|
.rsdt_done:
|
|
cmp [acpi_fadt_base], 0
|
|
jz .fadt_done
|
|
stdcall map_io_mem, [acpi_fadt_base], [acpi_fadt_size], \
|
|
PG_GLOBAL+PAT_WB+PG_READ
|
|
mov [acpi_fadt_base], eax
|
|
.fadt_done:
|
|
cmp [acpi_hpet_base], 0
|
|
jz .hpet_done
|
|
stdcall map_io_mem, [acpi_hpet_base], [acpi_hpet_size], \
|
|
PG_GLOBAL+PAT_WB+PG_READ
|
|
mov [acpi_hpet_base], eax
|
|
mov eax, [eax+ACPI_HPET.Base.Address.lo]
|
|
mov [hpet_base], eax
|
|
.hpet_done:
|
|
cmp [acpi_madt_base], 0
|
|
jz .madt_done
|
|
stdcall map_io_mem, [acpi_madt_base], [acpi_madt_size], \
|
|
PG_GLOBAL+PAT_WB+PG_READ
|
|
mov [acpi_madt_base], eax
|
|
|
|
mov ecx, [eax+ACPI_MADT.Local_IC_Addr]
|
|
mov [acpi_lapic_base], ecx
|
|
push eax
|
|
stdcall map_io_mem, ecx, 0x1000, PG_GLOBAL+PG_NOCACHE+PG_SWR
|
|
mov [LAPIC_BASE], eax
|
|
mov ecx, eax
|
|
pop eax
|
|
|
|
mov edi, smpt
|
|
mov ebx, [ecx+APIC_ID]
|
|
shr ebx, 24 ; read APIC ID
|
|
|
|
mov [edi], ebx ; bootstrap always first
|
|
inc [cpu_count]
|
|
add edi, 4
|
|
|
|
mov [ioapic_cnt], 0
|
|
lea edx, [eax+ACPI_MADT.IntController]
|
|
mov ecx, [eax+ACPI_MADT.Length]
|
|
add ecx, eax
|
|
.check:
|
|
mov eax, [edx]
|
|
cmp al, 0
|
|
je .lapic
|
|
cmp al, 1
|
|
je .io_apic
|
|
jmp .next
|
|
.lapic:
|
|
shr eax, 24 ; get APIC ID
|
|
cmp eax, ebx ; skip self
|
|
je .next
|
|
|
|
test [edx+4], byte 1 ; is enabled ?
|
|
jz .next
|
|
|
|
cmp [cpu_count], 16
|
|
jae .next
|
|
|
|
stosd ; store APIC ID
|
|
inc [cpu_count]
|
|
jmp .next
|
|
|
|
.io_apic:
|
|
mov eax, [ioapic_cnt]
|
|
push dword[edx+4]
|
|
pop [acpi_ioapic_base+eax*4]
|
|
push dword[edx+8]
|
|
pop [ioapic_gsi_base+eax*4]
|
|
inc [ioapic_cnt]
|
|
jmp .next
|
|
|
|
.next:
|
|
mov eax, [edx]
|
|
movzx eax, ah
|
|
add edx, eax
|
|
cmp edx, ecx
|
|
jb .check
|
|
.madt_done:
|
|
|
|
xor ecx, ecx
|
|
.next_ssdt:
|
|
cmp ecx, [acpi_ssdt_cnt]
|
|
jz .ssdt_done
|
|
push ecx
|
|
stdcall map_io_mem, [acpi_ssdt_base+ecx*4], [acpi_ssdt_size+ecx*4], \
|
|
PG_GLOBAL+PAT_WB+PG_READ
|
|
pop ecx
|
|
mov [acpi_ssdt_base+ecx*4], eax
|
|
inc ecx
|
|
jmp .next_ssdt
|
|
.ssdt_done:
|
|
|
|
.done:
|
|
ret
|