aboutsummaryrefslogtreecommitdiff
path: root/tests/uefi-test-tools/UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/uefi-test-tools/UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.c')
-rw-r--r--tests/uefi-test-tools/UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/tests/uefi-test-tools/UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.c b/tests/uefi-test-tools/UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.c
new file mode 100644
index 0000000000..b208e17fb0
--- /dev/null
+++ b/tests/uefi-test-tools/UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.c
@@ -0,0 +1,130 @@
+/** @file
+ Populate the BIOS_TABLES_TEST structure.
+
+ Copyright (C) 2019, Red Hat, Inc.
+
+ 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 <Guid/Acpi.h>
+#include <Guid/BiosTablesTest.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+/**
+ Wait for a keypress with a message that the application is about to exit.
+**/
+STATIC
+VOID
+WaitForExitKeyPress (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Idx;
+ EFI_INPUT_KEY Key;
+
+ if (gST->ConIn == NULL) {
+ return;
+ }
+ AsciiPrint ("%a: press any key to exit\n", gEfiCallerBaseName);
+ Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Idx);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+}
+
+EFI_STATUS
+EFIAPI
+BiosTablesTestMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ VOID *Pages;
+ volatile BIOS_TABLES_TEST *BiosTablesTest;
+ 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 *BiosTablesTest),
+ SIZE_1MB);
+ if (Pages == NULL) {
+ AsciiErrorPrint ("%a: AllocateAlignedPages() failed\n",
+ gEfiCallerBaseName);
+ //
+ // Assuming the application was launched by the boot manager as a boot
+ // loader, exiting with error will cause the boot manager to proceed with
+ // the remaining boot options. If there are no other boot options, the boot
+ // manager menu will be pulled up. Give the user a chance to read the error
+ // message.
+ //
+ WaitForExitKeyPress ();
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // 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;
+ }
+
+ AsciiPrint ("%a: BiosTablesTest=%p Rsdp10=%p Rsdp20=%p\n",
+ gEfiCallerBaseName, Pages, Rsdp10, Rsdp20);
+
+ //
+ // Store the RSD PTR address(es) first, then the signature second.
+ //
+ BiosTablesTest = Pages;
+ BiosTablesTest->Rsdp10 = (UINTN)Rsdp10;
+ BiosTablesTest->Rsdp20 = (UINTN)Rsdp20;
+
+ MemoryFence();
+
+ InverseSignature = &BiosTablesTest->InverseSignatureGuid;
+ InverseSignature->Data1 = gBiosTablesTestGuid.Data1;
+ InverseSignature->Data1 ^= MAX_UINT32;
+ InverseSignature->Data2 = gBiosTablesTestGuid.Data2;
+ InverseSignature->Data2 ^= MAX_UINT16;
+ InverseSignature->Data3 = gBiosTablesTestGuid.Data3;
+ InverseSignature->Data3 ^= MAX_UINT16;
+ for (Idx = 0; Idx < sizeof InverseSignature->Data4; ++Idx) {
+ InverseSignature->Data4[Idx] = gBiosTablesTestGuid.Data4[Idx];
+ InverseSignature->Data4[Idx] ^= MAX_UINT8;
+ }
+
+ //
+ // The wait below has dual purpose. First, it blocks the application without
+ // wasting VCPU cycles while the hypervisor is scanning guest RAM. Second,
+ // assuming the application was launched by the boot manager as a boot
+ // loader, exiting the app with success causes the boot manager to pull up
+ // the boot manager menu at once (regardless of other boot options); the wait
+ // gives the user a chance to read the info printed above.
+ //
+ WaitForExitKeyPress ();
+ return EFI_SUCCESS;
+}