In case PcdFirmwareReleaseDateString is not set use a valid date
as fallback.  Using "unknown" makes Windows unhappy.
Fixes: 4cb94f20b0 ("OvmfPkg/SmbiosPlatformDxe: use PcdFirmware*")
Reported-by: ruifeng.gao@intel.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
		
	
		
			
				
	
	
		
			195 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   This driver installs SMBIOS information for OVMF
 | |
| 
 | |
|   Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
 | |
|   Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <IndustryStandard/SmBios.h>          // SMBIOS_TABLE_TYPE0
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/DebugLib.h>                 // ASSERT_EFI_ERROR()
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| #include <Library/PcdLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h> // gBS
 | |
| #include <Protocol/Smbios.h>                  // EFI_SMBIOS_PROTOCOL
 | |
| 
 | |
| #include "SmbiosPlatformDxe.h"
 | |
| 
 | |
| STATIC CONST SMBIOS_TABLE_TYPE0  mOvmfDefaultType0 = {
 | |
|   // SMBIOS_STRUCTURE Hdr
 | |
|   {
 | |
|     EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
 | |
|     sizeof (SMBIOS_TABLE_TYPE0),      // UINT8 Length
 | |
|   },
 | |
|   1,      // SMBIOS_TABLE_STRING       Vendor
 | |
|   2,      // SMBIOS_TABLE_STRING       BiosVersion
 | |
|   0xE800, // UINT16                    BiosSegment
 | |
|   3,      // SMBIOS_TABLE_STRING       BiosReleaseDate
 | |
|   0,      // UINT8                     BiosSize
 | |
|   {      // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
 | |
|     0,   // Reserved                                      :2
 | |
|     0,   // Unknown                                       :1
 | |
|     1,   // BiosCharacteristicsNotSupported               :1
 | |
|     // Remaining BiosCharacteristics bits left unset :60
 | |
|   },
 | |
|   {      // BIOSCharacteristicsExtensionBytes[2]
 | |
|     0,   // BiosReserved
 | |
|     0x1C // SystemReserved = VirtualMachineSupported |
 | |
|     //                  UefiSpecificationSupported |
 | |
|     //                  TargetContentDistributionEnabled
 | |
|   },
 | |
|   0,     // UINT8                     SystemBiosMajorRelease
 | |
|   0,     // UINT8                     SystemBiosMinorRelease
 | |
|   0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease
 | |
|   0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Get SMBIOS record length.
 | |
| 
 | |
|   @param  SmbiosTable   SMBIOS pointer.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| SmbiosTableLength (
 | |
|   IN SMBIOS_STRUCTURE_POINTER  SmbiosTable
 | |
|   )
 | |
| {
 | |
|   CHAR8  *AChar;
 | |
|   UINTN  Length;
 | |
| 
 | |
|   AChar = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);
 | |
| 
 | |
|   //
 | |
|   // Each structure shall be terminated by a double-null (SMBIOS spec.7.1)
 | |
|   //
 | |
|   while ((*AChar != 0) || (*(AChar + 1) != 0)) {
 | |
|     AChar++;
 | |
|   }
 | |
| 
 | |
|   Length = ((UINTN)AChar - (UINTN)SmbiosTable.Raw + 2);
 | |
| 
 | |
|   return Length;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Install all structures from the given SMBIOS structures block
 | |
| 
 | |
|   @param  TableAddress         SMBIOS tables starting address
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| InstallAllStructures (
 | |
|   IN UINT8  *TableAddress
 | |
|   )
 | |
| {
 | |
|   EFI_SMBIOS_PROTOCOL       *Smbios;
 | |
|   EFI_STATUS                Status;
 | |
|   SMBIOS_STRUCTURE_POINTER  SmbiosTable;
 | |
|   EFI_SMBIOS_HANDLE         SmbiosHandle;
 | |
|   BOOLEAN                   NeedSmbiosType0;
 | |
| 
 | |
|   //
 | |
|   // Find the SMBIOS protocol
 | |
|   //
 | |
|   Status = gBS->LocateProtocol (
 | |
|                   &gEfiSmbiosProtocolGuid,
 | |
|                   NULL,
 | |
|                   (VOID **)&Smbios
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   SmbiosTable.Raw = TableAddress;
 | |
|   if (SmbiosTable.Raw == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   NeedSmbiosType0 = TRUE;
 | |
| 
 | |
|   while (SmbiosTable.Hdr->Type != 127) {
 | |
|     //
 | |
|     // Log the SMBIOS data for this structure
 | |
|     //
 | |
|     SmbiosHandle = SmbiosTable.Hdr->Handle;
 | |
|     Status       = Smbios->Add (
 | |
|                              Smbios,
 | |
|                              NULL,
 | |
|                              &SmbiosHandle,
 | |
|                              (EFI_SMBIOS_TABLE_HEADER *)SmbiosTable.Raw
 | |
|                              );
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|     if (SmbiosTable.Hdr->Type == 0) {
 | |
|       NeedSmbiosType0 = FALSE;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Get the next structure address
 | |
|     //
 | |
|     SmbiosTable.Raw = (UINT8 *)(SmbiosTable.Raw + SmbiosTableLength (SmbiosTable));
 | |
|   }
 | |
| 
 | |
|   if (NeedSmbiosType0) {
 | |
|     //
 | |
|     // Add OVMF default Type 0 (BIOS Information) table
 | |
|     //
 | |
|     CHAR16  *VendStr, *VersStr, *DateStr;
 | |
|     UINTN   VendLen, VersLen, DateLen;
 | |
|     CHAR8   *Type0;
 | |
| 
 | |
|     VendStr = (CHAR16 *)FixedPcdGetPtr (PcdFirmwareVendor);
 | |
|     VendLen = StrLen (VendStr);
 | |
|     if (VendLen < 3) {
 | |
|       VendStr = L"unknown";
 | |
|       VendLen = StrLen (VendStr);
 | |
|     }
 | |
| 
 | |
|     VersStr = (CHAR16 *)FixedPcdGetPtr (PcdFirmwareVersionString);
 | |
|     VersLen = StrLen (VersStr);
 | |
|     if (VersLen < 3) {
 | |
|       VersStr = L"unknown";
 | |
|       VersLen = StrLen (VersStr);
 | |
|     }
 | |
| 
 | |
|     DateStr = (CHAR16 *)FixedPcdGetPtr (PcdFirmwareReleaseDateString);
 | |
|     DateLen = StrLen (DateStr);
 | |
|     if (DateLen < 3) {
 | |
|       DateStr = L"2/2/2022";
 | |
|       DateLen = StrLen (DateStr);
 | |
|     }
 | |
| 
 | |
|     DEBUG ((DEBUG_INFO, "FirmwareVendor:            \"%s\" (%d chars)\n", VendStr, VendLen));
 | |
|     DEBUG ((DEBUG_INFO, "FirmwareVersionString:     \"%s\" (%d chars)\n", VersStr, VersLen));
 | |
|     DEBUG ((DEBUG_INFO, "FirmwareReleaseDateString: \"%s\" (%d chars)\n", DateStr, DateLen));
 | |
| 
 | |
|     Type0 = AllocateZeroPool (sizeof (mOvmfDefaultType0) + VendLen + VersLen + DateLen + 4);
 | |
|     if (Type0 == NULL) {
 | |
|       return EFI_OUT_OF_RESOURCES;
 | |
|     }
 | |
| 
 | |
|     CopyMem (Type0, &mOvmfDefaultType0, sizeof (mOvmfDefaultType0));
 | |
|     UnicodeStrToAsciiStrS (VendStr, Type0 + sizeof (mOvmfDefaultType0), VendLen + 1);
 | |
|     UnicodeStrToAsciiStrS (VersStr, Type0 + sizeof (mOvmfDefaultType0) + VendLen + 1, VersLen + 1);
 | |
|     UnicodeStrToAsciiStrS (DateStr, Type0 + sizeof (mOvmfDefaultType0) + VendLen + VersLen + 2, DateLen + 1);
 | |
| 
 | |
|     SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
 | |
|     Status       = Smbios->Add (
 | |
|                              Smbios,
 | |
|                              NULL,
 | |
|                              &SmbiosHandle,
 | |
|                              (EFI_SMBIOS_TABLE_HEADER *)Type0
 | |
|                              );
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|     FreePool (Type0);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |