758 lines
17 KiB
C++
758 lines
17 KiB
C++
//++
|
|
//
|
|
// Copyright (c) Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// blacpi.cpp
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements ACPI support for the boot loader environment.
|
|
//
|
|
// Environment:
|
|
//
|
|
// Boot loader.
|
|
//
|
|
//--
|
|
|
|
#include "bl.h"
|
|
|
|
#pragma pack(1)
|
|
|
|
//
|
|
// Generic Address Structure (GAS)
|
|
//
|
|
|
|
#define ACPI_GAS_MEMORY 0
|
|
#define ACPI_GAS_IO 1
|
|
#define ACPI_GAS_PCI 2
|
|
|
|
#define ACPI_GAS_ACCESS_SIZE_UNDEFINED 0
|
|
#define ACPI_GAS_ACCESS_SIZE_BYTE 1
|
|
#define ACPI_GAS_ACCESS_SIZE_WORD 2
|
|
#define ACPI_GAS_ACCESS_SIZE_DWORD 3
|
|
#define ACPI_GAS_ACCESS_SIZE_QWORD 4
|
|
|
|
typedef struct _ACPI_GAS {
|
|
UINT8 AddressSpaceId;
|
|
UINT8 RegisterBitWidth;
|
|
UINT8 RegisterBitOffset;
|
|
UINT8 AccessSize;
|
|
UINT64 Address;
|
|
} ACPI_GAS, *PACPI_GAS;
|
|
|
|
C_ASSERT(sizeof(ACPI_GAS) == 12);
|
|
|
|
//
|
|
// Root System Description Pointer (RSDP)
|
|
//
|
|
|
|
typedef struct _ACPI_RSDP {
|
|
CHAR Signature[8];
|
|
UINT8 Checksum;
|
|
CHAR OemId[6];
|
|
UINT8 Revision;
|
|
UINT32 RsdtAddress;
|
|
UINT32 Length;
|
|
UINT64 XsdtAddress;
|
|
UINT8 ExtendedChecksum;
|
|
UINT8 Reserved[3];
|
|
} ACPI_RSDP, *PACPI_RSDP;
|
|
|
|
C_ASSERT(sizeof(ACPI_RSDP) == 36);
|
|
|
|
//
|
|
// Root System Description Table (RSDT)
|
|
//
|
|
|
|
typedef struct _ACPI_RSDT {
|
|
UINT8 Signature[4];
|
|
UINT32 Length;
|
|
UINT8 Revision;
|
|
UINT8 Checksum;
|
|
UINT8 OemId[6];
|
|
UINT8 OemTableId[8];
|
|
UINT32 OemRevision;
|
|
UINT32 CreatorId;
|
|
UINT32 CreatorRevision;
|
|
UINT32 Entry[];
|
|
} ACPI_RSDT, *PACPI_RSDT;
|
|
|
|
C_ASSERT(sizeof(ACPI_RSDT) == 36);
|
|
|
|
//
|
|
// Multiple APIC Description Table (MADT)
|
|
//
|
|
|
|
typedef struct _ACPI_MADT {
|
|
UINT8 Signature[4];
|
|
UINT32 Length;
|
|
UINT8 Revision;
|
|
UINT8 Checksum;
|
|
UINT8 OemId[6];
|
|
UINT8 OemTableId[8];
|
|
UINT32 OemRevision;
|
|
UINT32 CreatorId;
|
|
UINT32 CreatorRevision;
|
|
UINT32 LocalApicAddress;
|
|
UINT32 Flags;
|
|
UINT8 ApicStructures[];
|
|
} ACPI_MADT, *PACPI_MADT;
|
|
|
|
C_ASSERT(sizeof(ACPI_MADT) == 44);
|
|
|
|
#define ACPI_APIC_TYPE_PROCESSOR_LOCAL 0
|
|
|
|
typedef struct _ACPI_MADT_ENTRY {
|
|
UINT8 Type;
|
|
UINT8 Length;
|
|
} ACPI_MADT_ENTRY, *PACPI_MADT_ENTRY;
|
|
|
|
typedef struct _ACPI_PROCESSOR_LOCAL_APIC {
|
|
UINT8 Type;
|
|
UINT8 Length;
|
|
UINT8 AcpiProcessorId;
|
|
UINT8 ApicId;
|
|
union {
|
|
struct {
|
|
UINT32 Enabled:1;
|
|
UINT32 Reserved:31;
|
|
} s1;
|
|
UINT32 Flags;
|
|
} u1;
|
|
} ACPI_PROCESSOR_LOCAL_APIC, *PACPI_PROCESSOR_LOCAL_APIC;
|
|
|
|
C_ASSERT(sizeof(ACPI_PROCESSOR_LOCAL_APIC) == 8);
|
|
|
|
//
|
|
//System Resource Affinity Table (SRAT)
|
|
//
|
|
|
|
typedef struct _ACPI_SRAT {
|
|
UINT8 Signature[4];
|
|
UINT32 Length;
|
|
UINT8 Revision;
|
|
UINT8 Checksum;
|
|
UINT8 OemId[6];
|
|
UINT8 OemTableId[8];
|
|
UINT32 OemRevision;
|
|
UINT32 CreatorId;
|
|
UINT32 CreatorRevision;
|
|
UINT8 Reserved[12];
|
|
UINT8 SratStructures[];
|
|
} ACPI_SRAT, *PACPI_SRAT;
|
|
|
|
C_ASSERT(sizeof(ACPI_SRAT) == 48);
|
|
|
|
#define ACPI_SRAT_TYPE_PROC_AFFINITY_ENTRY 0
|
|
#define ACPI_SRAT_TYPE_MEM_AFFINITY_ENTRY 1
|
|
|
|
typedef ACPI_MADT_ENTRY ACPI_SRAT_ENTRY;
|
|
typedef PACPI_MADT_ENTRY PACPI_SRAT_ENTRY;
|
|
|
|
typedef struct _ACPI_SRAT_PROC_AFFINITY_ENTRY {
|
|
UINT8 Type;
|
|
UINT8 Length;
|
|
UINT8 ProximityDomainLowEightBits;
|
|
UINT8 ApicID;
|
|
UINT32 Flags;
|
|
UINT8 LocalApicEid;
|
|
UINT8 ProximityDomainHighTwentyFourBits[3];
|
|
UINT32 Reserved;
|
|
} ACPI_SRAT_PROC_AFFINITY_ENTRY, *PACPI_SRAT_PROC_AFFINITY_ENTRY;
|
|
|
|
typedef struct _ACPI_SRAT_MEM_AFFINITY_ENTRY {
|
|
UINT8 Type;
|
|
UINT8 Length;
|
|
UINT32 ProximityDomain;
|
|
UINT8 Reserved[2];
|
|
UINT32 BaseAddressLow;
|
|
UINT32 BaseAddressHigh;
|
|
UINT32 LengthLow;
|
|
UINT32 LengthHigh;
|
|
UINT32 Reserved2;
|
|
UINT32 Flags;
|
|
UINT8 Reserved3[8];
|
|
} ACPI_SRAT_MEM_AFFINITY_ENTRY, *PACPI_SRAT_MEM_AFFINITY_ENTRY;
|
|
|
|
//
|
|
// Fixed ACPI Description Table (FADT)
|
|
//
|
|
|
|
#define ACPI_FADT_FLAGS_RESET_SUPPORTED 0x400
|
|
|
|
typedef struct _ACPI_FADT {
|
|
UINT8 Signature[4];
|
|
UINT32 Length;
|
|
UINT8 Revision;
|
|
UINT8 Checksum;
|
|
UINT8 OemId[6];
|
|
UINT8 OemTableId[8];
|
|
UINT32 OemRevision;
|
|
UINT32 CreatorId;
|
|
UINT32 CreatorRevision;
|
|
UINT8 Data1[112-36];
|
|
UINT32 Flags;
|
|
ACPI_GAS ResetRegister;
|
|
UINT8 ResetValue;
|
|
UINT8 Data2[244-129];
|
|
} ACPI_FADT, *PACPI_FADT;
|
|
|
|
C_ASSERT(FIELD_OFFSET(ACPI_FADT, Flags) == 112);
|
|
C_ASSERT(FIELD_OFFSET(ACPI_FADT, ResetRegister) == 116);
|
|
C_ASSERT(FIELD_OFFSET(ACPI_FADT, ResetValue) == 128);
|
|
C_ASSERT(sizeof(ACPI_FADT) == 244);
|
|
|
|
#pragma pack()
|
|
|
|
PACPI_FADT BlAcpiFadt;
|
|
PACPI_MADT BlAcpiMadt;
|
|
UINT32 BlAcpiNumberOfProcessors;
|
|
PACPI_RSDP BlAcpiRsdp;
|
|
PVOID BlAcpiRsdpAddress;
|
|
PACPI_RSDT BlAcpiRsdt;
|
|
PACPI_SRAT BlAcpiSrat;
|
|
|
|
PACPI_RSDP
|
|
BlAcpiLocateRsdp(
|
|
VOID
|
|
)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function locates the ACPI RSDP structure.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ACPI RSDP structure, if located.
|
|
// NULL, otherwise.
|
|
//
|
|
//--
|
|
|
|
{
|
|
ULONG_PTR End;
|
|
PACPI_RSDP Rsdp;
|
|
ULONG_PTR Start;
|
|
|
|
Start = 0xE0000;
|
|
End = 0x100000;
|
|
|
|
while (Start < End) {
|
|
|
|
Rsdp = (PACPI_RSDP) Start;
|
|
|
|
if ((Rsdp->Signature[0] == 'R') &&
|
|
(Rsdp->Signature[1] == 'S') &&
|
|
(Rsdp->Signature[2] == 'D') &&
|
|
(Rsdp->Signature[3] == ' ') &&
|
|
(Rsdp->Signature[4] == 'P') &&
|
|
(Rsdp->Signature[5] == 'T') &&
|
|
(Rsdp->Signature[6] == 'R') &&
|
|
(Rsdp->Signature[7] == ' ') &&
|
|
(BlRtlComputeChecksum8(Rsdp, 20) == 0)
|
|
) {
|
|
|
|
return Rsdp;
|
|
}
|
|
|
|
Start += 0x10;
|
|
}
|
|
|
|
Start = (ULONG_PTR) BlMmExtendedBiosDataArea;
|
|
End = Start + 0x10000;
|
|
|
|
while (Start < End) {
|
|
|
|
Rsdp = (PACPI_RSDP) Start;
|
|
|
|
if ((Rsdp->Signature[0] == 'R') &&
|
|
(Rsdp->Signature[1] == 'S') &&
|
|
(Rsdp->Signature[2] == 'D') &&
|
|
(Rsdp->Signature[3] == ' ') &&
|
|
(Rsdp->Signature[4] == 'P') &&
|
|
(Rsdp->Signature[5] == 'T') &&
|
|
(Rsdp->Signature[6] == 'R') &&
|
|
(Rsdp->Signature[7] == ' ') &&
|
|
(BlRtlComputeChecksum8(Rsdp, 20) == 0)
|
|
) {
|
|
|
|
return Rsdp;
|
|
}
|
|
|
|
Start += 0x10;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
PACPI_RSDT
|
|
BlAcpiLocateRsdt(
|
|
PACPI_RSDP Rsdp
|
|
)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function locates the ACPI RSDT structure.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Rsdp - Supplies a pointer to the ACPI RSDP structure.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ACPI RSDT structure, if located.
|
|
// NULL, otherwise.
|
|
//
|
|
//--
|
|
|
|
{
|
|
PACPI_RSDT Rsdt;
|
|
|
|
Rsdt = (PACPI_RSDT) (ULONG_PTR) Rsdp->RsdtAddress;
|
|
|
|
if (Rsdt == NULL) {
|
|
|
|
return NULL;
|
|
}
|
|
|
|
if ((Rsdt->Signature[0] == 'R') &&
|
|
(Rsdt->Signature[1] == 'S') &&
|
|
(Rsdt->Signature[2] == 'D') &&
|
|
(Rsdt->Signature[3] == 'T') &&
|
|
(Rsdt->Length >= sizeof(ACPI_RSDT)) &&
|
|
(BlRtlComputeChecksum8(Rsdt, Rsdt->Length) == 0)) {
|
|
|
|
return Rsdt;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
PACPI_MADT
|
|
BlAcpiLocateMadt(
|
|
PACPI_RSDT Rsdt
|
|
)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function locates the ACPI MADT structure.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Rsdt - Supplies a pointer to the ACPI RSDT structure.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ACPI MADT structure, if located.
|
|
// NULL, otherwise.
|
|
//
|
|
//--
|
|
|
|
{
|
|
UINT32 Index;
|
|
PACPI_MADT Madt;
|
|
UINT32 NumberOfTables;
|
|
|
|
NumberOfTables = (Rsdt->Length - FIELD_OFFSET(ACPI_RSDT, Entry)) / sizeof(Rsdt->Entry[0]);
|
|
|
|
for (Index = 0; Index < NumberOfTables; Index += 1) {
|
|
|
|
Madt = (PACPI_MADT) (ULONG_PTR) Rsdt->Entry[Index];
|
|
|
|
if ((Madt->Signature[0] == 'A') &&
|
|
(Madt->Signature[1] == 'P') &&
|
|
(Madt->Signature[2] == 'I') &&
|
|
(Madt->Signature[3] == 'C') &&
|
|
(Madt->Length >= sizeof(ACPI_MADT)) &&
|
|
(BlRtlComputeChecksum8(Madt, Madt->Length) == 0)) {
|
|
|
|
return Madt;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
PACPI_SRAT
|
|
BlAcpiLocateSrat(
|
|
PACPI_RSDT Rsdt
|
|
)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function locates the ACPI SRAT structure.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Rsdt - Supplies a pointer to the ACPI RSDT structure.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ACPI SRAT structure, if located.
|
|
// NULL, otherwise.
|
|
//
|
|
//--
|
|
|
|
{
|
|
UINT32 Index;
|
|
PACPI_SRAT Srat;
|
|
UINT32 NumberOfTables;
|
|
|
|
NumberOfTables = (Rsdt->Length - FIELD_OFFSET(ACPI_RSDT, Entry)) / sizeof(Rsdt->Entry[0]);
|
|
|
|
for (Index = 0; Index < NumberOfTables; Index += 1) {
|
|
|
|
Srat = (PACPI_SRAT) (ULONG_PTR) Rsdt->Entry[Index];
|
|
|
|
if ((Srat->Signature[0] == 'S') &&
|
|
(Srat->Signature[1] == 'R') &&
|
|
(Srat->Signature[2] == 'A') &&
|
|
(Srat->Signature[3] == 'T') &&
|
|
(Srat->Length >= sizeof(ACPI_SRAT)) &&
|
|
(BlRtlComputeChecksum8(Srat, Srat->Length) == 0)) {
|
|
#if ACPI_VERBOSE
|
|
BlRtlPrintf("ACPI: Found SRAT Table\n");
|
|
#endif
|
|
|
|
return Srat;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
VOID
|
|
BlAcpiDumpSratEntries(
|
|
VOID
|
|
)
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function prints out the SRAT table.
|
|
//--
|
|
{
|
|
PACPI_SRAT_ENTRY Entry;
|
|
PCHAR Limit;
|
|
PACPI_SRAT_PROC_AFFINITY_ENTRY ProcAffinityEntry;
|
|
PACPI_SRAT_MEM_AFFINITY_ENTRY MemAffinityEntry;
|
|
PCHAR Next;
|
|
UINT32 hbits;
|
|
UINT32 totalbits;
|
|
|
|
if (BlAcpiSrat == NULL) {
|
|
BlRtlPrintf("ACPI: No Srat??\n");
|
|
return;
|
|
}
|
|
#if ACPI_VERBOSE
|
|
BlRtlPrintf("SRAT:\n");
|
|
#endif
|
|
|
|
Next = (PCHAR) &BlAcpiSrat->SratStructures[0];
|
|
Limit = ((PCHAR) BlAcpiSrat) + BlAcpiSrat->Length;
|
|
|
|
while (Next < Limit) {
|
|
|
|
Entry = (PACPI_SRAT_ENTRY) Next;
|
|
|
|
if ((Entry->Type == ACPI_SRAT_TYPE_PROC_AFFINITY_ENTRY) &&
|
|
(Entry->Length >= sizeof(ACPI_SRAT_PROC_AFFINITY_ENTRY))) {
|
|
|
|
ProcAffinityEntry = (PACPI_SRAT_PROC_AFFINITY_ENTRY) Next;
|
|
#if ACPI_VERBOSE
|
|
BlRtlPrintf(" Processor:\n");
|
|
#endif
|
|
hbits = 0;
|
|
hbits += ProcAffinityEntry->ProximityDomainHighTwentyFourBits[0] << 24;
|
|
hbits += ProcAffinityEntry->ProximityDomainHighTwentyFourBits[1] << 16;
|
|
hbits += ProcAffinityEntry->ProximityDomainHighTwentyFourBits[2] << 8;
|
|
totalbits = hbits | ProcAffinityEntry->ProximityDomainLowEightBits;
|
|
#if ACPI_VERBOSE
|
|
BlRtlPrintf(" HighDomain 0x%06x LowDomain 0x%02x totalbits 0x%08x\n",
|
|
hbits, ProcAffinityEntry->ProximityDomainLowEightBits,
|
|
totalbits);
|
|
BlRtlPrintf(" ApicID: %d flags 0x%08x\n", ProcAffinityEntry->ApicID,
|
|
ProcAffinityEntry->Flags);
|
|
#endif
|
|
}
|
|
else if ((Entry->Type == ACPI_SRAT_TYPE_MEM_AFFINITY_ENTRY) &&
|
|
(Entry->Length >= sizeof(ACPI_SRAT_MEM_AFFINITY_ENTRY))) {
|
|
|
|
MemAffinityEntry = (PACPI_SRAT_MEM_AFFINITY_ENTRY) Next;
|
|
#if ACPI_VERBOSE
|
|
BlRtlPrintf(" Memory:\n");
|
|
BlRtlPrintf(" BaseAddress 0x%08x.%08x .. 0x%08x.%08x",
|
|
MemAffinityEntry->BaseAddressHigh, MemAffinityEntry->BaseAddressLow,
|
|
MemAffinityEntry->LengthHigh, MemAffinityEntry->LengthLow);
|
|
BlRtlPrintf(" Domain %d Flags 0x%08x\n",
|
|
MemAffinityEntry->ProximityDomain,
|
|
MemAffinityEntry->Flags);
|
|
#endif
|
|
}
|
|
|
|
Next += Entry->Length;
|
|
}
|
|
}
|
|
|
|
UINT32
|
|
BlAcpiGetNumberOfProcessors(
|
|
VOID
|
|
)
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function returns the number of processors.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Number of processors.
|
|
//
|
|
//--
|
|
|
|
{
|
|
PACPI_MADT_ENTRY Entry;
|
|
PCHAR Limit;
|
|
PACPI_PROCESSOR_LOCAL_APIC LocalApic;
|
|
PCHAR Next;
|
|
UINT32 NumberOfProcessors;
|
|
|
|
if (BlAcpiMadt == NULL) {
|
|
|
|
return 1;
|
|
}
|
|
|
|
Next = (PCHAR) &BlAcpiMadt->ApicStructures[0];
|
|
Limit = ((PCHAR) BlAcpiMadt) + BlAcpiMadt->Length;
|
|
NumberOfProcessors = 0;
|
|
|
|
while (Next < Limit) {
|
|
|
|
Entry = (PACPI_MADT_ENTRY) Next;
|
|
|
|
if ((Entry->Type == ACPI_APIC_TYPE_PROCESSOR_LOCAL) &&
|
|
(Entry->Length >= sizeof(ACPI_PROCESSOR_LOCAL_APIC))) {
|
|
|
|
LocalApic = (PACPI_PROCESSOR_LOCAL_APIC) Next;
|
|
|
|
if (LocalApic->u1.s1.Enabled != FALSE) {
|
|
|
|
#if ACPI_VERBOSE
|
|
|
|
BlRtlPrintf("ACPI: AcpiProcessorId=%u , LocalApicId=%u\n",
|
|
LocalApic->AcpiProcessorId,
|
|
LocalApic->ApicId);
|
|
|
|
#endif
|
|
|
|
NumberOfProcessors += 1;
|
|
}
|
|
}
|
|
|
|
Next += Entry->Length;
|
|
}
|
|
|
|
return NumberOfProcessors;
|
|
}
|
|
|
|
PACPI_FADT
|
|
BlAcpiLocateFadt(
|
|
PACPI_RSDT Rsdt
|
|
)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function locates the ACPI FADT structure.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Rsdt - Supplies a pointer to the ACPI RSDT structure.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ACPI FADT structure, if located.
|
|
// NULL, otherwise.
|
|
//
|
|
//--
|
|
|
|
{
|
|
PACPI_FADT Fadt;
|
|
UINT32 Index;
|
|
UINT32 NumberOfTables;
|
|
|
|
NumberOfTables = (Rsdt->Length - FIELD_OFFSET(ACPI_RSDT, Entry)) / sizeof(Rsdt->Entry[0]);
|
|
|
|
for (Index = 0; Index < NumberOfTables; Index += 1) {
|
|
|
|
Fadt = (PACPI_FADT) (ULONG_PTR) Rsdt->Entry[Index];
|
|
|
|
if ((Fadt->Signature[0] == 'F') &&
|
|
(Fadt->Signature[1] == 'A') &&
|
|
(Fadt->Signature[2] == 'C') &&
|
|
(Fadt->Signature[3] == 'P') &&
|
|
(BlRtlComputeChecksum8(Fadt, Fadt->Length) == 0)) {
|
|
|
|
return Fadt;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
VOID
|
|
BlAcpiResetSystem(
|
|
VOID
|
|
)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function resets the system through the ACPI reset register.
|
|
//
|
|
//--
|
|
|
|
{
|
|
if ((BlAcpiFadt->Revision < 2) ||
|
|
(BlAcpiFadt->Length < (FIELD_OFFSET(ACPI_FADT, ResetValue) + sizeof(UINT8))) ||
|
|
((BlAcpiFadt->Flags & ACPI_FADT_FLAGS_RESET_SUPPORTED) == 0)
|
|
) {
|
|
|
|
#if ACPI_VERBOSE
|
|
|
|
BlRtlPrintf("ACPI: Reset register is not supported! [FADT v%u]\n", BlAcpiFadt->Revision);
|
|
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
#if ACPI_VERBOSE
|
|
|
|
BlRtlPrintf("ACPI: Reset register type is %u.\n", BlAcpiFadt->ResetRegister.AddressSpaceId);
|
|
|
|
#endif
|
|
|
|
switch (BlAcpiFadt->ResetRegister.AddressSpaceId) {
|
|
|
|
case ACPI_GAS_IO: {
|
|
|
|
BlRtlWritePort8((UINT16) BlAcpiFadt->ResetRegister.Address, BlAcpiFadt->ResetValue);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
BlAcpiInitialize(
|
|
VOID
|
|
)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function initializes ACPI support for the boot loader.
|
|
//
|
|
//--
|
|
|
|
{
|
|
BlAcpiRsdp = BlAcpiLocateRsdp();
|
|
|
|
if (BlAcpiRsdp == NULL) {
|
|
|
|
BlRtlPrintf("ACPI: No RSDP!\n");
|
|
BlRtlHalt();
|
|
}
|
|
|
|
BlAcpiRsdpAddress = (PVOID) BlAcpiRsdp;
|
|
|
|
BlAcpiRsdt = BlAcpiLocateRsdt(BlAcpiRsdp);
|
|
|
|
if (BlAcpiRsdt == NULL) {
|
|
|
|
BlRtlPrintf("ACPI: No RSDT!\n");
|
|
BlRtlHalt();
|
|
}
|
|
|
|
BlAcpiFadt = BlAcpiLocateFadt(BlAcpiRsdt);
|
|
|
|
if (BlAcpiFadt == NULL) {
|
|
|
|
BlRtlPrintf("ACPI: No FADT!\n");
|
|
BlRtlHalt();
|
|
}
|
|
|
|
BlAcpiMadt = BlAcpiLocateMadt(BlAcpiRsdt);
|
|
|
|
if (BlAcpiMadt == NULL) {
|
|
|
|
BlAcpiNumberOfProcessors = 1;
|
|
|
|
} else {
|
|
|
|
BlAcpiNumberOfProcessors = BlAcpiGetNumberOfProcessors();
|
|
}
|
|
|
|
if (BlAcpiNumberOfProcessors == 0) {
|
|
|
|
BlRtlPrintf("ACPI: No local APIC!\n");
|
|
BlRtlHalt();
|
|
}
|
|
|
|
BlAcpiSrat = BlAcpiLocateSrat(BlAcpiRsdt);
|
|
if (BlAcpiSrat != NULL) {
|
|
BlAcpiDumpSratEntries();
|
|
}
|
|
|
|
|
|
#if ACPI_VERBOSE
|
|
|
|
BlRtlPrintf("ACPI: RSDP @ %p\n"
|
|
"ACPI: RSDT @ %p\n"
|
|
"ACPI: FADT @ %p [Revision=%u , Length=%u]\n"
|
|
"ACPI: MADT @ %p\n"
|
|
"ACPI: %u processor(s)\n",
|
|
BlAcpiRsdp,
|
|
BlAcpiRsdt,
|
|
BlAcpiFadt,
|
|
BlAcpiFadt->Revision,
|
|
BlAcpiFadt->Length,
|
|
BlAcpiMadt,
|
|
BlAcpiNumberOfProcessors);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Map APIC page uncached.
|
|
//
|
|
|
|
if ((BlAcpiMadt != NULL) && (BlAcpiMadt->LocalApicAddress != 0)) {
|
|
|
|
#if ACPI_VERBOSE
|
|
|
|
BlRtlPrintf("ACPI: APIC mapped @ %p.\n", BlAcpiMadt->LocalApicAddress);
|
|
|
|
#endif
|
|
|
|
BlMmMapVirtualRange((PVOID) (ULONG_PTR) BlAcpiMadt->LocalApicAddress,
|
|
(PVOID) (ULONG_PTR) BlAcpiMadt->LocalApicAddress,
|
|
PAGE_SIZE,
|
|
TRUE,
|
|
FALSE,
|
|
FALSE);
|
|
}
|
|
}
|