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 <Guid/SmBios.h>
18 #include <Library/BaseLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiLib.h>
25 Wait for a keypress with a message that the application is about to exit.
37 if (gST
->ConIn
== NULL
) {
40 AsciiPrint ("%a: press any key to exit\n", gEfiCallerBaseName
);
41 Status
= gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &Idx
);
42 if (EFI_ERROR (Status
)) {
45 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
51 IN EFI_HANDLE ImageHandle
,
52 IN EFI_SYSTEM_TABLE
*SystemTable
56 volatile BIOS_TABLES_TEST
*BiosTablesTest
;
61 CONST EFI_CONFIGURATION_TABLE
*ConfigTable
;
62 CONST EFI_CONFIGURATION_TABLE
*ConfigTablesEnd
;
63 volatile EFI_GUID
*InverseSignature
;
66 Pages
= AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof *BiosTablesTest
),
69 AsciiErrorPrint ("%a: AllocateAlignedPages() failed\n",
72 // Assuming the application was launched by the boot manager as a boot
73 // loader, exiting with error will cause the boot manager to proceed with
74 // the remaining boot options. If there are no other boot options, the boot
75 // manager menu will be pulled up. Give the user a chance to read the error
78 WaitForExitKeyPress ();
79 return EFI_OUT_OF_RESOURCES
;
83 // Locate all the gEfiAcpi10TableGuid, gEfiAcpi20TableGuid,
84 // gEfiSmbiosTableGuid, gEfiSmbios3TableGuid config tables in one go.
90 ConfigTable
= gST
->ConfigurationTable
;
91 ConfigTablesEnd
= gST
->ConfigurationTable
+ gST
->NumberOfTableEntries
;
92 while ((Rsdp10
== NULL
|| Rsdp20
== NULL
||
93 Smbios21
== NULL
|| Smbios30
== NULL
) &&
94 ConfigTable
< ConfigTablesEnd
) {
95 if (CompareGuid (&ConfigTable
->VendorGuid
, &gEfiAcpi10TableGuid
)) {
96 Rsdp10
= ConfigTable
->VendorTable
;
97 } else if (CompareGuid (&ConfigTable
->VendorGuid
, &gEfiAcpi20TableGuid
)) {
98 Rsdp20
= ConfigTable
->VendorTable
;
99 } else if (CompareGuid (&ConfigTable
->VendorGuid
, &gEfiSmbiosTableGuid
)) {
100 Smbios21
= ConfigTable
->VendorTable
;
101 } else if (CompareGuid (&ConfigTable
->VendorGuid
, &gEfiSmbios3TableGuid
)) {
102 Smbios30
= ConfigTable
->VendorTable
;
107 AsciiPrint ("%a: BiosTablesTest=%p Rsdp10=%p Rsdp20=%p\n",
108 gEfiCallerBaseName
, Pages
, Rsdp10
, Rsdp20
);
109 AsciiPrint ("%a: Smbios21=%p Smbios30=%p\n", gEfiCallerBaseName
, Smbios21
,
113 // Store the config table addresses first, then the signature second.
115 BiosTablesTest
= Pages
;
116 BiosTablesTest
->Rsdp10
= (UINTN
)Rsdp10
;
117 BiosTablesTest
->Rsdp20
= (UINTN
)Rsdp20
;
118 BiosTablesTest
->Smbios21
= (UINTN
)Smbios21
;
119 BiosTablesTest
->Smbios30
= (UINTN
)Smbios30
;
123 InverseSignature
= &BiosTablesTest
->InverseSignatureGuid
;
124 InverseSignature
->Data1
= gBiosTablesTestGuid
.Data1
;
125 InverseSignature
->Data1
^= MAX_UINT32
;
126 InverseSignature
->Data2
= gBiosTablesTestGuid
.Data2
;
127 InverseSignature
->Data2
^= MAX_UINT16
;
128 InverseSignature
->Data3
= gBiosTablesTestGuid
.Data3
;
129 InverseSignature
->Data3
^= MAX_UINT16
;
130 for (Idx
= 0; Idx
< sizeof InverseSignature
->Data4
; ++Idx
) {
131 InverseSignature
->Data4
[Idx
] = gBiosTablesTestGuid
.Data4
[Idx
];
132 InverseSignature
->Data4
[Idx
] ^= MAX_UINT8
;
136 // The wait below has dual purpose. First, it blocks the application without
137 // wasting VCPU cycles while the hypervisor is scanning guest RAM. Second,
138 // assuming the application was launched by the boot manager as a boot
139 // loader, exiting the app with success causes the boot manager to pull up
140 // the boot manager menu at once (regardless of other boot options); the wait
141 // gives the user a chance to read the info printed above.
143 WaitForExitKeyPress ();