/** @file Copyright (c) 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License that accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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, 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; } 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, 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; } 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; }