/** @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; }