2 Populate the BIOS_TABLES_TEST structure.
4 Copyright (C) 2019, Red Hat, Inc.
6 This program and the accompanying materials are licensed and made available
7 under the terms and conditions of the BSD License that accompanies this
8 distribution. The full text of the license may be found at
9 <http://opensource.org/licenses/bsd-license.php>.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
12 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Guid/Acpi.h>
16 #include <Guid/BiosTablesTest.h>
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/UefiLib.h>
24 Wait for a keypress with a message that the application is about to exit.
36 if (gST
->ConIn
== NULL
) {
39 AsciiPrint ("%a: press any key to exit\n", gEfiCallerBaseName
);
40 Status
= gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &Idx
);
41 if (EFI_ERROR (Status
)) {
44 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
50 IN EFI_HANDLE ImageHandle
,
51 IN EFI_SYSTEM_TABLE
*SystemTable
55 volatile BIOS_TABLES_TEST
*BiosTablesTest
;
58 CONST EFI_CONFIGURATION_TABLE
*ConfigTable
;
59 CONST EFI_CONFIGURATION_TABLE
*ConfigTablesEnd
;
60 volatile EFI_GUID
*InverseSignature
;
63 Pages
= AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof *BiosTablesTest
),
66 AsciiErrorPrint ("%a: AllocateAlignedPages() failed\n",
69 // Assuming the application was launched by the boot manager as a boot
70 // loader, exiting with error will cause the boot manager to proceed with
71 // the remaining boot options. If there are no other boot options, the boot
72 // manager menu will be pulled up. Give the user a chance to read the error
75 WaitForExitKeyPress ();
76 return EFI_OUT_OF_RESOURCES
;
80 // Locate both gEfiAcpi10TableGuid and gEfiAcpi20TableGuid config tables in
85 ConfigTable
= gST
->ConfigurationTable
;
86 ConfigTablesEnd
= gST
->ConfigurationTable
+ gST
->NumberOfTableEntries
;
87 while ((Rsdp10
== NULL
|| Rsdp20
== NULL
) && ConfigTable
< ConfigTablesEnd
) {
88 if (CompareGuid (&ConfigTable
->VendorGuid
, &gEfiAcpi10TableGuid
)) {
89 Rsdp10
= ConfigTable
->VendorTable
;
90 } else if (CompareGuid (&ConfigTable
->VendorGuid
, &gEfiAcpi20TableGuid
)) {
91 Rsdp20
= ConfigTable
->VendorTable
;
96 AsciiPrint ("%a: BiosTablesTest=%p Rsdp10=%p Rsdp20=%p\n",
97 gEfiCallerBaseName
, Pages
, Rsdp10
, Rsdp20
);
100 // Store the RSD PTR address(es) first, then the signature second.
102 BiosTablesTest
= Pages
;
103 BiosTablesTest
->Rsdp10
= (UINTN
)Rsdp10
;
104 BiosTablesTest
->Rsdp20
= (UINTN
)Rsdp20
;
108 InverseSignature
= &BiosTablesTest
->InverseSignatureGuid
;
109 InverseSignature
->Data1
= gBiosTablesTestGuid
.Data1
;
110 InverseSignature
->Data1
^= MAX_UINT32
;
111 InverseSignature
->Data2
= gBiosTablesTestGuid
.Data2
;
112 InverseSignature
->Data2
^= MAX_UINT16
;
113 InverseSignature
->Data3
= gBiosTablesTestGuid
.Data3
;
114 InverseSignature
->Data3
^= MAX_UINT16
;
115 for (Idx
= 0; Idx
< sizeof InverseSignature
->Data4
; ++Idx
) {
116 InverseSignature
->Data4
[Idx
] = gBiosTablesTestGuid
.Data4
[Idx
];
117 InverseSignature
->Data4
[Idx
] ^= MAX_UINT8
;
121 // The wait below has dual purpose. First, it blocks the application without
122 // wasting VCPU cycles while the hypervisor is scanning guest RAM. Second,
123 // assuming the application was launched by the boot manager as a boot
124 // loader, exiting the app with success causes the boot manager to pull up
125 // the boot manager menu at once (regardless of other boot options); the wait
126 // gives the user a chance to read the info printed above.
128 WaitForExitKeyPress ();