/** @file
Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
VOID
DumpCharArray (
IN CHAR8 *Ch,
IN UINTN Size
);
VOID
DumpAcpiTableHeader (
IN EFI_ACPI_DESCRIPTION_HEADER *Table
);
BOOLEAN
IsMmioExit (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN BOOLEAN CheckAllocated
);
typedef struct {
UINT8 Type;
UINT8 Length;
} APIC_STRUCT_HEADER;
CHAR8 *mMadtTypeString[] = {
"APIC ",
"IO_APIC ",
"INT_SRC_OR",
"NNI_SRC ",
"APIC_NMI ",
"APIC_OR ",
"IO_SAPIC ",
"SAPIC ",
"PL_INT_SRC",
"X2APIC ",
"X2APIC_NMI",
};
STATIC CHAR8 mUnknownStr[11];
CHAR8 *
ShortNameOfMadtType(
IN UINT8 Type
)
{
if (Type < sizeof(mMadtTypeString) / sizeof(mMadtTypeString[0])) {
return mMadtTypeString[Type];
} else {
AsciiSPrint(mUnknownStr, sizeof(mUnknownStr), "[%02x] ", Type);
return mUnknownStr;
}
}
VOID
DumpAcpiMadt (
IN EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt
)
{
APIC_STRUCT_HEADER *ApicStructHeader;
INTN MadtLen;
EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *ProcessorLocalApic;
EFI_ACPI_4_0_IO_APIC_STRUCTURE *IOApic;
EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *InterruptSourceOverride;
EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE *NonMaskableInterruptSource;
EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE *LocalApicNMI;
EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE *LocalApicAddressOverride;
EFI_ACPI_4_0_IO_SAPIC_STRUCTURE *IOSapic;
EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE *ProcessorLocalSapic;
EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE *PlatformInterruptSource;
EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *ProcessorLocalX2Apic;
EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE *LocalX2ApicNmi;
DumpAcpiTableHeader (&Madt->Header);
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " LocalApicAddress=0x%08x\n", Madt->LocalApicAddress));
//
// Sub table
//
MadtLen = Madt->Header.Length - sizeof(EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
ApicStructHeader = (APIC_STRUCT_HEADER *)(Madt + 1);
while (MadtLen > 0) {
switch (ApicStructHeader->Type) {
case EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC:
ProcessorLocalApic = (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " ID=0x%02x", ProcessorLocalApic->AcpiProcessorId));
DEBUG ((DEBUG_INFO, " ApicId=0x%02x", ProcessorLocalApic->ApicId));
if ((ProcessorLocalApic->Flags & EFI_ACPI_4_0_LOCAL_APIC_ENABLED) != 0) {
DEBUG ((DEBUG_INFO, " (Enabled)"));
}
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_IO_APIC:
IOApic = (EFI_ACPI_4_0_IO_APIC_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " IoApicId=0x%02x", IOApic->IoApicId));
DEBUG ((DEBUG_INFO, " Address=0x%08x", IOApic->IoApicAddress));
DEBUG ((DEBUG_INFO, " InterruptBase=0x%08x", IOApic->GlobalSystemInterruptBase));
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE:
InterruptSourceOverride = (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " Bus=0x%02x", InterruptSourceOverride->Bus));
DEBUG ((DEBUG_INFO, " Source=0x%02x", InterruptSourceOverride->Source));
DEBUG ((DEBUG_INFO, " Interrupt=0x%08x", InterruptSourceOverride->GlobalSystemInterrupt));
DEBUG ((DEBUG_INFO, " Flags=0x%04x", InterruptSourceOverride->Flags));
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE:
NonMaskableInterruptSource = (EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " Interrupt=0x%08x", NonMaskableInterruptSource->GlobalSystemInterrupt));
DEBUG ((DEBUG_INFO, " Flags=0x%04x", NonMaskableInterruptSource->Flags));
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_LOCAL_APIC_NMI:
LocalApicNMI = (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " ID=0x%02x", LocalApicNMI->AcpiProcessorId));
DEBUG ((DEBUG_INFO, " Lint=0x%02x", LocalApicNMI->LocalApicLint));
DEBUG ((DEBUG_INFO, " Flags=0x%04x", LocalApicNMI->Flags));
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE:
LocalApicAddressOverride = (EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " LocalApicAddress=0x%016lx", LocalApicAddressOverride->LocalApicAddress));
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_IO_SAPIC:
IOSapic = (EFI_ACPI_4_0_IO_SAPIC_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " IoApicId=0x%02x", IOSapic->IoApicId));
DEBUG ((DEBUG_INFO, " InterruptBase=0x%08x", IOSapic->GlobalSystemInterruptBase));
DEBUG ((DEBUG_INFO, " IoSapicAddress=0x%016lx", IOSapic->IoSapicAddress));
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_LOCAL_SAPIC:
ProcessorLocalSapic = (EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " ID=0x%02x", ProcessorLocalSapic->AcpiProcessorId));
DEBUG ((DEBUG_INFO, " LocalSapicId=0x%02x", ProcessorLocalSapic->LocalSapicId));
DEBUG ((DEBUG_INFO, " LocalSapicEid=0x%02x", ProcessorLocalSapic->LocalSapicEid));
DEBUG ((DEBUG_INFO, " UID=0x%08x", ProcessorLocalSapic->ACPIProcessorUIDValue));
if ((ProcessorLocalSapic->Flags & EFI_ACPI_5_0_LOCAL_APIC_ENABLED) != 0) {
DEBUG ((DEBUG_INFO, " (Enabled)"));
}
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES:
PlatformInterruptSource = (EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " Type=0x%02x", PlatformInterruptSource->InterruptType));
DEBUG ((DEBUG_INFO, " ID=0x%02x", PlatformInterruptSource->ProcessorId));
DEBUG ((DEBUG_INFO, " EID=0x%02x", PlatformInterruptSource->ProcessorEid));
DEBUG ((DEBUG_INFO, " IoSapicVector=0x%02x", PlatformInterruptSource->IoSapicVector));
DEBUG ((DEBUG_INFO, " Interrupt=0x%08x", PlatformInterruptSource->GlobalSystemInterrupt));
DEBUG ((DEBUG_INFO, " SourceFlags=0x%08x", PlatformInterruptSource->PlatformInterruptSourceFlags));
DEBUG ((DEBUG_INFO, " Flags=0x%04x", PlatformInterruptSource->Flags));
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC:
ProcessorLocalX2Apic = (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " X2ApicId=0x%08x", ProcessorLocalX2Apic->X2ApicId));
DEBUG ((DEBUG_INFO, " UID=0x%08x", ProcessorLocalX2Apic->AcpiProcessorUid));
if ((ProcessorLocalX2Apic->Flags & EFI_ACPI_5_0_LOCAL_APIC_ENABLED) != 0) {
DEBUG ((DEBUG_INFO, " (Enabled)"));
}
DEBUG ((DEBUG_INFO, "\n"));
break;
case EFI_ACPI_4_0_LOCAL_X2APIC_NMI:
LocalX2ApicNmi = (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE *)ApicStructHeader;
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, ": [0x%02x]", ApicStructHeader->Type));
DEBUG ((DEBUG_INFO, " UID=0x%08x", LocalX2ApicNmi->AcpiProcessorUid));
DEBUG ((DEBUG_INFO, " Lint=0x%02x", LocalX2ApicNmi->LocalX2ApicLint));
DEBUG ((DEBUG_INFO, " Flags=0x%04x", LocalX2ApicNmi->Flags));
DEBUG ((DEBUG_INFO, "\n"));
break;
default:
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, " "));
DEBUG ((DEBUG_INFO, ShortNameOfMadtType(ApicStructHeader->Type)));
DEBUG ((DEBUG_INFO, "\n"));
break;
}
ApicStructHeader = (APIC_STRUCT_HEADER *)((UINT8 *)ApicStructHeader + ApicStructHeader->Length);
MadtLen -= ApicStructHeader->Length;
}
}
EFI_STATUS
CheckAcpiMadt (
IN EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt
)
{
APIC_STRUCT_HEADER *ApicStructHeader;
INTN MadtLen;
EFI_ACPI_4_0_IO_APIC_STRUCTURE *IOApic;
EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE *LocalApicAddressOverride;
EFI_ACPI_4_0_IO_SAPIC_STRUCTURE *IOSapic;
#if 0
EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *ProcessorLocalApic;
EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *InterruptSourceOverride;
EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE *NonMaskableInterruptSource;
EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE *LocalApicNMI;
EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE *ProcessorLocalSapic;
EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE *PlatformInterruptSource;
EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *ProcessorLocalX2Apic;
EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE *LocalX2ApicNmi;
#endif
if (!IsMmioExit (Madt->LocalApicAddress, SIZE_4KB, TRUE)) {
DEBUG ((DEBUG_ERROR, "MADT resource (0x%x) is not reported correctly.\n", Madt->LocalApicAddress));
return EFI_NOT_STARTED;
}
//
// Sub table
//
MadtLen = Madt->Header.Length - sizeof(EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
ApicStructHeader = (APIC_STRUCT_HEADER *)(Madt + 1);
while (MadtLen > 0) {
switch (ApicStructHeader->Type) {
case EFI_ACPI_4_0_IO_APIC:
IOApic = (EFI_ACPI_4_0_IO_APIC_STRUCTURE *)ApicStructHeader;
if (!IsMmioExit (IOApic->IoApicAddress, SIZE_4KB, TRUE)) {
DEBUG ((DEBUG_ERROR, "MADT.IOAPIC resource (0x%x) is not reported correctly.\n", IOApic->IoApicAddress));
return EFI_NOT_STARTED;
}
break;
case EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE:
LocalApicAddressOverride = (EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE *)ApicStructHeader;
if (!IsMmioExit (LocalApicAddressOverride->LocalApicAddress, SIZE_4KB, TRUE)) {
DEBUG ((DEBUG_ERROR, "MADT.LocalApicOverride resource (0x%x) is not reported correctly.\n", LocalApicAddressOverride->LocalApicAddress));
return EFI_NOT_STARTED;
}
break;
case EFI_ACPI_4_0_IO_SAPIC:
IOSapic = (EFI_ACPI_4_0_IO_SAPIC_STRUCTURE *)ApicStructHeader;
if (!IsMmioExit (IOSapic->IoSapicAddress, SIZE_4KB, TRUE)) {
DEBUG ((DEBUG_ERROR, "MADT.IOSAPIC resource (0x%x) is not reported correctly.\n", IOSapic->IoSapicAddress));
return EFI_NOT_STARTED;
}
break;
#if 0
case EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC:
ProcessorLocalApic = (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *)ApicStructHeader;
break;
case EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE:
InterruptSourceOverride = (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *)ApicStructHeader;
break;
case EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE:
NonMaskableInterruptSource = (EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE *)ApicStructHeader;
break;
case EFI_ACPI_4_0_LOCAL_APIC_NMI:
LocalApicNMI = (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE *)ApicStructHeader;
break;
case EFI_ACPI_4_0_LOCAL_SAPIC:
ProcessorLocalSapic = (EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE *)ApicStructHeader;
break;
case EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES:
PlatformInterruptSource = (EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE *)ApicStructHeader;
break;
case EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC:
ProcessorLocalX2Apic = (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)ApicStructHeader;
break;
case EFI_ACPI_4_0_LOCAL_X2APIC_NMI:
LocalX2ApicNmi = (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE *)ApicStructHeader;
break;
#endif
default:
break;
}
ApicStructHeader = (APIC_STRUCT_HEADER *)((UINT8 *)ApicStructHeader + ApicStructHeader->Length);
MadtLen -= ApicStructHeader->Length;
}
return EFI_SUCCESS;
}