qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

BiosTablesTest.c (4942B)


      1 /** @file
      2   Populate the BIOS_TABLES_TEST structure.
      3 
      4   Copyright (C) 2019, Red Hat, Inc.
      5 
      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>.
     10 
     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.
     13 **/
     14 
     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>
     23 
     24 /**
     25   Wait for a keypress with a message that the application is about to exit.
     26 **/
     27 STATIC
     28 VOID
     29 WaitForExitKeyPress (
     30   VOID
     31   )
     32 {
     33   EFI_STATUS    Status;
     34   UINTN         Idx;
     35   EFI_INPUT_KEY Key;
     36 
     37   if (gST->ConIn == NULL) {
     38     return;
     39   }
     40   AsciiPrint ("%a: press any key to exit\n", gEfiCallerBaseName);
     41   Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Idx);
     42   if (EFI_ERROR (Status)) {
     43     return;
     44   }
     45   gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
     46 }
     47 
     48 EFI_STATUS
     49 EFIAPI
     50 BiosTablesTestMain (
     51   IN EFI_HANDLE       ImageHandle,
     52   IN EFI_SYSTEM_TABLE *SystemTable
     53   )
     54 {
     55   VOID                          *Pages;
     56   volatile BIOS_TABLES_TEST     *BiosTablesTest;
     57   CONST VOID                    *Rsdp10;
     58   CONST VOID                    *Rsdp20;
     59   CONST VOID                    *Smbios21;
     60   CONST VOID                    *Smbios30;
     61   CONST EFI_CONFIGURATION_TABLE *ConfigTable;
     62   CONST EFI_CONFIGURATION_TABLE *ConfigTablesEnd;
     63   volatile EFI_GUID             *InverseSignature;
     64   UINTN                         Idx;
     65 
     66   Pages = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof *BiosTablesTest),
     67             SIZE_1MB);
     68   if (Pages == NULL) {
     69     AsciiErrorPrint ("%a: AllocateAlignedPages() failed\n",
     70       gEfiCallerBaseName);
     71     //
     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
     76     // message.
     77     //
     78     WaitForExitKeyPress ();
     79     return EFI_OUT_OF_RESOURCES;
     80   }
     81 
     82   //
     83   // Locate all the gEfiAcpi10TableGuid, gEfiAcpi20TableGuid,
     84   // gEfiSmbiosTableGuid, gEfiSmbios3TableGuid config tables in one go.
     85   //
     86   Rsdp10 = NULL;
     87   Rsdp20 = NULL;
     88   Smbios21 = NULL;
     89   Smbios30 = NULL;
     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;
    103     }
    104     ++ConfigTable;
    105   }
    106 
    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,
    110     Smbios30);
    111 
    112   //
    113   // Store the config table addresses first, then the signature second.
    114   //
    115   BiosTablesTest = Pages;
    116   BiosTablesTest->Rsdp10 = (UINTN)Rsdp10;
    117   BiosTablesTest->Rsdp20 = (UINTN)Rsdp20;
    118   BiosTablesTest->Smbios21 = (UINTN)Smbios21;
    119   BiosTablesTest->Smbios30 = (UINTN)Smbios30;
    120 
    121   MemoryFence();
    122 
    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;
    133   }
    134 
    135   //
    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.
    142   //
    143   WaitForExitKeyPress ();
    144   return EFI_SUCCESS;
    145 }