If the PcdAcpiTestSupport Feature PCD is set, allocate and fill the ACPI_TEST_SUPPORT structure at a 1MB boundary.
This feature is a best-effort development / unit test helper, so even if it is enabled at build time, and fails at boot time, it will not prevent AcpiPlatformDxe from doing its job. For the same reason, error messages are only logged at the DEBUG_WARN level. Cc: Anthony Perard <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Drew Jones <[email protected]> Cc: Igor Mammedov <[email protected]> Cc: Jordan Justen <[email protected]> Cc: Julien Grall <[email protected]> Cc: Philippe Mathieu-Daudé <[email protected]> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <[email protected]> --- OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | 4 + OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf | 4 + OvmfPkg/AcpiPlatformDxe/AcpiTestSupport.c | 89 ++++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf index 9c5bfe767981..11ae3e2a1ac1 100644 --- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -66,6 +66,10 @@ [Protocols] gEfiPciIoProtocolGuid # PROTOCOL SOMETIMES_CONSUMED [Guids] + gAcpiTestSupportGuid + gEfiAcpi10TableGuid + gEfiAcpi20TableGuid + gEfiEventReadyToBootGuid gEfiXenInfoGuid gRootBridgesConnectedEventGroupGuid diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf index b2501fea9ca4..062f4d2fc50c 100644 --- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf +++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf @@ -58,6 +58,10 @@ [Protocols] gEfiPciIoProtocolGuid # PROTOCOL SOMETIMES_CONSUMED [Guids] + gAcpiTestSupportGuid + gEfiAcpi10TableGuid + gEfiAcpi20TableGuid + gEfiEventReadyToBootGuid gRootBridgesConnectedEventGroupGuid [Pcd] diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiTestSupport.c b/OvmfPkg/AcpiPlatformDxe/AcpiTestSupport.c index 462c8e64a4fd..26dd26cdc439 100644 --- a/OvmfPkg/AcpiPlatformDxe/AcpiTestSupport.c +++ b/OvmfPkg/AcpiPlatformDxe/AcpiTestSupport.c @@ -15,16 +15,105 @@ #include "AcpiPlatform.h" +#include <Guid/Acpi.h> +#include <Guid/AcpiTestSupport.h> +#include <Guid/EventGroup.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> + +STATIC volatile ACPI_TEST_SUPPORT *mAcpiTestSupport; +STATIC EFI_EVENT mAcpiTestSupportEvent; + +STATIC +VOID +EFIAPI +AcpiTestSupportOnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + VOID *Pages; + CONST VOID *Rsdp10; + CONST VOID *Rsdp20; + CONST EFI_CONFIGURATION_TABLE *ConfigTable; + CONST EFI_CONFIGURATION_TABLE *ConfigTablesEnd; + volatile EFI_GUID *InverseSignature; + UINTN Idx; + + Pages = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof *mAcpiTestSupport), + SIZE_1MB); + if (Pages == NULL) { + DEBUG ((DEBUG_WARN, "%a: AllocateAlignedPages() failed\n", __FUNCTION__)); + UnregisterAcpiTestSupport (); + return; + } + + // + // Locate both gEfiAcpi10TableGuid and gEfiAcpi20TableGuid config tables in + // one go. + // + Rsdp10 = NULL; + Rsdp20 = NULL; + ConfigTable = gST->ConfigurationTable; + ConfigTablesEnd = gST->ConfigurationTable + gST->NumberOfTableEntries; + while ((Rsdp10 == NULL || Rsdp20 == NULL) && ConfigTable < ConfigTablesEnd) { + if (CompareGuid (&ConfigTable->VendorGuid, &gEfiAcpi10TableGuid)) { + Rsdp10 = ConfigTable->VendorTable; + } else if (CompareGuid (&ConfigTable->VendorGuid, &gEfiAcpi20TableGuid)) { + Rsdp20 = ConfigTable->VendorTable; + } + ++ConfigTable; + } + + DEBUG ((DEBUG_VERBOSE, "%a: AcpiTestSupport=%p Rsdp10=%p Rsdp20=%p\n", + __FUNCTION__, Pages, Rsdp10, Rsdp20)); + + // + // Store the RSD PTR address(es) first, then the signature second. + // + mAcpiTestSupport = Pages; + mAcpiTestSupport->Rsdp10 = (UINTN)Rsdp10; + mAcpiTestSupport->Rsdp20 = (UINTN)Rsdp20; + + MemoryFence(); + + InverseSignature = &mAcpiTestSupport->InverseSignatureGuid; + InverseSignature->Data1 = gAcpiTestSupportGuid.Data1; + InverseSignature->Data1 ^= MAX_UINT32; + InverseSignature->Data2 = gAcpiTestSupportGuid.Data2; + InverseSignature->Data2 ^= MAX_UINT16; + InverseSignature->Data3 = gAcpiTestSupportGuid.Data3; + InverseSignature->Data3 ^= MAX_UINT16; + for (Idx = 0; Idx < sizeof InverseSignature->Data4; ++Idx) { + InverseSignature->Data4[Idx] = gAcpiTestSupportGuid.Data4[Idx]; + InverseSignature->Data4[Idx] ^= MAX_UINT8; + } + + UnregisterAcpiTestSupport (); +} + VOID RegisterAcpiTestSupport ( VOID ) { + EFI_STATUS Status; + + Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, + AcpiTestSupportOnReadyToBoot, NULL /* Context */, + &gEfiEventReadyToBootGuid, &mAcpiTestSupportEvent); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "%a: CreateEventEx(): %r\n", __FUNCTION__, Status)); + } } VOID UnregisterAcpiTestSupport ( VOID ) { + if (mAcpiTestSupportEvent != NULL) { + gBS->CloseEvent (mAcpiTestSupportEvent); + mAcpiTestSupportEvent = NULL; + } } -- 2.19.1.3.g30247aa5d201 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

