/** @file
|
|
Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#include <Uefi.h>
|
#include <PiDxe.h>
|
#include <Library/TestPointCheckLib.h>
|
#include <Library/TestPointLib.h>
|
#include <Library/DebugLib.h>
|
#include <Library/UefiLib.h>
|
#include <Library/BaseMemoryLib.h>
|
#include <IndustryStandard/Acpi.h>
|
#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
|
#include <IndustryStandard/HighPrecisionEventTimerTable.h>
|
#include <IndustryStandard/DmaRemappingReportingTable.h>
|
#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
|
#include <IndustryStandard/TcpaAcpi.h>
|
#include <IndustryStandard/Tpm2Acpi.h>
|
#include <Guid/Acpi.h>
|
|
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mAcpiGcdMemoryMap;
|
EFI_GCD_IO_SPACE_DESCRIPTOR *mAcpiGcdIoMap;
|
UINTN mAcpiGcdMemoryMapNumberOfDescriptors;
|
UINTN mAcpiGcdIoMapNumberOfDescriptors;
|
|
VOID
|
DumpAcpiMadt (
|
IN EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt
|
);
|
|
VOID
|
DumpAcpiMcfg (
|
IN EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *Mcfg
|
);
|
|
VOID
|
DumpAcpiHpet (
|
IN EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *Hpet
|
);
|
|
VOID
|
DumpAcpiDmar (
|
IN EFI_ACPI_DMAR_HEADER *Dmar
|
);
|
|
VOID
|
DumpAcpiWsmt (
|
IN EFI_ACPI_WSMT_TABLE *Wsmt
|
);
|
|
VOID
|
DumpAcpiTpm2 (
|
IN EFI_TPM2_ACPI_TABLE *Tpm2
|
);
|
|
VOID
|
DumpAcpiTcpa (
|
IN EFI_ACPI_DESCRIPTION_HEADER *Tcpa
|
);
|
|
EFI_STATUS
|
CheckAcpiMadt (
|
IN EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt
|
);
|
|
EFI_STATUS
|
CheckAcpiMcfg (
|
IN EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *Mcfg
|
);
|
|
EFI_STATUS
|
CheckAcpiHpet (
|
IN EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *Hpet
|
);
|
|
EFI_STATUS
|
CheckAcpiDmar (
|
IN EFI_ACPI_DMAR_HEADER *Dmar
|
);
|
|
EFI_STATUS
|
CheckAcpiTpm2 (
|
IN EFI_TPM2_ACPI_TABLE *Tpm2
|
);
|
|
EFI_STATUS
|
CheckAcpiTcpa (
|
IN EFI_ACPI_DESCRIPTION_HEADER *Tcpa
|
);
|
|
VOID
|
TestPointDumpGcd (
|
OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **GcdMemoryMap, OPTIONAL
|
OUT UINTN *GcdMemoryMapNumberOfDescriptors, OPTIONAL
|
OUT EFI_GCD_IO_SPACE_DESCRIPTOR **GcdIoMap, OPTIONAL
|
OUT UINTN *GcdIoMapNumberOfDescriptors, OPTIONAL
|
IN BOOLEAN DumpPrint
|
);
|
|
BOOLEAN
|
IsMmioExit (
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
IN UINT64 Length,
|
IN BOOLEAN CheckAllocated
|
)
|
{
|
UINTN Index;
|
for (Index = 0; Index < mAcpiGcdMemoryMapNumberOfDescriptors; Index++) {
|
if (mAcpiGcdMemoryMap[Index].GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
|
continue;
|
}
|
if ((BaseAddress >= mAcpiGcdMemoryMap[Index].BaseAddress) &&
|
(BaseAddress + Length <= mAcpiGcdMemoryMap[Index].BaseAddress + mAcpiGcdMemoryMap[Index].Length)) {
|
if (CheckAllocated) {
|
if (mAcpiGcdMemoryMap[Index].ImageHandle != NULL) {
|
return TRUE;
|
} else {
|
return FALSE;
|
}
|
} else {
|
return TRUE;
|
}
|
}
|
}
|
return FALSE;
|
}
|
|
BOOLEAN
|
IsIoExit (
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
IN UINT64 Length,
|
IN BOOLEAN CheckAllocated
|
)
|
{
|
UINTN Index;
|
for (Index = 0; Index < mAcpiGcdIoMapNumberOfDescriptors; Index++) {
|
if (mAcpiGcdIoMap[Index].GcdIoType != EfiGcdIoTypeIo) {
|
continue;
|
}
|
if ((BaseAddress >= mAcpiGcdIoMap[Index].BaseAddress) &&
|
(BaseAddress + Length <= mAcpiGcdIoMap[Index].BaseAddress + mAcpiGcdIoMap[Index].Length)) {
|
if (CheckAllocated) {
|
if (mAcpiGcdIoMap[Index].ImageHandle != NULL) {
|
return TRUE;
|
} else {
|
return FALSE;
|
}
|
} else {
|
return TRUE;
|
}
|
}
|
}
|
return FALSE;
|
}
|
|
VOID
|
DumpCharArray (
|
IN CHAR8 *Ch,
|
IN UINTN Size
|
)
|
{
|
UINTN Index;
|
|
for (Index = 0; Index < Size; Index++) {
|
DEBUG ((DEBUG_INFO, "%c", Ch[Index]));
|
}
|
}
|
|
VOID
|
DumpAcpiTableHeader (
|
IN EFI_ACPI_DESCRIPTION_HEADER *Table
|
)
|
{
|
DEBUG ((DEBUG_INFO, " "));
|
DumpCharArray ((CHAR8 *)&Table->Signature, sizeof(Table->Signature));
|
DEBUG ((DEBUG_INFO, " : (0x%016lx) 0x%02x \'", Table, Table->Revision));
|
DumpCharArray ((CHAR8 *)Table->OemId, sizeof(Table->OemId));
|
DEBUG ((DEBUG_INFO, "\' \'"));
|
DumpCharArray ((CHAR8 *)&Table->OemTableId, sizeof(Table->OemTableId));
|
DEBUG ((DEBUG_INFO, "\' 0x%08x \'", Table->OemRevision));
|
DumpCharArray ((CHAR8 *)&Table->CreatorId, sizeof(Table->CreatorId));
|
DEBUG ((DEBUG_INFO, "\' 0x%08x |\n", Table->CreatorRevision));
|
}
|
|
VOID
|
DumpAcpiFadt (
|
IN EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt
|
)
|
{
|
DumpAcpiTableHeader (&Fadt->Header);
|
DEBUG ((DEBUG_INFO, " "));
|
DEBUG ((DEBUG_INFO, " SCI=0x%04x", Fadt->SciInt));
|
DEBUG ((DEBUG_INFO, " SMI=0x%08x", Fadt->SmiCmd));
|
DEBUG ((DEBUG_INFO, " AcpiEnable=0x%02x", Fadt->AcpiEnable));
|
DEBUG ((DEBUG_INFO, " AcpiDisable=0x%02x", Fadt->AcpiDisable));
|
DEBUG ((DEBUG_INFO, "\n"));
|
}
|
|
EFI_STATUS
|
CheckAcpiFadt (
|
IN EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt
|
)
|
{
|
if (Fadt->SmiCmd != 0) {
|
if (!IsIoExit (Fadt->SmiCmd, 1, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.SmiCmd resource (0x%x) is not reported correctly.\n", Fadt->SmiCmd));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->Pm1aEvtBlk != 0) {
|
if (!IsIoExit (Fadt->Pm1aEvtBlk, Fadt->Pm1EvtLen, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.Pm1aEvtBlk resource (0x%x) is not reported correctly.\n", Fadt->Pm1aEvtBlk));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->Pm1bEvtBlk != 0) {
|
if (!IsIoExit (Fadt->Pm1bEvtBlk, Fadt->Pm1EvtLen, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.Pm1bEvtBlk resource (0x%x) is not reported correctly.\n", Fadt->Pm1bEvtBlk));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->Pm1aCntBlk != 0) {
|
if (!IsIoExit (Fadt->Pm1aCntBlk, Fadt->Pm1CntLen, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.Pm1aCntBlk resource (0x%x) is not reported correctly.\n", Fadt->Pm1aCntBlk));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->Pm1bCntBlk != 0) {
|
if (!IsIoExit (Fadt->Pm1bCntBlk, Fadt->Pm1CntLen, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.Pm1bCntBlk resource (0x%x) is not reported correctly.\n", Fadt->Pm1bCntBlk));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->Pm2CntBlk != 0) {
|
if (!IsIoExit (Fadt->Pm2CntBlk, Fadt->Pm2CntLen, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.Pm2CntBlk resource (0x%x) is not reported correctly.\n", Fadt->Pm2CntBlk));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->PmTmrBlk != 0) {
|
if (!IsIoExit (Fadt->PmTmrBlk, Fadt->PmTmrLen, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.PmTmrBlk resource (0x%x) is not reported correctly.\n", Fadt->PmTmrBlk));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->Gpe0Blk != 0) {
|
if (!IsIoExit (Fadt->Gpe0Blk, Fadt->Gpe0BlkLen, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.Gpe0Blk resource (0x%x) is not reported correctly.\n", Fadt->Gpe0Blk));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->Gpe1Blk != 0) {
|
if (!IsIoExit (Fadt->Gpe1Blk, Fadt->Gpe1BlkLen, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.Gpe1Blk resource (0x%x) is not reported correctly.\n", Fadt->Gpe1Blk));
|
return EFI_NOT_STARTED;
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, ResetReg)) {
|
if (Fadt->ResetReg.Address != 0) {
|
switch (Fadt->ResetReg.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->ResetReg.Address, Fadt->ResetReg.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.ResetReg resource (0x%x) is not reported correctly.\n", Fadt->ResetReg.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->ResetReg.Address, Fadt->ResetReg.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.ResetReg resource (0x%x) is not reported correctly.\n", Fadt->ResetReg.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, XPm1aEvtBlk)) {
|
if (Fadt->XPm1aEvtBlk.Address != 0) {
|
switch (Fadt->XPm1aEvtBlk.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->XPm1aEvtBlk.Address, Fadt->XPm1aEvtBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm1aEvtBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm1aEvtBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->XPm1aEvtBlk.Address, Fadt->XPm1aEvtBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm1aEvtBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm1aEvtBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, XPm1bEvtBlk)) {
|
if (Fadt->XPm1bEvtBlk.Address != 0) {
|
switch (Fadt->XPm1bEvtBlk.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->XPm1bEvtBlk.Address, Fadt->XPm1bEvtBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm1bEvtBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm1bEvtBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->XPm1bEvtBlk.Address, Fadt->XPm1bEvtBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm1bEvtBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm1bEvtBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, XPm1aCntBlk)) {
|
if (Fadt->XPm1aCntBlk.Address != 0) {
|
switch (Fadt->XPm1aCntBlk.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->XPm1aCntBlk.Address, Fadt->XPm1aCntBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm1aCntBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm1aCntBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->XPm1aCntBlk.Address, Fadt->XPm1aCntBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm1aCntBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm1aCntBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, XPm1bCntBlk)) {
|
if (Fadt->XPm1bCntBlk.Address != 0) {
|
switch (Fadt->XPm1bCntBlk.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->XPm1bCntBlk.Address, Fadt->XPm1bCntBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm1bCntBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm1bCntBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->XPm1bCntBlk.Address, Fadt->XPm1bCntBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm1bCntBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm1bCntBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, XPm2CntBlk)) {
|
if (Fadt->XPm2CntBlk.Address != 0) {
|
switch (Fadt->XPm2CntBlk.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->XPm2CntBlk.Address, Fadt->XPm2CntBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm2CntBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm2CntBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->XPm2CntBlk.Address, Fadt->XPm2CntBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPm2CntBlk resource (0x%x) is not reported correctly.\n", Fadt->XPm2CntBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, XPmTmrBlk)) {
|
if (Fadt->XPmTmrBlk.Address != 0) {
|
switch (Fadt->XPmTmrBlk.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->XPmTmrBlk.Address, Fadt->XPmTmrBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPmTmrBlk resource (0x%x) is not reported correctly.\n", Fadt->XPmTmrBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->XPmTmrBlk.Address, Fadt->XPmTmrBlk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XPmTmrBlk resource (0x%x) is not reported correctly.\n", Fadt->XPmTmrBlk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, XGpe0Blk)) {
|
if (Fadt->XGpe0Blk.Address != 0) {
|
switch (Fadt->XGpe0Blk.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->XGpe0Blk.Address, Fadt->XGpe0Blk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XGpe0Blk resource (0x%x) is not reported correctly.\n", Fadt->XGpe0Blk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->XGpe0Blk.Address, Fadt->XGpe0Blk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XGpe0Blk resource (0x%x) is not reported correctly.\n", Fadt->XGpe0Blk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, XGpe1Blk)) {
|
if (Fadt->XGpe1Blk.Address != 0) {
|
switch (Fadt->XGpe1Blk.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->XGpe1Blk.Address, Fadt->XGpe1Blk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XGpe1Blk resource (0x%x) is not reported correctly.\n", Fadt->XGpe1Blk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->XGpe1Blk.Address, Fadt->XGpe1Blk.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.XGpe1Blk resource (0x%x) is not reported correctly.\n", Fadt->XGpe1Blk.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, SleepControlReg)) {
|
if (Fadt->SleepControlReg.Address != 0) {
|
switch (Fadt->SleepControlReg.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->SleepControlReg.Address, Fadt->SleepControlReg.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.SleepControlReg resource (0x%x) is not reported correctly.\n", Fadt->SleepControlReg.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->SleepControlReg.Address, Fadt->SleepControlReg.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.SleepControlReg resource (0x%x) is not reported correctly.\n", Fadt->SleepControlReg.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
if (Fadt->Header.Length > OFFSET_OF(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE, SleepStatusReg)) {
|
if (Fadt->SleepStatusReg.Address != 0) {
|
switch (Fadt->SleepStatusReg.AddressSpaceId) {
|
case EFI_ACPI_5_0_SYSTEM_MEMORY:
|
if (!IsMmioExit (Fadt->SleepStatusReg.Address, Fadt->SleepStatusReg.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.SleepStatusReg resource (0x%x) is not reported correctly.\n", Fadt->SleepStatusReg.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
case EFI_ACPI_5_0_SYSTEM_IO:
|
if (!IsIoExit (Fadt->SleepStatusReg.Address, Fadt->SleepStatusReg.RegisterBitWidth/8, TRUE)) {
|
DEBUG ((DEBUG_ERROR, "FADT.SleepStatusReg resource (0x%x) is not reported correctly.\n", Fadt->SleepStatusReg.Address));
|
return EFI_NOT_STARTED;
|
}
|
break;
|
}
|
}
|
}
|
return EFI_SUCCESS;
|
}
|
|
VOID
|
DumpAcpiFacs (
|
IN EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs
|
)
|
{
|
DEBUG ((DEBUG_INFO, " "));
|
DumpCharArray ((CHAR8 *)&Facs->Signature, sizeof(Facs->Signature));
|
DEBUG ((DEBUG_INFO, " : (0x%016lx) 0x%02x\n", Facs, Facs->Version));
|
DEBUG ((DEBUG_INFO, " "));
|
DEBUG ((DEBUG_INFO, " HardwareSignature=%08x\n", Facs->HardwareSignature));
|
}
|
|
VOID
|
DumpAcpiTable (
|
IN EFI_ACPI_DESCRIPTION_HEADER *Table
|
)
|
{
|
EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
|
|
if (Table == NULL) {
|
return ;
|
}
|
|
switch (Table->Signature) {
|
case EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
|
Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Table;
|
DumpAcpiFadt (Fadt);
|
if (Fadt->Header.Revision >= EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
|
if (Fadt->XFirmwareCtrl != 0) {
|
DumpAcpiFacs ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->XFirmwareCtrl);
|
} else {
|
DumpAcpiFacs ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl);
|
}
|
if (Fadt->XDsdt != 0) {
|
DumpAcpiTable ((EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt->XDsdt);
|
} else {
|
DumpAcpiTable ((EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt->Dsdt);
|
}
|
} else {
|
DumpAcpiFacs ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl);
|
DumpAcpiTable ((EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt->Dsdt);
|
}
|
break;
|
case EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
|
DumpAcpiMadt ((EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table);
|
break;
|
case EFI_ACPI_2_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_SIGNATURE:
|
DumpAcpiMcfg ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *)Table);
|
break;
|
case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
|
DumpAcpiHpet ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *)Table);
|
break;
|
case EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE:
|
DumpAcpiDmar ((EFI_ACPI_DMAR_HEADER *)Table);
|
break;
|
case EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE:
|
DumpAcpiWsmt ((EFI_ACPI_WSMT_TABLE *)Table);
|
break;
|
case EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE:
|
DumpAcpiTpm2 ((EFI_TPM2_ACPI_TABLE *)Table);
|
break;
|
case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE:
|
DumpAcpiTcpa ((VOID *)Table);
|
break;
|
default:
|
DumpAcpiTableHeader (Table);
|
break;
|
}
|
}
|
|
EFI_STATUS
|
CheckAcpiTableResource (
|
IN EFI_ACPI_DESCRIPTION_HEADER *Table
|
)
|
{
|
EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
|
|
if (Table == NULL) {
|
return EFI_INVALID_PARAMETER;
|
}
|
|
switch (Table->Signature) {
|
case EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
|
Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Table;
|
CheckAcpiFadt (Fadt);
|
if (Fadt->Header.Revision >= EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
|
if (Fadt->XFirmwareCtrl != 0) {
|
// CheckAcpiFacs ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->XFirmwareCtrl);
|
} else {
|
// CheckAcpiFacs ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl);
|
}
|
if (Fadt->XDsdt != 0) {
|
// CheckAcpiDsdt ((EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt->XDsdt);
|
} else {
|
// CheckAcpiDsdt ((EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt->Dsdt);
|
}
|
} else {
|
// CheckAcpiFacs ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl);
|
// CheckAcpiDsdt ((EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt->Dsdt);
|
}
|
break;
|
case EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
|
return CheckAcpiMadt ((EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table);
|
break;
|
case EFI_ACPI_2_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_SIGNATURE:
|
return CheckAcpiMcfg ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *)Table);
|
break;
|
case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
|
return CheckAcpiHpet ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *)Table);
|
break;
|
case EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE:
|
return CheckAcpiDmar ((EFI_ACPI_DMAR_HEADER *)Table);
|
break;
|
case EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE:
|
// CheckAcpiWsmt ((EFI_ACPI_WSMT_TABLE *)Table);
|
break;
|
case EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE:
|
return CheckAcpiTpm2 ((EFI_TPM2_ACPI_TABLE *)Table);
|
break;
|
case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE:
|
return CheckAcpiTcpa ((VOID *)Table);
|
break;
|
default:
|
break;
|
}
|
|
return EFI_SUCCESS;
|
}
|
|
EFI_STATUS
|
DumpAcpiRsdt (
|
IN EFI_ACPI_DESCRIPTION_HEADER *Rsdt,
|
IN UINT32 *Signature, OPTIONAL
|
OUT VOID **OutTable, OPTIONAL
|
IN BOOLEAN DumpPrint,
|
IN BOOLEAN CheckResource
|
)
|
{
|
UINTN Index;
|
UINT32 EntryCount;
|
UINT32 *EntryPtr;
|
EFI_ACPI_DESCRIPTION_HEADER *Table;
|
EFI_STATUS Status;
|
EFI_STATUS ReturnStatus;
|
|
if (Rsdt == NULL) {
|
return EFI_INVALID_PARAMETER;
|
}
|
|
if (OutTable != NULL) {
|
*OutTable = NULL;
|
} else if ((OutTable == NULL) && (Signature != NULL)) {
|
return EFI_INVALID_PARAMETER;
|
}
|
|
ReturnStatus = EFI_SUCCESS;
|
EntryCount = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);
|
EntryPtr = (UINT32 *)(Rsdt + 1);
|
for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {
|
Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(*EntryPtr));
|
if (DumpPrint) {
|
DumpAcpiTable (Table);
|
}
|
if (CheckResource) {
|
Status = CheckAcpiTableResource (Table);
|
if (EFI_ERROR(Status)) {
|
ReturnStatus = Status;
|
}
|
}
|
if (Signature != NULL && Table->Signature == *Signature) {
|
*OutTable = Table;
|
}
|
}
|
|
if (OutTable != NULL) {
|
if (*OutTable == NULL) {
|
return EFI_NOT_FOUND;
|
}
|
}
|
|
return ReturnStatus;
|
}
|
|
EFI_STATUS
|
DumpAcpiXsdt (
|
IN EFI_ACPI_DESCRIPTION_HEADER *Xsdt,
|
IN UINT32 *Signature, OPTIONAL
|
OUT VOID **OutTable, OPTIONAL
|
IN BOOLEAN DumpPrint,
|
IN BOOLEAN CheckResource
|
)
|
{
|
UINTN Index;
|
UINT32 EntryCount;
|
UINT64 EntryPtr;
|
UINTN BasePtr;
|
EFI_ACPI_DESCRIPTION_HEADER *Table;
|
EFI_STATUS Status;
|
EFI_STATUS ReturnStatus;
|
|
if (Xsdt == NULL) {
|
return EFI_INVALID_PARAMETER;
|
}
|
|
if (OutTable != NULL) {
|
*OutTable = NULL;
|
} else if ((OutTable == NULL) && (Signature != NULL)) {
|
return EFI_INVALID_PARAMETER;
|
}
|
|
ReturnStatus = EFI_SUCCESS;
|
EntryCount = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);
|
|
BasePtr = (UINTN)(Xsdt + 1);
|
for (Index = 0; Index < EntryCount; Index ++) {
|
CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));
|
Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(EntryPtr));
|
if (DumpPrint) {
|
DumpAcpiTable (Table);
|
}
|
if (CheckResource) {
|
Status = CheckAcpiTableResource (Table);
|
if (EFI_ERROR(Status)) {
|
ReturnStatus = Status;
|
}
|
}
|
if (Signature != NULL && Table->Signature == *Signature) {
|
*OutTable = Table;
|
}
|
}
|
|
if (OutTable != NULL) {
|
if (*OutTable == NULL) {
|
return EFI_NOT_FOUND;
|
}
|
}
|
|
return ReturnStatus;
|
}
|
|
EFI_STATUS
|
DumpAcpiRsdp (
|
IN EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp,
|
IN UINT32 *Signature, OPTIONAL
|
OUT VOID **Table,
|
IN BOOLEAN DumpPrint,
|
IN BOOLEAN CheckResource
|
)
|
{
|
EFI_STATUS Status;
|
EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
|
EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
|
|
if (DumpPrint) {
|
DumpCharArray ((CHAR8 *)&Rsdp->Signature, sizeof(Rsdp->Signature));
|
DEBUG ((DEBUG_INFO, ": (0x%016lx) 0x%02x \'", Rsdp, Rsdp->Revision));
|
DumpCharArray ((CHAR8 *)Rsdp->OemId, sizeof(Rsdp->OemId));
|
DEBUG ((DEBUG_INFO, "\'\n"));
|
DEBUG ((DEBUG_INFO, " "));
|
DEBUG ((DEBUG_INFO, " RSDT=0x%08x XSDT=0x%016lx\n", Rsdp->RsdtAddress, Rsdp->XsdtAddress));
|
|
if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
|
DumpAcpiTable ((EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress);
|
}
|
DumpAcpiTable ((EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress);
|
}
|
|
//
|
// Search XSDT
|
//
|
if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
|
Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->XsdtAddress;
|
Status = DumpAcpiXsdt (Xsdt, Signature, Table, DumpPrint, CheckResource);
|
} else {
|
//
|
// Search RSDT
|
//
|
Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;
|
Status = DumpAcpiRsdt (Rsdt, Signature, Table, DumpPrint, CheckResource);
|
}
|
|
return Status;
|
}
|
|
EFI_STATUS
|
DumpAcpiWithGuid (
|
IN EFI_GUID *AcpiTableGuid,
|
IN UINT32 *Signature, OPTIONAL
|
OUT VOID **Table,
|
IN BOOLEAN DumpPrint,
|
IN BOOLEAN CheckResource
|
)
|
{
|
VOID *Rsdp;
|
EFI_STATUS Status;
|
|
Status = EfiGetSystemConfigurationTable (AcpiTableGuid, &Rsdp);
|
if (EFI_ERROR(Status)) {
|
return EFI_NOT_FOUND;
|
}
|
|
Status = DumpAcpiRsdp (Rsdp, Signature, Table, DumpPrint, CheckResource);
|
|
return Status;
|
}
|
|
EFI_STATUS
|
TestPointCheckAcpi (
|
VOID
|
)
|
{
|
EFI_STATUS Status;
|
|
DEBUG ((DEBUG_INFO, "==== TestPointCheckAcpi - Enter\n"));
|
|
DEBUG ((DEBUG_INFO, "AcpiTable :\n"));
|
DEBUG ((DEBUG_INFO, " Table Address Rev OemId OemTableId OemRev Creat CreatorRev\n"));
|
//
|
// First dump
|
//
|
Status = DumpAcpiWithGuid (&gEfiAcpi20TableGuid, NULL, NULL, TRUE, FALSE);
|
if (Status == EFI_NOT_FOUND) {
|
Status = DumpAcpiWithGuid (&gEfiAcpi10TableGuid, NULL, NULL, TRUE, FALSE);
|
}
|
|
if (EFI_ERROR(Status)) {
|
DEBUG ((DEBUG_ERROR, "No ACPI table\n"));
|
TestPointLibAppendErrorString (
|
PLATFORM_TEST_POINT_ROLE_PLATFORM_IBV,
|
NULL,
|
TEST_POINT_BYTE4_READY_TO_BOOT_ACPI_TABLE_FUNCTIONAL_ERROR_CODE \
|
TEST_POINT_READY_TO_BOOT \
|
TEST_POINT_BYTE4_READY_TO_BOOT_ACPI_TABLE_FUNCTIONAL_ERROR_STRING
|
);
|
}
|
|
DEBUG ((DEBUG_INFO, "==== TestPointCheckAcpi - Exit\n"));
|
|
return Status;
|
}
|
|
EFI_STATUS
|
TestPointCheckAcpiGcdResource (
|
VOID
|
)
|
{
|
EFI_STATUS Status;
|
|
DEBUG ((DEBUG_INFO, "==== TestPointCheckAcpiGcdResource - Enter\n"));
|
|
//
|
// Check the ACPI existence
|
//
|
Status = DumpAcpiWithGuid (&gEfiAcpi20TableGuid, NULL, NULL, FALSE, FALSE);
|
if (Status == EFI_NOT_FOUND) {
|
Status = DumpAcpiWithGuid (&gEfiAcpi10TableGuid, NULL, NULL, FALSE, FALSE);
|
}
|
|
if (!EFI_ERROR(Status)) {
|
//
|
// Then check resource in ACPI and GCD
|
//
|
TestPointDumpGcd (&mAcpiGcdMemoryMap, &mAcpiGcdMemoryMapNumberOfDescriptors, &mAcpiGcdIoMap, &mAcpiGcdIoMapNumberOfDescriptors, FALSE);
|
|
Status = DumpAcpiWithGuid (&gEfiAcpi20TableGuid, NULL, NULL, FALSE, TRUE);
|
if (Status == EFI_NOT_FOUND) {
|
Status = DumpAcpiWithGuid (&gEfiAcpi10TableGuid, NULL, NULL, FALSE, TRUE);
|
}
|
}
|
|
if (EFI_ERROR(Status)) {
|
DEBUG ((DEBUG_ERROR, "ACPI table resource not in GCD\n"));
|
TestPointLibAppendErrorString (
|
PLATFORM_TEST_POINT_ROLE_PLATFORM_IBV,
|
NULL,
|
TEST_POINT_BYTE4_READY_TO_BOOT_GCD_RESOURCE_FUNCTIONAL_ERROR_CODE \
|
TEST_POINT_READY_TO_BOOT \
|
TEST_POINT_BYTE4_READY_TO_BOOT_GCD_RESOURCE_FUNCTIONAL_ERROR_STRING
|
);
|
}
|
DEBUG ((DEBUG_INFO, "==== TestPointCheckAcpiGcdResource - Exit\n"));
|
|
return Status;
|
}
|
|
VOID *
|
TestPointGetAcpi (
|
IN UINT32 Signature
|
)
|
{
|
EFI_STATUS Status;
|
VOID *Table;
|
|
Status = DumpAcpiWithGuid (&gEfiAcpi20TableGuid, &Signature, &Table, FALSE, FALSE);
|
if (Status == EFI_NOT_FOUND) {
|
Status = DumpAcpiWithGuid (&gEfiAcpi10TableGuid, &Signature, &Table, FALSE, FALSE);
|
}
|
|
if (EFI_ERROR(Status)) {
|
return NULL;
|
}
|
|
return Table;
|
}
|
|