Newer
Older
AMI-Aptio-BIOS-Reversed / OemSaveSmbiosDxe / OemSaveSmbiosDxe.c
@Ajax Dong Ajax Dong 2 days ago 32 KB Init
/**
 * 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 ();
}