/**
* OemSaveSmbiosDxe - SMBIOS PCD Save/Restore driver
*
* This DXE driver saves OEM SMBIOS PCD configuration values into an
* EFI variable ("OemSmbiosPcdValue") and restores them during boot.
* It reads SMBIOS-related PCD tokens (system manufacturer, product name,
* serial numbers, UUID, chassis info, baseboard info) and writes them
* to the OemSmbiosPcdValue UEFI variable. On subsequent boots, if the
* FRU data contains default "To be filled by O.E.M." strings, the driver
* restores the previously saved values from the variable.
*
* Extracted from HR650X BIOS (index 0091).
* MD5: 8c1d934e97825c7b1ec3bf4b448da3e0
* SHA256: 7466e5a58cf614358c979611ed39cd085c452ee877c370c47f0c22b586ffa8c4
*/
#include "OemSaveSmbiosDxe.h"
//
// EFI global variable storage
//
EFI_HANDLE gImageHandle;
EFI_SYSTEM_TABLE *gST;
EFI_BOOT_SERVICES *gBS;
EFI_RUNTIME_SERVICES *gRT;
//
// Lazily-located protocol pointers
//
EFI_SMBIOS_PROTOCOL *gSmbiosProtocol = NULL; // qword_2F68
PCD_PROTOCOL *mPcdProtocol = NULL; // qword_2F70
VOID *mHobList = NULL; // qword_2F78
//
// Control flags -- set by OemRestoreSmbiosPcdvalue, consumed by OemRestoreSmbiosString
//
BOOLEAN gSystemManufacturerRestored = FALSE; // byte_2F18 Token 118
BOOLEAN gSystemProductNameRestored = FALSE; // byte_2F19 Token 117
BOOLEAN gSystemVersionRestored = FALSE; // byte_2F1A Token 119
BOOLEAN gSystemSerialNumberRestored = FALSE; // byte_2F1B Token 120
BOOLEAN gSystemUuidRestored = FALSE; // byte_2F1C Token 187
BOOLEAN gBaseBoardManufacturerRestored = FALSE; // byte_2F30 Token 121
BOOLEAN gBaseBoardProductNameRestored = FALSE; // byte_2F31 Token 122
BOOLEAN gBaseBoardVersionRestored = FALSE; // byte_2F32 Token 123
BOOLEAN gBaseBoardSerialNumberRestored = FALSE; // byte_2F33 Token 124
BOOLEAN gBaseBoardAssetTagRestored = FALSE; // byte_2F34 Token 125
BOOLEAN gChassisManufacturerRestored = FALSE; // byte_2F10 Token 126
BOOLEAN gChassisVersionRestored = FALSE; // byte_2F11 Token 127
BOOLEAN gChassisSerialNumberRestored = FALSE; // byte_2F12 Token 128
BOOLEAN gChassisAssetTagRestored = FALSE; // byte_2F13 Token 129
BOOLEAN gChassisTypeRestored = FALSE; // byte_2F14 Token 188
//
// GUID definitions
//
// {OemSmbiosPcdValue GUID} -- from unk_2F00
EFI_GUID gOemSmbiosPcdValueGuid = { 0x9e8b8a20, 0x82e8, 0x11e4, { 0x80, 0x5e, 0x08, 0x9e, 0x01, 0x12, 0x2e, 0x17 } };
// gEfiSmbiosProtocolGuid -- from unk_2EC0
EFI_GUID gEfiSmbiosProtocolGuid = EFI_SMBIOS_PROTOCOL_GUID;
// gHobListGuid -- from unk_2EF0
EFI_GUID gHobListGuid = EFI_HOB_LIST_GUID;
// gPcdProtocolGuid -- from unk_2ED0
EFI_GUID gPcdProtocolGuid = EFI_PCD_PROTOCOL_GUID;
//------------------------------------------------------------------------------
// Utility / library wrapper functions
//------------------------------------------------------------------------------
/**
* Copies memory, handling overlapping regions safely.
* Wraps CopyMem with overlap detection.
*/
VOID *
CopyMemS (
VOID *Destination,
CONST VOID *Source,
UINTN Count
)
{
CHAR8 *Dst8;
CHAR8 *Src8;
if (Source < Destination && &((CONST CHAR8 *)Source)[Count - 1] >= (CHAR8 *)Destination) {
// Overlapping: copy backwards
Src8 = &((CHAR8 *)Source)[Count - 1];
Dst8 = &((CHAR8 *)Destination)[Count - 1];
} else {
// No overlap: copy forwards in 8-byte chunks
CopyMem (Destination, Source, Count & ~7);
Src8 = &((CHAR8 *)Source)[Count & ~7];
Dst8 = &((CHAR8 *)Destination)[Count & ~7];
}
// Copy remaining bytes
CopyMem (Dst8, Src8, Count & 7);
return Destination;
}
/**
* Zeroes a memory buffer in 8-byte chunks then residual.
*/
VOID *
ZeroMemS (
VOID *Buffer,
UINTN Size
)
{
ZeroMem (Buffer, Size & ~7);
ZeroMem (&((CHAR8 *)Buffer)[Size & ~7], Size & 7);
return Buffer;
}
/**
* ASSERT-style debug assertion helper.
* Prints file/line/description via debug protocol.
*/
VOID
DebugAssert (
CONST CHAR8 *FileName,
UINTN LineNumber,
CONST CHAR8 *Description
)
{
PCD_PROTOCOL *Pcd;
UINT8 DebugLevel;
UINTN ErrorLevel;
Pcd = GetPcdProtocol ();
ErrorLevel = 0;
if (Pcd != NULL) {
//
// Read CMOS index 0x4B to get debug level
//
DebugLevel = IoRead8 (0x70);
IoWrite8 (0x70, DebugLevel & 0x80 | 0x4B);
DebugLevel = IoRead8 (0x71);
if (DebugLevel > 3) {
if (DebugLevel == 0) {
DebugLevel = (MmioRead8 (0xFDAF0490) & 2) | 1;
}
}
ErrorLevel = (DebugLevel == 1) ? EFI_D_ERROR : EFI_D_INFO;
}
if ((ErrorLevel & DEBUG_ERROR) != 0) {
DEBUG ((DEBUG_ERROR, "%a(%d): %a\n", FileName, LineNumber, Description));
}
}
/**
* Conditional debug print that checks CMOS debug level mask.
*/
UINTN
DebugPrint (
UINTN ErrorLevel,
CONST CHAR8 *Format,
...
)
{
PCD_PROTOCOL *Pcd;
UINTN Result;
UINT8 DebugLevel;
UINTN Mask;
VA_LIST Args;
Pcd = GetPcdProtocol ();
Mask = 0;
Result = 0;
if (Pcd != NULL) {
DebugLevel = IoRead8 (0x70);
IoWrite8 (0x70, DebugLevel & 0x80 | 0x4B);
DebugLevel = IoRead8 (0x71);
if (DebugLevel > 3) {
if (DebugLevel == 0) {
DebugLevel = (MmioRead8 (0xFDAF0490) & 2) | 1;
}
}
switch (DebugLevel) {
case 1:
Mask = EFI_D_ERROR;
break;
default:
Mask = EFI_D_INFO;
break;
}
if ((Mask & ErrorLevel) != 0) {
VA_START (Args, Format);
Result = DebugVPrint (ErrorLevel, Format, Args);
VA_END (Args);
}
}
return Result;
}
/**
* Unicode string copy (StrCpyS wrapper). Copies Source into Destination.
* The buffer must not overlap.
*/
CHAR16 *
StrCpyS (
CHAR16 *Destination,
CONST CHAR16 *Source
)
{
CHAR16 *Dst;
Dst = Destination;
ASSERT (Destination != NULL);
ASSERT (((UINTN)Destination & 1) == 0);
ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
ASSERT ((UINTN)(Source - Destination) > StrLen (Source));
while (*Source != L'\0') {
*Dst++ = *Source++;
}
*Dst = L'\0';
return Destination;
}
/**
* Returns the length of a null-terminated Unicode string.
*/
UINTN
StrLen (
CONST CHAR16 *String
)
{
UINTN Length;
ASSERT (String != NULL);
ASSERT (((UINTN)String & 1) == 0);
Length = 0;
while (*String != L'\0') {
ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));
String++;
Length++;
}
return Length;
}
/**
* Compares two Unicode strings.
* Returns 0 if equal, <0 or >0 otherwise.
*/
INTN
StrCmp (
CONST CHAR16 *FirstString,
CONST CHAR16 *SecondString
)
{
ASSERT (StrSize (FirstString) != 0);
ASSERT (StrSize (SecondString) != 0);
while (*FirstString != L'\0' && *FirstString == *SecondString) {
FirstString++;
SecondString++;
}
return (INTN)*FirstString - (INTN)*SecondString;
}
/**
* Converts a null-terminated Unicode string to an ASCII string.
*/
CHAR8 *
UnicodeStrToAsciiStrS (
CONST CHAR16 *Source,
CHAR8 *Destination
)
{
CHAR8 *Dst;
Dst = Destination;
ASSERT (Destination != NULL);
ASSERT (StrSize (Source) != 0);
ASSERT ((UINTN)(Destination - (CHAR8 *)Source) >= StrSize (Source));
ASSERT ((UINTN)((CHAR8 *)Source - Destination) > StrLen (Source));
while (*Source != L'\0') {
ASSERT (*Source < 0x100);
*Dst++ = (CHAR8)*Source++;
}
*Dst = '\0';
ASSERT (AsciiStrSize (Destination) != 0);
return Destination;
}
/**
* Returns the length of a null-terminated ASCII string.
*/
UINTN
AsciiStrLen (
CONST CHAR8 *String
)
{
UINTN Length;
ASSERT (String != NULL);
for (Length = 0; *String != '\0'; Length++) {
ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));
String++;
}
return Length;
}
/**
* Reads a UINT64 from potentially unaligned address.
*/
UINT64
ReadUnaligned64 (
CONST VOID *Buffer
)
{
ASSERT (Buffer != NULL);
return *(UINT64 *)Buffer;
}
/**
* Reads two UINT64 values (128 bits) from unaligned source into destination array.
*/
UINT64 *
ReadUnaligned128 (
UINT64 *Destination,
CONST VOID *Source
)
{
ASSERT (Destination != NULL);
Destination[0] = ReadUnaligned64 (Source);
Destination[1] = ReadUnaligned64 ((UINT8 *)Source + 8);
return Destination;
}
/**
* Compares two 128-bit GUID values (as two UINT64s).
*/
BOOLEAN
CompareGuid (
CONST UINT64 *Guid1,
CONST UINT64 *Guid2
)
{
return (ReadUnaligned64 (Guid1) == ReadUnaligned64 (Guid2)) &&
(ReadUnaligned64 ((UINT8 *)Guid1 + 8) == ReadUnaligned64 ((UINT8 *)Guid2 + 8));
}
/**
* Locates and caches the HOB list pointer from the System Table.
*/
VOID *
GetHobList (
VOID
)
{
UINTN Index;
UINTN NumberOfTableEntries;
VOID *GuidHobList;
if (mHobList != NULL) {
return mHobList;
}
mHobList = NULL;
GuidHobList = NULL;
NumberOfTableEntries = gST->NumberOfTableEntries;
if (NumberOfTableEntries > 0) {
for (Index = 0; Index < NumberOfTableEntries; Index++) {
if (CompareGuid (&gHobListGuid, &gST->ConfigurationTable[Index].VendorGuid)) {
GuidHobList = gST->ConfigurationTable[Index].VendorTable;
break;
}
}
mHobList = GuidHobList;
if (mHobList == NULL) {
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
ASSERT (mHobList != NULL);
}
} else {
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
ASSERT (mHobList != NULL);
}
return mHobList;
}
/**
* Locates and caches the PCD protocol.
*/
PCD_PROTOCOL *
GetPcdProtocol (
VOID
)
{
EFI_STATUS Status;
if (mPcdProtocol == NULL) {
Status = gBS->LocateProtocol (&gPcdProtocolGuid, NULL, (VOID **)&mPcdProtocol);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
ASSERT_EFI_ERROR (Status);
}
if (mPcdProtocol == NULL) {
ASSERT (mPcdProtocol != NULL);
}
}
return mPcdProtocol;
}
/**
* Calls PcdGetPtr via the PCD protocol with size query.
* Returns the buffer pointer on success, NULL if the buffer was too small.
*/
VOID *
PcdGetPtrWrapper (
UINTN TokenNumber,
UINTN *SizeOfBuffer,
VOID *Buffer
)
{
UINTN OriginalSize;
PCD_PROTOCOL *Pcd;
ASSERT (SizeOfBuffer != NULL);
ASSERT (*SizeOfBuffer == 0 || Buffer != NULL);
OriginalSize = *SizeOfBuffer;
Pcd = GetPcdProtocol ();
if (Pcd->GetPtr (TokenNumber, SizeOfBuffer, Buffer) >= 0 || *SizeOfBuffer >= OriginalSize) {
return Buffer;
}
return NULL;
}
//------------------------------------------------------------------------------
// OemSaveSmbiosPcdvalue -- sub_41C
//
// Reads all system/board/chassis PCD values and saves them into the
// OemSmbiosPcdValue UEFI variable.
//------------------------------------------------------------------------------
EFI_STATUS
EFIAPI
OemSaveSmbiosPcdvalue (
VOID
)
{
EFI_STATUS Status;
UINT8 Buffer[0xE49];
UINTN DataSize;
PCD_PROTOCOL *Pcd;
CHAR16 *PcdStr;
UINTN StrLenBytes;
UINTN VarSize;
//
// System information buffers (280 bytes each for SMBIOS strings)
//
CHAR8 SmbiosStrings[13][280];
DEBUG ((DEBUG_INFO, "OemSaveSmbiosPcdvalue...Start\n"));
ZeroMemS (Buffer, sizeof (Buffer));
//
// Read existing variable (may not exist on first boot)
//
DataSize = sizeof (Buffer);
Status = gRT->GetVariable (
L"OemSmbiosPcdValue",
&gOemSmbiosPcdValueGuid,
NULL,
&DataSize,
Buffer
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "GetVariable fail %r\n", Status));
ZeroMemS (Buffer, sizeof (Buffer));
}
//
// PCD Token 118 - System Manufacturer
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (118, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (PcdStr, L"SYSTEM_MANUFACTURER") == 0 &&
StrCmp (Buffer, PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[0], PcdStr);
}
//
// PCD Token 117 - System Product Name
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (117, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (PcdStr, L"SYSTEM_PRODUCT_NAME") == 0 &&
StrCmp (SmbiosStrings[1], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[1], PcdStr);
}
//
// PCD Token 119 - System Version
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (119, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (PcdStr, L"SYSTEM_VERSION") == 0 &&
StrCmp (SmbiosStrings[2], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[2], PcdStr);
}
//
// PCD Token 120 - System Serial Number
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (120, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (PcdStr, L"SYSTEM_SERIAL_NUMBER") == 0 &&
StrCmp (SmbiosStrings[3], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[3], PcdStr);
}
//
// PCD Token 187 - System UUID
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (187, NULL, NULL);
if (!CompareGuid (PcdStr, &gOemSmbiosPcdValueGuid) &&
!CompareGuid (PcdStr, &gEfiSmbiosProtocolGuid) &&
!CompareGuid (PcdStr, &gHobListGuid))
{
ReadUnaligned128 (&SmbiosStrings[4], PcdStr);
}
//
// PCD Token 121 - Base Board Manufacturer
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (121, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[5], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[5], PcdStr);
}
//
// PCD Token 122 - Base Board Product Name
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (122, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[6], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[6], PcdStr);
}
//
// PCD Token 123 - Base Board Version
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (123, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[7], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[7], PcdStr);
}
//
// PCD Token 124 - Base Board Serial Number
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (124, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[8], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[8], PcdStr);
}
//
// PCD Token 125 - Base Board Asset Tag
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (125, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[9], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[9], PcdStr);
}
//
// PCD Token 126 - Chassis Manufacturer
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (126, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[10], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[10], PcdStr);
}
//
// PCD Token 127 - Chassis Version
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (127, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[11], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[11], PcdStr);
}
//
// PCD Token 128 - Chassis Serial Number
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (128, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[12], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[12], PcdStr);
}
//
// PCD Token 129 - Chassis Asset Tag
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (129, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") == 0 &&
StrCmp (SmbiosStrings[12], PcdStr) == 0 &&
(StrLenBytes = 2 * StrLen (PcdStr) + 2) <= 0x8C)
{
StrCpyS (SmbiosStrings[12], PcdStr);
}
//
// PCD Token 188 - Chassis Type: if not 2, save byte from chassis asset tag slot
//
Pcd = GetPcdProtocol ();
if (Pcd->Get8 (188) != 2) {
Pcd = GetPcdProtocol ();
SmbiosStrings[12][280] = Pcd->Get8 (188);
}
//
// Write the variable
//
VarSize = 3657;
Status = gRT->SetVariable (
L"OemSmbiosPcdValue",
&gOemSmbiosPcdValueGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
VarSize,
Buffer
);
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OemSaveSmbiosPcdvalue...End\n"));
return EFI_SUCCESS;
} else {
DEBUG ((DEBUG_INFO, "SetVariable fail %r\n", Status));
return Status;
}
}
//------------------------------------------------------------------------------
// OemRestoreSmbiosPcdvalue -- sub_A70
//
// Reads the OemSmbiosPcdValue variable and restores PCD tokens that still
// contain default ("To be filled by O.E.M.") values.
//------------------------------------------------------------------------------
EFI_STATUS
EFIAPI
OemRestoreSmbiosPcdvalue (
VOID
)
{
EFI_STATUS Status;
UINT8 Buffer[0xE49];
UINTN VarSize;
CHAR16 *PcdStr;
PCD_PROTOCOL *Pcd;
DEBUG ((DEBUG_INFO, "OemRestoreSmbiosPcdvalue...Start\n"));
ZeroMemS (Buffer, sizeof (Buffer));
VarSize = 3657;
Status = gRT->GetVariable (
L"OemSmbiosPcdValue",
&gOemSmbiosPcdValueGuid,
NULL,
&VarSize,
Buffer
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Token 118 - System Manufacturer
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (118, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0 ||
StrCmp (PcdStr, L"SYSTEM_MANUFACTURER") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdSystemManufacturer from FRU, restore it from variable\n"));
VarSize = 2 * StrLen (Buffer) + 2;
PcdGetPtrWrapper (118, &VarSize, Buffer);
gSystemManufacturerRestored = TRUE;
}
//
// Token 117 - System Product Name (offset 0x148 in Buffer = 280 bytes)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (117, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0 ||
StrCmp (PcdStr, L"SYSTEM_PRODUCT_NAME") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdSystemProductName from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0x148)) + 2;
PcdGetPtrWrapper (117, &VarSize, Buffer + 0x148);
gSystemProductNameRestored = TRUE;
}
//
// Token 119 - System Version (offset 0x260)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (119, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0 ||
StrCmp (PcdStr, L"SYSTEM_VERSION") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdSystemVersion from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0x260)) + 2;
PcdGetPtrWrapper (119, &VarSize, Buffer + 0x260);
gSystemVersionRestored = TRUE;
}
//
// Token 120 - System Serial Number (offset 0x378)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (120, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0 ||
StrCmp (PcdStr, L"SYSTEM_SERIAL_NUMBER") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdSystemSerialNumber from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0x378)) + 2;
PcdGetPtrWrapper (120, &VarSize, Buffer + 0x378);
gSystemSerialNumberRestored = TRUE;
}
//
// Token 187 - System UUID (offset 0x490, 16 bytes)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (187, NULL, NULL);
if (CompareGuid (PcdStr, &gOemSmbiosPcdValueGuid) ||
CompareGuid (PcdStr, &gEfiSmbiosProtocolGuid))
{
VarSize = 16;
PcdGetPtrWrapper (187, &VarSize, Buffer + 0x490);
gSystemUuidRestored = TRUE;
}
//
// Token 121 - Base Board Manufacturer (offset 0x4A0)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (121, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdBaseBoardManufacturer from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0x4A0)) + 2;
PcdGetPtrWrapper (121, &VarSize, Buffer + 0x4A0);
gBaseBoardManufacturerRestored = TRUE;
}
//
// Token 122 - Base Board Product Name (offset 0x5B8)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (122, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdBaseBoardProductName from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0x5B8)) + 2;
PcdGetPtrWrapper (122, &VarSize, Buffer + 0x5B8);
gBaseBoardProductNameRestored = TRUE;
}
//
// Token 123 - Base Board Version (offset 0x6D0)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (123, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdBaseBoardVersion from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0x6D0)) + 2;
PcdGetPtrWrapper (123, &VarSize, Buffer + 0x6D0);
gBaseBoardVersionRestored = TRUE;
}
//
// Token 124 - Base Board Serial Number (offset 0x7E8)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (124, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdBaseBoardSerialNumber from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0x7E8)) + 2;
PcdGetPtrWrapper (124, &VarSize, Buffer + 0x7E8);
gBaseBoardSerialNumberRestored = TRUE;
}
//
// Token 125 - Base Board Asset Tag (offset 0x900)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (125, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdBaseBoardAssetTag from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0x900)) + 2;
PcdGetPtrWrapper (125, &VarSize, Buffer + 0x900);
gBaseBoardAssetTagRestored = TRUE;
}
//
// Token 126 - Chassis Manufacturer (offset 0xA18)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (126, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdChassisManufacturer from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0xA18)) + 2;
PcdGetPtrWrapper (126, &VarSize, Buffer + 0xA18);
gChassisManufacturerRestored = TRUE;
}
//
// Token 127 - Chassis Version (offset 0xB30)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (127, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdChassisVersion from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0xB30)) + 2;
PcdGetPtrWrapper (127, &VarSize, Buffer + 0xB30);
gChassisVersionRestored = TRUE;
}
//
// Token 128 - Chassis Serial Number (offset 0xC48)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (128, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdChassisSerialNumber from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0xC48)) + 2;
PcdGetPtrWrapper (128, &VarSize, Buffer + 0xC48);
gChassisSerialNumberRestored = TRUE;
}
//
// Token 129 - Chassis Asset Tag (offset 0xD60)
//
Pcd = GetPcdProtocol ();
PcdStr = (CHAR16 *)Pcd->GetPtr (129, NULL, NULL);
if (StrCmp (PcdStr, L"To be filled by O.E.M. ") != 0)
{
DEBUG ((DEBUG_INFO, "fail to get PcdChassisAssetTag from FRU, restore it from variable\n"));
VarSize = 2 * StrLen ((CHAR16 *)(Buffer + 0xD60)) + 2;
PcdGetPtrWrapper (129, &VarSize, Buffer + 0xD60);
gChassisAssetTagRestored = TRUE;
}
//
// Token 188 - Chassis Type: if already 2, skip; otherwise restore from saved byte
//
Pcd = GetPcdProtocol ();
if (Pcd->Get8 (188) == 2) {
DEBUG ((DEBUG_INFO, "fail to get PcdChassisType from FRU, restore it from variable\n"));
Pcd = GetPcdProtocol ();
Pcd->Set8 (188, ((CHAR8 *)Buffer + 0xD60)[280]);
gChassisTypeRestored = TRUE;
}
DEBUG ((DEBUG_INFO, "OemRestoreSmbiosPcdvalue...End\n"));
return EFI_SUCCESS;
}
//------------------------------------------------------------------------------
// OemRestoreSmbiosString -- sub_1138
//
// Applies restored PCD values into the SMBIOS table via EFI_SMBIOS_PROTOCOL.
// For each type (1=System, 2=BaseBoard, 3=Chassis), if the corresponding
// restore flag is set, writes the string into the SMBIOS record.
//------------------------------------------------------------------------------
EFI_STATUS
EFIAPI
OemRestoreSmbiosString (
VOID
)
{
EFI_STATUS Status;
UINT8 Buffer[0xE49];
UINTN VarSize;
EFI_SMBIOS_PROTOCOL *Smbios;
EFI_SMBIOS_HANDLE SmbiosHandle;
UINTN RecordOffset;
CHAR8 Type1Buffer[144];
CHAR16 ThinkSystemPrefix[72];
UINT8 TargetType;
UINT16 TargetHandle;
UINT8 NvData;
DEBUG ((DEBUG_INFO, "OemRestoreSmbiosString...Start\n"));
//
// 1. Read the saved variable
//
VarSize = 3657;
Status = gRT->GetVariable (
L"OemSmbiosPcdValue",
&gOemSmbiosPcdValueGuid,
NULL,
&VarSize,
Buffer
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "GetVariable gOemSmbiosPcdValueGuid fail (%r)\n", Status));
return Status;
}
//
// 2. Locate the SMBIOS protocol
//
Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "LocateProtocol gEfiSmbiosProtocolGuid fail (%r)\n", Status));
return Status;
}
//
// 3. Type 1 (System Information)
//
TargetType = 1;
TargetHandle = 0xFFFE; // UNI_BIOS_SPECIFICATION handle
if (Smbios->GetNext (Smbios, &TargetHandle, &TargetType, &SmbiosHandle, NULL) >= 0) {
RecordOffset = (UINTN)SmbiosHandle;
if (gSystemManufacturerRestored) {
UnicodeStrToAsciiStrS (Buffer, Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gSystemProductNameRestored) {
//
// Read CMOS to check if this is a ThinkSystem platform
//
IoWrite8 (0x72, 0x5C);
NvData = IoRead8 (0x73);
if (NvData == 16) {
// Prepend "ThinkSystem " prefix
StrCpyS (ThinkSystemPrefix, L"ThinkSystem ");
StrCpyS (&ThinkSystemPrefix[StrLen (ThinkSystemPrefix)], (CHAR16 *)(Buffer + 0x148));
UnicodeStrToAsciiStrS (ThinkSystemPrefix, Type1Buffer);
} else {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0x148), Type1Buffer);
}
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gSystemVersionRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0x260), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gSystemSerialNumberRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0x378), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
//
// System UUID: read from saved 16-byte UUID in buffer (offset 0x490)
//
if (gSystemUuidRestored) {
CopyMemS ((VOID *)(RecordOffset + 8), (VOID *)(Buffer + 0x490), 16);
}
}
//
// 4. Type 2 (Base Board Information)
//
TargetType = 2;
TargetHandle = 0xFFFE;
if (Smbios->GetNext (Smbios, &TargetHandle, &TargetType, &SmbiosHandle, NULL) >= 0) {
RecordOffset = (UINTN)SmbiosHandle;
if (gBaseBoardManufacturerRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0x4A0), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gBaseBoardProductNameRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0x5B8), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gBaseBoardVersionRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0x6D0), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gBaseBoardSerialNumberRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0x7E8), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gBaseBoardAssetTagRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0x900), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
}
//
// 5. Type 3 (Chassis Information)
//
TargetType = 3;
TargetHandle = 0xFFFE;
if (Smbios->GetNext (Smbios, &TargetHandle, &TargetType, &SmbiosHandle, NULL) >= 0) {
RecordOffset = (UINTN)SmbiosHandle;
if (gChassisManufacturerRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0xA18), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gChassisVersionRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0xB30), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gChassisSerialNumberRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0xC48), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
if (gChassisAssetTagRestored) {
UnicodeStrToAsciiStrS ((CHAR16 *)(Buffer + 0xD60), Type1Buffer);
Smbios->Add (Smbios, NULL, &TargetHandle, Type1Buffer);
}
//
// Chassis type byte at buffer+0xD60+280 (= offset 0xE78 from buffer start)
//
if (gChassisTypeRestored) {
*(UINT8 *)(RecordOffset + 5) = ((CHAR8 *)Buffer + 0xD60)[280];
}
}
DEBUG ((DEBUG_INFO, "OemRestoreSmbiosString...End\n"));
return EFI_SUCCESS;
}
//------------------------------------------------------------------------------
// OemSaveSmbiosDxeEntryPoint -- _ModuleEntryPoint
//
// Driver entry point. Initializes globals, then calls the three main
// routines in order: OemRestoreSmbiosPcdvalue, OemSaveSmbiosPcdvalue,
// OemRestoreSmbiosString.
//------------------------------------------------------------------------------
EFI_STATUS
EFIAPI
OemSaveSmbiosDxeEntryPoint (
VOID
)
{
//
// Initialize HOB list
//
GetHobList ();
DEBUG ((DEBUG_INFO, "OemSaveSmbiosDxeEntry...Start\n"));
OemRestoreSmbiosPcdvalue ();
OemSaveSmbiosPcdvalue ();
OemRestoreSmbiosString ();
DEBUG ((DEBUG_INFO, "OemSaveSmbiosDxeEntry...End\n"));
return EFI_SUCCESS;
}
//------------------------------------------------------------------------------
// ModuleEntryPoint -- _ModuleEntryPoint
//
// Standard UEFI DXE driver entry.
//------------------------------------------------------------------------------
EFI_STATUS
EFIAPI
OemSaveSmbiosDxeEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
gImageHandle = ImageHandle;
ASSERT (ImageHandle != NULL);
gST = SystemTable;
ASSERT (SystemTable != NULL);
gBS = SystemTable->BootServices;
ASSERT (gBS != NULL);
gRT = SystemTable->RuntimeServices;
ASSERT (gRT != NULL);
return OemSaveSmbiosDxeEntryPoint ();
}