/** @file
  SMBIOS Data Update DXE driver - Lightning Ridge EXRP platform variant.

  This DXE driver is part of the UBA (Universal BIOS Architecture) framework.
  It provides SMBIOS data updates for the Lightning Ridge EXRP platform.

  The driver flow:
    1. Initialize UEFI service table pointers and locate HII/SMBIOS protocols
       (SmbiosDataUpdateInit).
    2. Open the UBA config protocol, read the board-specific SMBIOS config GUID
       (SmbiosDataUpdateEntry).
    3. Register the board's HII string package (RegisterHiiPackageList).
    4. Call UBA SMBIOS Data protocol's SetSmbiosData with the config GUID.
    5. The registered callback (SmbiosDataUpdateDispatch) iterates through
       SMBIOS Type 2 (30 fields), Type 9 (8 fields), and Type 41 (4 fields)
       string descriptors, reads localized strings via HII Font protocol, and
       writes them into the SMBIOS tables.

  Build path (from PDB strings):
    e:\hs\Build\HR6N0XMLK\DEBUG_VS2015\X64\PurleyRpPkg\Uba\UbaMain\Dxe\
    TypeLightningRidgeEXRP\SmbiosDataUpdateDxe\SmbiosDataUpdateDxe\DEBUG\
    AutoGen.c

  Copyright (c) Intel Corporation. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "SmbiosDataUpdateDxeLightningRidgeEXRP.h"

//
// Global UEFI system table pointers (initialized by SmbiosDataUpdateInit)
//
EFI_HANDLE               gImageHandle = NULL;        ///< 0x3928 - EFI image handle
EFI_SYSTEM_TABLE         *gSystemTable = NULL;       ///< 0x3918 - EFI system table
EFI_BOOT_SERVICES        *gBootServices = NULL;      ///< 0x3920 - EFI boot services table
EFI_RUNTIME_SERVICES     *gRuntimeServices = NULL;   ///< 0x3930 - EFI runtime services table

//
// Cached protocol/state pointers
//
VOID                     *mDebugProtocol = NULL;          ///< 0x3938 - Cached DebugLib protocol
VOID                     *mHobList = NULL;                ///< 0x3940 - Cached HOB list pointer
VOID                     *mHiiFont = NULL;                ///< 0x3948 - HII Font protocol
VOID                     *mHiiDatabase = NULL;            ///< 0x3950 - HII Database protocol handle
VOID                     *mHiiPackageList = NULL;         ///< 0x3958 - HII Package List protocol handle
VOID                     *mHiiString = NULL;              ///< 0x3960 - HII String protocol handle
VOID                     *mHiiPackageListProtocol = NULL; ///< 0x3968 - HII Package List protocol interface
VOID                     *mSmbiosProtocol1 = NULL;        ///< 0x3978 - SMBIOS protocol (string add)
VOID                     *mUbaSmbiosDataProtocol = NULL;  ///< 0x3980 - UBA SMBIOS Data protocol
VOID                     *mSmbiosProtocol2 = NULL;        ///< 0x3988 - SMBIOS protocol (string remove)
VOID                     *mSmbiosProtocol3 = NULL;        ///< 0x3990 - SMBIOS protocol (string add)
VOID                     *mSmbiosProtocol4 = NULL;        ///< 0x3998 - SMBIOS protocol (remove+add)
VOID                     *mMmPciUsra = NULL;              ///< 0x39A0 - MM PCIe base protocol

//
// Global state
//
EFI_GUID                 mSmbiosConfigGuid;           ///< 0x38F0 - Board-specific SMBIOS config GUID
EFI_HII_HANDLE           gSmbiosStringPackHandle = NULL; ///< 0x3910 - HII handle for SMBIOS strings
UINT64                   mPcdMaximumAsciiStringLength = MAX_ASCII_STRING_LENGTH; ///< Pcd for string length checks

// ===========================================================================
// GUID Definitions (protocol and config identifiers)
// ===========================================================================

///
/// GUID for the UBA config protocol opened from ImageHandle.
/// Contains board-specific SMBIOS configuration data.
///
static EFI_GUID mUbaConfigProtocolGuid = {
  0x36232936, 0x0E76, 0x31C8, { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 }
};

///
/// GUID for "en-US" default language (RFC 4646).
/// Used as default platform language when PlatformLang variable is not set.
///
static UINT16 mDefaultLanguage[] = L"en-US";

///
/// HOB list GUID for configuration table lookup.
///
static EFI_GUID mHobListGuid = {
  0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }
};

///
/// DXE Services Table GUID.
///
static EFI_GUID mDxeServicesTableGuid = {
  0x5AD34BA, 0x6B02, 0x4214, { 0xA2, 0xE5, 0x22, 0x8B, 0xE4, 0xE3, 0x89, 0x1C }
};

///
/// Global Variable GUID for UEFI standard variables (PlatformLang).
///
static EFI_GUID mGlobalVariableGuid = {
  0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }
};

///
/// DebugLib protocol GUID.
///
static EFI_GUID mDebugLibProtocolGuid = {
  0xE0D4DF48, 0xCB79, 0x4B33, { 0x95, 0x68, 0x20, 0xE8, 0xAA, 0xA1, 0xEC, 0x47 }
};

///
/// HII Font protocol GUID.
///
static EFI_GUID mHiiFontProtocolGuid = {
  0xE93CE36F, 0xAE91, 0x41CD, { 0xB7, 0xE9, 0x1D, 0xBF, 0x42, 0x56, 0xE4, 0x8E }
};

///
/// HII Database protocol GUID.
///
static EFI_GUID mHiiDatabaseProtocolGuid = {
  0xEF9FC172, 0xA1B2, 0x4693, { 0xB3, 0x27, 0x6D, 0x5F, 0xC4, 0x16, 0x42, 0x54 }
};

///
/// HII Package List protocol GUID.
///
static EFI_GUID mHiiPackageListProtocolGuid = {
  0x6B78D9C4, 0xE4B5, 0x43B9, { 0xB6, 0x5A, 0xCA, 0x93, 0xA2, 0x3A, 0xD7, 0x8D }
};

///
/// HII String protocol GUID.
///
static EFI_GUID mHiiStringProtocolGuid = {
  0xFD96974E, 0x23AA, 0x4CDC, { 0xB9, 0xCB, 0x98, 0xD1, 0x77, 0x50, 0x32, 0x2A }
};

///
/// SMBIOS protocol GUID.
///
static EFI_GUID mSmbiosProtocolGuid = {
  0x0358FF4A, 0xCB6B, 0x4A4B, { 0x87, 0xEC, 0x88, 0x1A, 0x9D, 0xEB, 0x2D, 0xD8 }
};

///
/// MM PCIe Base protocol GUID.
///
static EFI_GUID mMmPciBaseProtocolGuid = {
  0x2F34E1F8, 0x6BF6, 0x4C3E, { 0xBD, 0x34, 0x04, 0x67, 0x1A, 0x0B, 0x55, 0xFE }
};

///
/// UBA SMBIOS Data protocol GUID.
/// This protocol is used to register SMBIOS data update configuration.
///
static EFI_GUID mUbaSmbiosDataProtocolGuid = {
  0x36232936, 0x0E76, 0x31C8, { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 }
};

///
/// SMBIOS string package GUID for HII registration.
/// Identifies this driver's HII string package for SMBIOS strings.
///
static EFI_GUID mSmbiosStringPackageGuid = {
  0x36232936, 0x0E76, 0x31C8, { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 }
};

// ===========================================================================
// SMBIOS String Descriptor Table
// ===========================================================================

///
/// SMBIOS Type 2 (Baseboard) string descriptor table (30 entries).
/// Each entry is 10 bytes: {Type, FieldNum, StringId(16), Encoding, Offset, MaxLen, Flags, Reserved(16)}
///
/// These descriptors define which SMBIOS Type 2 string fields to update and
/// which HII string tokens to use for localized string lookup.
///
/// SMBIOS Type 2 fields: Manufacturer, ProductName, Version, SerialNumber,
/// AssetTag, LocationInChassis, ChassisLocation, etc.
///
static CONST SMBIOS_STRING_DESC mSmbiosType2Descriptors[30] = {
  //
  // Entry 0:  Type=8 (Type2), Field=3, StrId=0x0002, Enc=0x08, Off=8, Max=3, Flag=0x08000000
  //
  { 8, 3, 0x0002, 0x08, 8, 3, 0, {0} },

  //
  // Entry 1:  Type=8 (Type2), Field=4, StrId=0x04, Enc=0x10, Off=8, Max=16, Flag=5
  //
  { 8, 4, 0x0004, 0x10, 8, 16, 5, {0} },

  //
  // Entries 2-29 follow the same pattern with different field numbers,
  // string IDs, encodings, offsets, max lengths, and flags.
  //
  // Full descriptor table details available in the disassembly at sub_77C.
  // The table is a 300-byte (30 * 10) embedded constant array.
  // Key field numbers: 5 (Manufacturer), 6 (ProductName), 7 (Version),
  // 8 (SerialNumber), 9 (AssetTag), 10-29 (additional board strings).
  //
};

// ===========================================================================
// Forward Declarations of Internal Functions
// ===========================================================================

UINT64
ReadUnaligned64 (
  IN CONST VOID  *Buffer
  );

UINT64
WriteUnaligned64 (
  OUT VOID    *Dst,
  IN  UINT64  Value
  );

// ===========================================================================
// Low-Level Memory Helpers
// ===========================================================================

/**
  Fast zero-memory implementation.

  Zeros memory in 8-byte aligned chunks, then handles remaining bytes.
  This is an optimized memset variant from UEFI BaseMemoryLib.

  @param[out] Buffer  Pointer to the buffer to zero.
  @param[in]  Length  Number of bytes to zero.

  @return Pointer to the buffer.
**/
STATIC
VOID *
ZeroMemBase (
  OUT VOID    *Buffer,
  IN  UINTN   Length
  )
{
  CHAR8  *Buf;

  Buf = (CHAR8 *)Buffer;

  //
  // Zero 8-byte aligned chunks first.
  //
  SetMem (Buf, Length & ~7, 0);

  //
  // Zero remaining bytes (0-7).
  //
  SetMem (&Buf[Length & ~7], Length & 7, 0);

  return Buffer;
}

/**
  Fast copy-memory implementation with overlap handling.

  Copies memory in 8-byte aligned chunks if source and destination do not
  overlap. If source < destination and they overlap, copies backward from the
  end. If they do not overlap, copies forward in 8-byte chunks.

  @param[out] Destination  Pointer to the destination buffer.
  @param[in]  Source       Pointer to the source buffer.
  @param[in]  Length       Number of bytes to copy.

  @return Pointer to the destination buffer.
**/
STATIC
VOID *
CopyMemBase (
  OUT VOID       *Destination,
  IN  CONST VOID *Source,
  IN  UINTN      Length
  )
{
  CHAR8  *Dst;
  CONST CHAR8  *Src;
  UINTN  CountQwords;
  UINTN  CountRemaining;

  Dst = (CHAR8 *)Destination;
  Src = (CONST CHAR8 *)Source;

  if (Src < Dst && &Src[Length - 1] >= Dst) {
    //
    // Overlapping: source ends after destination starts.
    // Copy backwards from the end to avoid corruption.
    //
    Src = &Src[Length - 1];
    Dst = &Dst[Length - 1];
    CopyMem (Dst, Src, Length & 7);

    // Copy remaining 8-byte chunks backward
  } else {
    //
    // No overlap or destination before source: copy forward.
    //
    CountQwords = Length >> 3;
    CountRemaining = Length & 7;

    //
    // Copy 8-byte aligned chunks.
    //
    CopyMem (Dst, Src, CountQwords * 8);

    Dst = &Dst[CountQwords * 8];
    Src = &Src[CountQwords * 8];
  }

  //
  // Copy remaining bytes.
  //
  CopyMem (Dst, Src, CountRemaining);

  return Destination;
}

// ===========================================================================
// Memory and String Library Functions
// ===========================================================================

/**
  Zeros a memory buffer with assertion on invalid parameters.

  @param[in] Buffer  Pointer to the buffer to zero.
  @param[in] Length  Number of bytes to zero.

  @return Pointer to the buffer.
**/
VOID *
ZeroMem (
  IN VOID    *Buffer,
  IN UINTN   Length
  )
{
  if (Length == 0) {
    return Buffer;
  }

  if (Buffer == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
      53,
      "Buffer != ((void *) 0)"
      );
  }

  if (Length > (UINTN)~Buffer) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
      54,
      "Length <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)Buffer + 1)"
      );
  }

  return ZeroMemBase (Buffer, Length);
}

/**
  Copies memory with assertion on invalid parameters.

  @param[out] Destination  Pointer to the destination buffer.
  @param[in]  Source       Pointer to the source buffer.
  @param[in]  Length       Number of bytes to copy. If 0, returns Destination.

  @return Pointer to the destination buffer.
**/
VOID *
CopyMem (
  OUT VOID       *Destination,
  IN  CONST VOID *Source,
  IN  UINTN      Length
  )
{
  if (Length == 0) {
    return Destination;
  }

  if ((Length - 1) > (UINTN)~Destination) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
      56,
      "(Length - 1) <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)DestinationBuffer)"
      );
  }

  if ((Length - 1) > (UINTN)~Source) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
      57,
      "(Length - 1) <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)SourceBuffer)"
      );
  }

  if (Destination == Source) {
    return Destination;
  }

  return CopyMemBase (Destination, Source, Length);
}

/**
  Returns the length of an ASCII string (not including null terminator).

  Scans the string until a null byte is found, up to MAX_ASCII_STRING_LENGTH.
  Asserts if the string exceeds the maximum length.

  @param[in] String  Pointer to the ASCII string.

  @return Length of the string in characters.
**/
UINTN
AsciiStrLen (
  IN CONST CHAR8  *String
  )
{
  CONST CHAR8  *Scan;
  UINTN        Length;

  if (String == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
      1082,
      "String != ((void *) 0)"
      );
  }

  Scan = String;
  Length = 0;
  while (*Scan != '\0') {
    if (Length >= MAX_ASCII_STRING_LENGTH) {
      AssertHandler (
        "e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
        1090,
        "Length < _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength"
        );
    }
    Scan++;
    Length++;
  }

  return Length;
}

/**
  Compares two ASCII strings up to n characters.

  @param[in] FirstString   Pointer to the first ASCII string.
  @param[in] SecondString  Pointer to the second ASCII string.
  @param[in] Length        Maximum number of characters to compare.

  @return 0 if equal, negative if First < Second, positive if First > Second.
**/
INTN
AsciiStrnCmp (
  IN CONST CHAR8  *FirstString,
  IN CONST CHAR8  *SecondString,
  IN UINTN        Length
  )
{
  CONST CHAR8  *First;
  CONST CHAR8  *Second;
  UINTN        Count;

  First = FirstString;
  Second = SecondString;
  Count = Length;

  if (Count == 0) {
    return 0;
  }

  if (AsciiStrLen (FirstString) == (UINTN)-1) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
      1320,
      "AsciiStrSize (FirstString)"
      );
  }

  if (AsciiStrLen (SecondString) == (UINTN)-1) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
      1321,
      "AsciiStrSize (SecondString)"
      );
  }

  if (Count > MAX_ASCII_STRING_LENGTH) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
      1324,
      "Length <= _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength"
      );
  }

  while (*First != '\0' && *Second != '\0' && *First == *Second && Count > 1) {
    First++;
    Second++;
    Count--;
  }

  return (INTN)((UINT8)*First - (UINT8)*Second);
}

/**
  Returns the length of a UCS-2 string (max 0xF4240).

  @param[in] String  Pointer to the UCS-2 string.

  @return Length in characters, 0 if NULL or empty.
**/
UINTN
StrLen (
  IN CONST UINT16  *String
  )
{
  CONST UINT16  *Scan;
  UINTN         Length;

  if (((UINTN)String & 1) != 0) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
      128,
      "((UINTN) String & 0x00000001) == 0"
      );
  }

  if (String == NULL || MAX_ASCII_STRING_LENGTH == 0) {
    return 0;
  }

  Scan = String;
  Length = 0;
  if (*Scan != 0) {
    while (Length < MAX_ASCII_STRING_LENGTH - 1) {
      if (Scan[++Length] == 0) {
        return Length;
      }
    }
    return MAX_ASCII_STRING_LENGTH;
  }

  return Length;
}

/**
  Safe ASCII string length (bounded by MaxLength).

  @param[in] String     Pointer to the ASCII string.
  @param[in] MaxLength  Maximum length to check.

  @return Length of the string, or MaxLength if longer.
**/
UINTN
AsciiStrnLenS (
  IN CONST CHAR8  *String,
  IN UINTN        MaxLength
  )
{
  CONST CHAR8  *Scan;
  UINTN        Length;

  if (String == NULL || MaxLength == 0) {
    return 0;
  }

  Scan = String;
  Length = 0;
  if (*Scan != '\0') {
    while (Length < MaxLength - 1) {
      if (Scan[++Length] == '\0') {
        return Length;
      }
    }
    return MaxLength;
  }

  return Length;
}

/**
  Converts a UCS-2 string to an ASCII string with overlap-safe handling.

  Validates all parameters, checks for buffer overlap, and converts each
  UCS-2 character (must be < 0x100) to an ASCII byte.

  @param[out] Destination  Destination ASCII buffer.
  @param[in]  Source       Source UCS-2 string.
  @param[in]  DestMax      Maximum characters in destination (including null).

  @retval EFI_SUCCESS           Conversion successful.
  @retval EFI_INVALID_PARAMETER NULL parameter.
  @retval EFI_BAD_BUFFER_SIZE   DestMax exceeds maximum.
  @retval EFI_BUFFER_TOO_SMALL  DestMax <= SourceLen.
**/
EFI_STATUS
UnicodeStrnToAsciiStrS (
  OUT CHAR8        *Destination,
  IN  CONST UINT16 *Source,
  IN  UINTN        DestMax
  )
{
  CONST UINT16  *Src;
  CHAR8         *Dst;
  UINTN         SourceLen;
  BOOLEAN       Overlap;

  Src = Source;
  Dst = Destination;

  if (((UINTN)Source & 1) != 0) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
      2677,
      "((UINTN) Source & 0x00000001) == 0"
      );
  }

  if (Destination == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
      2682,
      "(Destination != ((void *) 0))"
      );
    return EFI_INVALID_PARAMETER;
  }

  if (Source == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
      2683,
      "(Source != ((void *) 0))"
      );
    return EFI_INVALID_PARAMETER;
  }

  if (DestMax > MAX_ASCII_STRING_LENGTH) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
      2689,
      "(DestMax <= (_gPcd_FixedAtBuild_PcdMaximumAsciiStringLength))"
      );
  }

  if (DestMax == 0) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
      2698,
      "(DestMax != 0)"
      );
    return EFI_INVALID_PARAMETER;
  }

  SourceLen = StrLen (Src);
  if (DestMax <= SourceLen) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
      2704,
      "(DestMax > SourceLen)"
      );
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Check for overlap between source and destination buffers.
  //
  Overlap = FALSE;
  if ((UINT8 *)Src >= Dst && (UINT8 *)Src < &Dst[DestMax]) {
    Overlap = TRUE;
  } else if (Dst >= (UINT8 *)Src && Dst < (UINT8 *)&Src[SourceLen + 1]) {
    Overlap = TRUE;
  }

  if (Overlap) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
      2709,
      "!InternalSafeStringIsOverlap (Destination, DestMax, (void *)Source, (SourceLen + 1) * sizeof(CHAR16))"
      );
    return EFI_BUFFER_TOO_SMALL; // Overlap error, treated as buffer error
  }

  //
  // Convert each UCS-2 character to ASCII.
  //
  while (*Src != 0) {
    if (*Src >= 0x100) {
      AssertHandler (
        "e:\\hs\\MdePkg\\Library\\BaseLib\\SafeString.c",
        2719,
        "*Source < 0x100"
        );
    }
    *Dst++ = (CHAR8)*Src++;
  }
  *Dst = '\0';

  return EFI_SUCCESS;
}

// ===========================================================================
// GUID Manipulation
// ===========================================================================

/**
  Reads a 32-bit value from potentially unaligned memory.

  @param[in] Buffer  Pointer to the memory to read.

  @return The 32-bit value, or 0 if Buffer is NULL.
**/
UINT32
EFIAPI
ReadUnaligned32 (
  IN CONST VOID  *Buffer
  )
{
  if (Buffer == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
      141,
      "Buffer != ((void *) 0)"
      );
  }

  return *(UINT32 *)Buffer;
}

/**
  Reads a 64-bit value from potentially unaligned memory.

  @param[in] Buffer  Pointer to the memory to read.

  @return The 64-bit value, or 0 if Buffer is NULL.
**/
UINT64
EFIAPI
ReadUnaligned64 (
  IN CONST VOID  *Buffer
  )
{
  if (Buffer == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
      192,
      "Buffer != ((void *) 0)"
      );
  }

  return *(UINT64 *)Buffer;
}

/**
  Writes a 64-bit value to potentially unaligned memory.

  @param[out] Dst    Pointer to the destination memory.
  @param[in]  Value  The 64-bit value to write.

  @return The value written.
**/
UINT64
EFIAPI
WriteUnaligned64 (
  OUT VOID    *Dst,
  IN  UINT64  Value
  )
{
  if (Dst == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
      219,
      "Buffer != ((void *) 0)"
      );
  }

  *(UINT64 *)Dst = Value;
  return Value;
}

/**
  Copies a 16-byte GUID by writing two 64-bit values.

  @param[out] Dst  Pointer to the destination GUID.
  @param[in]  Src  Pointer to the source GUID.

  @return Pointer to the destination GUID.
**/
EFI_GUID *
CopyGuid (
  OUT EFI_GUID  *Dst,
  IN  EFI_GUID  *Src
  )
{
  UINT64  First;
  UINT64  Second;

  First = ReadUnaligned64 (Src);
  WriteUnaligned64 (Dst, First);

  Second = ReadUnaligned64 ((UINT8 *)Src + 8);
  WriteUnaligned64 ((UINT8 *)Dst + 8, Second);

  return Dst;
}

/**
  Compares two GUIDs by comparing them as two 64-bit values.

  @param[in] Guid1  Pointer to the first GUID.
  @param[in] Guid2  Pointer to the second GUID.

  @return TRUE if the GUIDs are identical, FALSE otherwise.
**/
BOOLEAN
EFIAPI
CompareGuid (
  IN EFI_GUID  *Guid1,
  IN EFI_GUID  *Guid2
  )
{
  UINT64  Guid1First;
  UINT64  Guid1Second;
  UINT64  Guid2First;
  UINT64  Guid2Second;

  Guid1First  = ReadUnaligned64 (Guid1);
  Guid1Second = ReadUnaligned64 ((UINT8 *)Guid1 + 8);
  Guid2First  = ReadUnaligned64 (Guid2);
  Guid2Second = ReadUnaligned64 ((UINT8 *)Guid2 + 8);

  return (BOOLEAN)(Guid1First == Guid2First && Guid1Second == Guid2Second);
}

// ===========================================================================
// Memory Allocation
// ===========================================================================

/**
  Allocates boot services data pool memory.

  @param[in] Size  Number of bytes to allocate.

  @return Pointer to the allocated memory, or NULL if allocation failed.
**/
VOID *
AllocatePool (
  IN UINTN  Size
  )
{
  EFI_STATUS  Status;
  VOID        *Buffer;

  //
  // gBS->AllocatePool is at BootServices offset +64 (function index 8).
  // Signature: (EFI_MEMORY_TYPE, UINTN, VOID**)
  //
  Status = gBootServices->AllocatePool (
                            EfiBootServicesData,
                            Size,
                            &Buffer
                            );
  if (EFI_ERROR (Status)) {
    Buffer = NULL;
  }

  return Buffer;
}

/**
  Allocates and zeros pool memory.

  @param[in] Size  Number of bytes to allocate.

  @return Pointer to the allocated zeroed memory, or NULL if allocation failed.
**/
VOID *
AllocateZeroPool (
  IN UINTN  Size
  )
{
  VOID  *Buffer;

  Buffer = AllocatePool (Size);
  if (Buffer != NULL) {
    ZeroMem (Buffer, Size);
  }

  return Buffer;
}

/**
  Frees pool memory allocated by AllocatePool.

  @param[in] Buffer  Pointer to the memory to free.
                     If NULL, the function does nothing.
**/
VOID
FreePool (
  IN VOID  *Buffer
  )
{
  EFI_STATUS  Status;

  //
  // gBS->FreePool is at BootServices offset +72 (function index 9).
  //
  Status = gBootServices->FreePool (Buffer);
  if (EFI_ERROR (Status)) {
    DebugPrint (
      UBA_DEBUG_ERROR,
      "\nASSERT_EFI_ERROR (Status = %r)\n",
      Status
      );
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiMemoryAllocationLib\\MemoryAllocationLib.c",
      819,
      "!EFI_ERROR (Status)"
      );
  }
}

// ===========================================================================
// Configuration Table Access
// ===========================================================================

/**
  Finds a configuration table entry by GUID in the SystemTable.

  Scans SystemTable->ConfigurationTable for a GUID match. The configuration
  table is an array of EFI_CONFIGURATION_TABLE entries, each 24 bytes:
  - 16 bytes: VendorGuid (EFI_GUID)
  - 8 bytes:  VendorTable (VOID*)

  @param[in]  TableGuid  GUID of the configuration table to find.
  @param[out] Table      Returns the pointer to the matching table data.

  @retval EFI_SUCCESS           Table entry found.
  @retval EFI_NOT_FOUND         No matching table entry found.
**/
EFI_STATUS
GetConfigTable (
  IN  EFI_GUID  *TableGuid,
  OUT VOID      **Table
  )
{
  UINTN   Index;
  UINTN   NumEntries;
  EFI_CONFIGURATION_TABLE  *ConfigTable;
  VOID    *FoundTable;

  if (TableGuid == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
      97,
      "TableGuid != ((void *) 0)"
      );
  }

  if (Table == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
      98,
      "Table != ((void *) 0)"
      );
  }

  *Table = NULL;

  NumEntries = gSystemTable->NumberOfTableEntries;
  if (NumEntries == 0) {
    return EFI_NOT_FOUND;
  }

  ConfigTable = gSystemTable->ConfigurationTable;
  FoundTable = NULL;

  for (Index = 0; Index < NumEntries; Index++) {
    //
    // Compare GUIDs using 128-bit comparison.
    //
    if (CompareGuid (&ConfigTable[Index].VendorGuid, TableGuid)) {
      FoundTable = ConfigTable[Index].VendorTable;
      *Table = FoundTable;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

// ===========================================================================
// HOB List Access
// ===========================================================================

/**
  Initializes the HOB list pointer from the SystemTable.

  Finds the HOB list GUID in SystemTable->ConfigurationTable and asserts
  if not found. Caches the HOB list pointer in mHobList global.

  @return Pointer to the HOB list, or NULL if not found.
**/
VOID *
HobLibInit (
  VOID
  )
{
  EFI_STATUS  Status;
  VOID        *HobList;

  //
  // Return cached pointer if already initialized.
  //
  HobList = mHobList;
  if (HobList != NULL) {
    return HobList;
  }

  //
  // Find the HOB list in the configuration table.
  //
  Status = GetConfigTable (&mHobListGuid, &mHobList);
  if (EFI_ERROR (Status)) {
    DebugPrint (
      UBA_DEBUG_ERROR,
      "\nASSERT_EFI_ERROR (Status = %r)\n",
      Status
      );
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
      54,
      "!EFI_ERROR (Status)"
      );
  }

  //
  // Verify the HOB list was found.
  //
  if (mHobList == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
      55,
      "mHobList != ((void *) 0)"
      );
  }

  return mHobList;
}

// ===========================================================================
// Language and Variable Services
// ===========================================================================

/**
  Gets the platform language string from UEFI global variable.

  Reads the "PlatformLang" UEFI variable via RuntimeServices->GetVariable.
  The variable is identified by gEfiGlobalVariableGuid.
  Returns a buffer containing the current platform language code (e.g., "en-US").

  @param[out] Value  Returns a pointer to the allocated language string buffer.
                     Caller must free with FreePool().

  @retval EFI_SUCCESS           Language string retrieved successfully.
  @retval EFI_NOT_FOUND         "PlatformLang" variable does not exist.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
**/
EFI_STATUS
GetPlatformLang (
  OUT CHAR8  **Value
  )
{
  EFI_STATUS  Status;
  UINTN       BufferSize;
  CHAR8       *LangBuffer;

  if (Value == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
      1401,
      "Name != ((void *) 0) && Guid != ((void *) 0) && Value != ((void *) 0)"
      );
  }

  *Value = NULL;
  BufferSize = 0;

  //
  // Call GetVariable with zero size first to get required buffer size.
  // gRT->GetVariable is at RuntimeServices offset +72 (function index 9).
  //
  Status = gRuntimeServices->GetVariable (
                               L"PlatformLang",
                               &mGlobalVariableGuid,
                               NULL,
                               &BufferSize,
                               NULL
                               );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    //
    // Allocate buffer of required size.
    //
    LangBuffer = AllocatePool (BufferSize);
    if (LangBuffer == NULL) {
      AssertHandler (
        "e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
        1421,
        "*Value != ((void *) 0)"
        );
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Read the variable data.
    //
    Status = gRuntimeServices->GetVariable (
                                 L"PlatformLang",
                                 &mGlobalVariableGuid,
                                 NULL,
                                 &BufferSize,
                                 LangBuffer
                                 );
    if (EFI_ERROR (Status)) {
      FreePool (LangBuffer);
      *Value = NULL;
    } else {
      *Value = LangBuffer;
      return EFI_SUCCESS;
    }
  }

  return Status;
}

/**
  Matches a supported language against a list of available languages.

  Parses the ASCII semicolon-separated language list and checks if any
  of the provided language strings match a language in the supported list.
  Supports ISO 639-2 3-letter codes and RFC 4646 language tags.

  @param[in] SupportedLanguages  Semicolon-separated list of supported languages.
  @param[in] LanguageMatch       0 (not used in this variant) or non-zero.
  @param[in] ...                 Variable argument list of language strings
                                 to check against the supported list.

  @return Pointer to an allocated buffer containing the matched language,
          or NULL if no match found or on error.
**/
CHAR8 *
EFIAPI
GetSupportedLanguage (
  IN CONST CHAR8  *SupportedLanguages,
  IN CHAR8        LanguageMatch,
  ...
  )
{
  VA_LIST     Args;
  CONST CHAR8 *LangToCheck;
  CONST CHAR8 *Supported;
  UINTN       SupportedLen;
  UINTN       CheckLen;
  CHAR8       *ResultBuffer;
  UINTN       ResultLen;

  if (SupportedLanguages == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
      1528,
      "SupportedLanguages != ((void *) 0)"
      );
  }

  VA_START (Args, LanguageMatch);
  LangToCheck = VA_ARG (Args, CONST CHAR8 *);

  if (LangToCheck != NULL) {
    VA_COPY (Args, Args);

    while (LangToCheck != NULL) {
      //
      // Determine the length of the language to check.
      // If full match mode (LanguageMatch != 0) is disabled (0),
      // use the full string; otherwise truncate to 3 characters.
      //
      if (LanguageMatch == 0) {
        CheckLen = AsciiStrLen (LangToCheck);
        if (CheckLen <= 3) {
          SupportedLen = CheckLen;
        } else {
          SupportedLen = 3;
        }
      } else {
        //
        // Full match: use the complete string length, but truncated
        // to 3 chars if zero mode is off and string is long.
        //
        SupportedLen = 0;
        if (*LangToCheck != '\0') {
          CheckLen = 0;
          while (LangToCheck[CheckLen] != ';' && LangToCheck[CheckLen] != '\0') {
            CheckLen++;
          }
          SupportedLen = CheckLen;
        }
      }

      //
      // Scan the supported languages string for a match.
      //
      if (LanguageMatch != 0) {
        //
        // Full match mode: iterate through each language list entry.
        //
        Supported = SupportedLanguages;
        while (*Supported != '\0') {
          //
          // Skip ';' separators.
          //
          while (*Supported == ';') {
            Supported++;
          }

          //
          // Get the length of this supported language entry.
          //
          SupportedLen = 0;
          while (Supported[SupportedLen] != '\0' && Supported[SupportedLen] != ';') {
            SupportedLen++;
          }

          if (CheckLen <= SupportedLen) {
            if (AsciiStrnCmp (Supported, LangToCheck, CheckLen) == 0) {
              //
              // Match found - allocate buffer and copy the language.
              //
              ResultLen = SupportedLen + 1;
              ResultBuffer = AllocateZeroPool (ResultLen);
              if (ResultBuffer != NULL) {
                return CopyMem (ResultBuffer, LangToCheck, ResultLen);
              }
              return NULL;
            }
          }

          Supported += SupportedLen;
        }
      } else {
        //
        // Short match mode: truncate language to 3 characters, compare.
        //
        if (CheckLen <= 3) {
          SupportedLen = CheckLen;
        } else {
          SupportedLen = 3;
        }

        //
        // Scan supported languages.
        //
        Supported = SupportedLanguages;
        while (*Supported != '\0') {
          //
          // Skip ';' separators.
          //
          while (*Supported == ';') {
            Supported++;
          }

          SupportedLen = 0;
          while (Supported[SupportedLen] != '\0' && Supported[SupportedLen] != ';') {
            SupportedLen++;
          }

          if (CheckLen <= SupportedLen) {
            if (AsciiStrnCmp (Supported, LangToCheck, CheckLen) == 0) {
              ResultLen = SupportedLen + 1;
              ResultBuffer = AllocateZeroPool (ResultLen);
              if (ResultBuffer != NULL) {
                return CopyMem (ResultBuffer, LangToCheck, ResultLen);
              }
              return NULL;
            }
          }

          //
          // If full check fails, try truncating to 3 chars.
          //
          if (CheckLen > 3 && 3 <= SupportedLen) {
            if (AsciiStrnCmp (Supported, LangToCheck, 3) == 0) {
              ResultLen = SupportedLen + 1;
              ResultBuffer = AllocateZeroPool (ResultLen);
              if (ResultBuffer != NULL) {
                return CopyMem (ResultBuffer, LangToCheck, ResultLen);
              }
              return NULL;
            }
          }

          //
          // Handle RFC 4646 language tags with '-' separator.
          //
          while (Supported[SupportedLen] == '-') {
            Supported[SupportedLen] = '\0';
          }

          Supported += SupportedLen;
        }
      }

      //
      // Move to next language string in varargs.
      //
      LangToCheck = VA_ARG (Args, CONST CHAR8 *);
    }
  }

  VA_END (Args);

  return NULL;
}

// ===========================================================================
// Debug Output
// ===========================================================================

/**
  Gets the DebugLib protocol instance.

  Allocates pool memory then locates the DebugLib protocol by GUID.
  If the pool allocation returns a suspiciously small value (<= 0x10),
  the protocol is not looked up.

  Note: The pool allocation size is hardcoded as 31 (MEMORY_TYPE_BOOT_SERVICES_DATA).
  The allocated pointer is used to check if the allocation succeeded by comparing
  its value to 0x10. This is a heuristic: if the pointer value is > 0x10, the
  allocation is considered valid.

  @return Pointer to the DebugLib protocol interface, or NULL if not found.
**/
VOID *
GetDebugLibProtocol (
  VOID
  )
{
  VOID        *DebugProtocol;
  UINTN       PoolSize;
  EFI_STATUS  Status;

  //
  // Return cached pointer if already initialized.
  //
  DebugProtocol = mDebugProtocol;
  if (DebugProtocol != NULL) {
    return DebugProtocol;
  }

  //
  // Allocate pool as a probe. The allocation size is 31 bytes
  // (MEMORY_TYPE_BOOT_SERVICES_DATA).
  //
  PoolSize = MEMORY_TYPE_BOOT_SERVICES_DATA;
  mDebugProtocol = gBootServices->AllocatePool (EfiBootServicesData, POOL_ALLOC_SIZE);

  //
  // Heuristic: if the returned pointer is > 16, treat it as a valid allocation.
  // This is a non-standard check unique to this implementation.
  //
  if ((UINTN)mDebugProtocol > 0x10) {
    //
    // gBS->LocateProtocol is at BootServices offset +320 (function index 41).
    //
    Status = gBootServices->LocateProtocol (
                              &mDebugLibProtocolGuid,
                              NULL,
                              &mDebugProtocol
                              );
    if (EFI_ERROR (Status)) {
      mDebugProtocol = NULL;
    }
  } else {
    //
    // Suspicious allocation pointer - treat as failure.
    //
    mDebugProtocol = NULL;
  }

  return mDebugProtocol;
}

/**
  Platform-aware debug print function.

  Writes a formatted debug message through the DebugLib protocol.
  Checks the CMOS RTC register 0x4B to determine the platform SKU and
  filters debug output accordingly. Only Type 1 platforms (CMOS SKU = 1)
  get info-level debug messages; all others get only error-level messages.

  Note: The RTC CMOS register 0x4B at port 0x70/0x71 is used as a non-volatile
  platform SKU indicator. A memory-mapped I/O register at 0xFDAF0490 bit 1
  serves as a fallback when the CMOS value is 0.

  @param[in] DebugLevel    Debug message level (e.g., UBA_DEBUG_ERROR).
  @param[in] FormatString  Format string for the debug message.
  @param[in] ...           Variable arguments for the format string.
**/
VOID
EFIAPI
DebugPrint (
  IN UINTN       DebugLevel,
  IN CONST CHAR8 *FormatString,
  ...
  )
{
  VA_LIST          VaList;
  UINT64           FilterMask;
  VOID             *DebugProtocol;
  UINT8            CmosSku;
  UINT8            PlatformInfo;
  UINT8            EffectiveSku;

  VA_START (VaList, FormatString);

  //
  // Get the DebugLib protocol; if not available, skip the print.
  //
  DebugProtocol = GetDebugLibProtocol ();
  if (DebugProtocol == NULL) {
    VA_END (VaList);
    return;
  }

  //
  // Read the platform SKU from RTC CMOS register 0x4B.
  // The NMI-disable bit (0x80) is preserved in the index write.
  //
  IoWrite8 (RTC_CMOS_INDEX_PORT, (IoRead8 (RTC_CMOS_INDEX_PORT) & 0x80) | RTC_CMOS_INDEX_SKU);
  CmosSku = IoRead8 (RTC_CMOS_DATA_PORT);

  //
  // Determine effective SKU:
  // - If raw CMOS value > 3 and == 0, read platform info register.
  // - CMOS value of 1 = Platform Type 1 (get info-level debug).
  //
  EffectiveSku = CmosSku;
  if (CmosSku > 3) {
    if (CmosSku == 0) {
      //
      // Read platform info register for IIO mode detection.
      // Bit 1 of 0xFDAF0490 indicates IIO configuration mode.
      //
      EffectiveSku = (*(volatile UINT8 *)PLATFORM_INFO_REGISTER & 0x02) | 0x01;
    }
  }

  //
  // Map platform SKU to debug level filter mask.
  //
  EffectiveSku--;
  if (EffectiveSku <= 0xFD) {
    //
    // Valid SKU range (1-4 maps to 0-3).
    //
    FilterMask = UBA_DEBUG_ERROR;   // Default: only errors
    if (CmosSku == 1) {
      FilterMask = UBA_DEBUG_INFO;  // Type1: allow info-level messages
    }
  } else {
    FilterMask = UBA_DEBUG_ERROR;
  }

  //
  // If the requested debug level passes the filter, call DebugPrint.
  //
  if ((FilterMask & DebugLevel) != 0) {
    //
    // DebugProtocol layout:
    //   +0: DebugPrint (function pointer)
    //   +8: Assert (function pointer)
    //
    ((DEBUG_PRINT_FUNC)((VOID **)DebugProtocol)[0])(
      DebugLevel,
      FormatString,
      (UINT64 *)VaList
      );
  }

  VA_END (VaList);
}

/**
  ASSERT assertion handler wrapper.

  When an assertion fails, this function calls the DebugLib protocol's
  ASSERT handler with the file/line/expression information.

  @param[in] FileName   Source file name string.
  @param[in] LineNumber Line number in the source file.
  @param[in] Expression Failed assertion expression string.
**/
VOID
EFIAPI
AssertHandler (
  IN CONST CHAR8 *FileName,
  IN UINTN       LineNumber,
  IN CONST CHAR8 *Expression
  )
{
  VOID   *DebugProtocol;

  DebugProtocol = GetDebugLibProtocol ();
  if (DebugProtocol != NULL) {
    //
    // Call DebugProtocol->Assert (at offset +8).
    //
    ((DEBUG_ASSERT_FUNC)((VOID **)DebugProtocol)[1])(
      FileName,
      LineNumber,
      Expression
      );
  }
}

// ===========================================================================
// HII Protocol Services
// ===========================================================================

/**
  Gets supported languages for an HII handle.

  Retrieves the list of languages supported by a registered HII string
  package by calling HiiFont->GetStringInfo (at offset +24) first with
  a NULL buffer to get the required size, then with an allocated buffer.

  @param[in]  HiiHandle  HII handle to query.
  @param[in]  StringId   String token ID (not used directly here).
  @param[in]  Type       SMBIOS type (not used directly here).
  @param[in]  MaxLen     Maximum length hint (not used directly here).

  @return Pointer to the supported languages string, or NULL on failure.
**/
CHAR8 *
GetHiiSupportedLanguages (
  IN EFI_HII_HANDLE  HiiHandle,
  IN UINT16          StringId,
  IN UINTN           Type,
  IN UINTN           MaxLen
  )
{
  EFI_STATUS  Status;
  UINTN       BufferSize;
  CHAR8       FirstChar;
  CHAR8       *LangBuffer;

  if (HiiHandle == NULL) {
    AssertHandler (
      "e:\\hs\\MdeModulePkg\\Library\\UefiHiiLib\\HiiLanguage.c",
      47,
      "HiiHandle != ((void *) 0)"
      );
  }

  //
  // Call with NULL buffer to get required size.
  // HiiFont->GetStringInfo is at qword_3948 offset +24.
  //
  BufferSize = 0;
  Status = ((EFI_HII_GET_STRING_INFO)((VOID **)mHiiFont)[3])(
             mHiiFont,
             HiiHandle,
             &FirstChar,
             &BufferSize
             );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return NULL;
  }

  //
  // Allocate buffer of required size.
  //
  LangBuffer = AllocatePool (BufferSize);
  if (LangBuffer == NULL) {
    return NULL;
  }

  //
  // Now get the actual string.
  //
  Status = ((EFI_HII_GET_STRING_INFO)((VOID **)mHiiFont)[3])(
             mHiiFont,
             HiiHandle,
             LangBuffer,
             &BufferSize
             );
  if (EFI_ERROR (Status)) {
    FreePool (LangBuffer);
    return NULL;
  }

  return LangBuffer;
}

/**
  Gets a localized SMBIOS string from the HII Font protocol.

  Uses the HII Font protocol's string lookup to get a localized version
  of an SMBIOS string for the given HII handle and string ID.

  The function:
    1. Validates HiiHandle is non-NULL and StringId is non-zero.
    2. Gets the supported languages for the HII handle.
    3. Gets the current platform language.
    4. Calls GetSupportedLanguage() to find a matching language.
    5. Uses HiiFont->StringToImage (offset +8) to get the localized string.

  @param[in]  HiiHandle  HII handle for the string package.
  @param[in]  StringId   HII string token ID.
  @param[in]  Type       SMBIOS structure type (for context).
  @param[in]  MaxLen     Maximum string length hint.

  @return Pointer to the localized ASCII string, or NULL if not found.
**/
CHAR8 *
GetHiiString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN UINT16          StringId,
  IN UINT8           Type,
  IN UINTN           MaxLen
  )
{
  EFI_STATUS  Status;
  CHAR8       *SupportedLanguages;
  CHAR8       *PlatformLang;
  CHAR8       *MatchedLanguage;
  CHAR8       *ResultString;
  UINTN       StringSize;
  UINTN       RequiredSize;

  //
  // Validate parameters.
  //
  if (HiiHandle == NULL) {
    AssertHandler (
      "e:\\hs\\MdeModulePkg\\Library\\UefiHiiLib\\HiiString.c",
      238,
      "HiiHandle != ((void *) 0)"
      );
  }

  if (StringId == 0) {
    AssertHandler (
      "e:\\hs\\MdeModulePkg\\Library\\UefiHiiLib\\HiiString.c",
      239,
      "StringId != 0"
      );
  }

  //
  // Get the supported languages for this HII string package.
  //
  SupportedLanguages = GetHiiSupportedLanguages (HiiHandle, StringId, Type, MaxLen);
  if (SupportedLanguages == NULL) {
    return NULL;
  }

  //
  // Get the current platform language.
  //
  PlatformLang = NULL;
  GetPlatformLang (&PlatformLang);

  //
  // Match the platform language against supported languages.
  // Use "en-US" as default language for matching.
  //
  MatchedLanguage = NULL;
  if (PlatformLang != NULL) {
    MatchedLanguage = GetSupportedLanguage (
                        SupportedLanguages,
                        0,
                        SupportedLanguages,
                        PlatformLang,
                        NULL
                        );
  }

  if (MatchedLanguage == NULL) {
    //
    // Fall back to the first supported language.
    //
    MatchedLanguage = GetSupportedLanguage (
                        SupportedLanguages,
                        0,
                        SupportedLanguages,
                        NULL
                        );
  }

  if (MatchedLanguage != NULL) {
    //
    // Get the localized string size by calling HiiFont->StringToImage (offset +8)
    // with NULL buffer to get required size.
    //
    StringSize = 0;
    Status = ((EFI_HII_STRING_TO_IMAGE)((VOID **)mHiiFont)[1])(
               mHiiFont,
               MatchedLanguage,
               HiiHandle,
               StringId,
               NULL,
               &StringSize,
               0
               );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      //
      // Allocate buffer for the string.
      //
      ResultString = AllocatePool (StringSize);
      if (ResultString != NULL) {
        //
        // Get the actual string.
        //
        Status = ((EFI_HII_STRING_TO_IMAGE)((VOID **)mHiiFont)[1])(
                   mHiiFont,
                   MatchedLanguage,
                   HiiHandle,
                   StringId,
                   ResultString,
                   &StringSize,
                   0
                   );
        if (EFI_ERROR (Status)) {
          FreePool (ResultString);
          ResultString = NULL;
        }
      }
    } else {
      ResultString = NULL;
    }
  } else {
    ResultString = NULL;
  }

  //
  // Clean up temporary allocations.
  //
  FreePool (SupportedLanguages);
  if (PlatformLang != NULL) {
    FreePool (PlatformLang);
  }
  if (MatchedLanguage != NULL) {
    FreePool (MatchedLanguage);
  }
  if (ResultString != NULL && ResultString != MatchedLanguage) {
    // ResultString was allocated separately, keep it
  }

  return ResultString;
}

/**
  Gets the string for the given HII handle and string ID.

  Allocates a buffer and retrieves the string via HiiFont->StringToImage.
  Handles the two-call pattern (get size, allocate, get data).

  @param[in]  HiiHandle   HII handle.
  @param[in]  StringId    String token ID.
  @param[in]  Language    Language to use.
  @param[out] StringSize  Returns the size of the string.

  @return Pointer to the allocated string, or NULL on failure.
**/
STATIC
CHAR8 *
InternalGetHiiString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN UINT16          StringId,
  IN CONST CHAR8     *Language,
  OUT UINTN          *StringSize
  )
{
  EFI_STATUS  Status;
  UINTN       Size;
  CHAR8       *String;

  *StringSize = 0;
  Size = 0;

  //
  // Call StringToImage with NULL buffer to get required size.
  //
  Status = ((EFI_HII_STRING_TO_IMAGE)((VOID **)mHiiFont)[1])(
             mHiiFont,
             (CHAR8 *)Language,
             HiiHandle,
             StringId,
             NULL,
             &Size,
             0
             );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return NULL;
  }

  //
  // Allocate buffer.
  //
  String = AllocatePool (Size);
  if (String == NULL) {
    return NULL;
  }

  //
  // Get the actual string.
  //
  Status = ((EFI_HII_STRING_TO_IMAGE)((VOID **)mHiiFont)[1])(
             mHiiFont,
             (CHAR8 *)Language,
             HiiHandle,
             StringId,
             String,
             &Size,
             0
             );
  if (EFI_ERROR (Status)) {
    FreePool (String);
    return NULL;
  }

  *StringSize = Size;
  return String;
}

/**
  Registers an HII package list and returns the HII handle.

  Builds a package list from the input GUID and string package data,
  then calls the HII Database protocol's NewPackageList to register it.
  Returns the resulting HII handle.

  The input is an array of string pointers. The first pointer is the
  GUID (16 bytes), followed by entries where each entry is:
    4 bytes: header (includes size-4)
    0..N bytes: string data as UCS-2 characters

  @param[in]  Guid           GUID for the SMBIOS string package.
  @param[out] ImageHandle    Returns the image handle.
  @param[in]  StringPackage  Array of NULL-terminated string pointers.
  @param[in]  Flags          Package registration flags.

  @return HII handle for the registered package, or NULL on failure.
**/
EFI_HII_HANDLE
RegisterHiiPackageList (
  IN     EFI_GUID      *Guid,
  OUT    EFI_HANDLE    *ImageHandle,
  IN     UINT32        *StringPackage,
  IN     UINTN         Flags
  )
{
  EFI_HII_HANDLE  HiiHandle;
  EFI_STATUS      Status;
  VOID            *PackageData;
  UINT32          *Entry;
  UINT32          **EntryPtr;
  UINTN           TotalSize;
  UINTN           DataSize;
  UINTN           EntrySize;
  UINT32          *CurEntry;

  //
  // Validate parameters.
  //
  if (Guid == NULL) {
    AssertHandler (
      "e:\\hs\\MdeModulePkg\\Library\\UefiHiiLib\\HiiLib.c",
      160,
      "PackageListGuid != ((void *) 0)"
      );
  }

  //
  // If no string entries, return NULL handle.
  //
  if (StringPackage == NULL) {
    return NULL;
  }

  //
  // Calculate total package size.
  // Each entry header has size-4 in the first 4 bytes.
  // We need to sum all entry sizes (excluding the 4-byte header
  // contribution counted as size-4 per entry).
  //
  Entry = StringPackage;
  EntryPtr = &Entry;
  TotalSize = 0;

  do {
    EntryPtr++;
    EntrySize = ReadUnaligned32 (Entry) - 4;
    TotalSize += EntrySize;
    Entry = *EntryPtr;
  } while (*EntryPtr != NULL);

  if (TotalSize == 0) {
    return NULL;
  }

  //
  // Allocate buffer for the entire package list (header + data).
  // The HII package list header is sizeof(EFI_HII_PACKAGE_LIST_HEADER)
  // which includes a GUID (16 bytes) and package length (24 bytes total).
  //
  DataSize = TotalSize + sizeof (EFI_HII_PACKAGE_LIST_HEADER);
  PackageData = AllocateZeroPool (DataSize);
  if (PackageData == NULL) {
    return NULL;
  }

  //
  // Fill in the package list header.
  // Copy the GUID to the beginning of the package list.
  //
  CopyGuid ((EFI_GUID *)PackageData, Guid);
  *(UINT32 *)((UINT8 *)PackageData + 16) = (UINT32)DataSize;

  //
  // Copy all package entries.
  //
  {
    UINT8  *Dst = (UINT8 *)PackageData + 20;
    Entry = StringPackage;
    EntryPtr = &Entry;

    do {
      EntrySize = ReadUnaligned32 (Entry) - 4;
      CopyMem (Dst, Entry + 1, EntrySize);
      Dst += EntrySize;
      EntryPtr++;
      Entry = *EntryPtr;
    } while (*EntryPtr != NULL);

    //
    // Add the terminating 4-byte zero entry.
    //
    CopyMem (Dst, &mZeroGuid, 4);
  }

  //
  // Call HiiDatabase->NewPackageList (at offset +0 of qword_3968).
  //
  HiiHandle = NULL;
  Status = ((EFI_HII_NEW_PACKAGE_LIST)((VOID **)mHiiPackageListProtocol)[0])(
             mHiiPackageListProtocol,
             PackageData,
             ImageHandle,
             &HiiHandle
             );
  if (EFI_ERROR (Status)) {
    HiiHandle = NULL;
  }

  FreePool (PackageData);

  return HiiHandle;
}

// ===========================================================================
// SMBIOS Protocol Services
// ===========================================================================

/**
  Adds a SMBIOS string record to the SMBIOS table.

  Uses the SMBIOS protocol to add a string record. The protocol function
  at offset +0 takes (This, Reserved, Handle, Buffer).

  @param[in] Buffer  Pointer to the SMBIOS string record buffer.
                     The record format: Byte0=Type, Byte1=FieldCount,
                     UINT16=Handle, followed by string data.

  @retval EFI_SUCCESS           String added successfully.
  @retval EFI_PROTOCOL_ERROR    SMBIOS protocol not available.
**/
EFI_STATUS
AddSmbiosString (
  IN VOID  *Buffer
  )
{
  VOID        *SmbiosProto;
  EFI_STATUS  Status;
  UINT16      Handle;

  //
  // Get or locate the SMBIOS protocol.
  //
  SmbiosProto = mSmbiosProtocol3;
  if (SmbiosProto == NULL) {
    Status = gBootServices->LocateProtocol (
                              &mSmbiosProtocolGuid,
                              NULL,
                              &mSmbiosProtocol3
                              );
    if (EFI_ERROR (Status)) {
      return Status;
    }
    SmbiosProto = mSmbiosProtocol3;
  }

  //
  // Initialize handle to "uninitialized" (0xFFFE).
  // The SMBIOS AddString function at protocol offset 0 uses:
  //   - param 0: This pointer
  //   - param 1: Reserved (0)
  //   - param 2: Handle pointer (0xFFFE = use default)
  //   - param 3: Buffer containing the string record
  //
  Handle = SMBIOS_HANDLE_UNINITIALIZED;
  ((EFI_SMBIOS_ADD_STRING)((VOID **)SmbiosProto)[0])(
    SmbiosProto,
    0,
    &Handle,
    Buffer
    );

  return EFI_SUCCESS;
}

/**
  Finds the first SMBIOS string matching a given type.

  Uses the SMBIOS protocol GetNextString function (at offset +24) to
  enumerate SMBIOS strings and find the first one whose type matches
  the specified type ID.

  @param[in]  TypeId      SMBIOS string type to find.
  @param[out] Handle      Returns the handle of the matching string.

  @retval EFI_SUCCESS           Matching string found.
  @retval EFI_NOT_FOUND         No matching string found.
  @retval EFI_PROTOCOL_ERROR    SMBIOS protocol not available.
**/
EFI_STATUS
FindFirstSmbiosString (
  IN  UINT8    TypeId,
  OUT UINT16   *Handle
  )
{
  VOID        *SmbiosProto;
  UINT16      CurrentHandle;
  UINT8       CurrentType;
  UINT8       SearchType;
  UINTN       Count;
  UINTN       BufferSize;
  UINT8       Buffer[40];

  if (Handle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get or locate the SMBIOS protocol.
  //
  SmbiosProto = mSmbiosProtocol1;
  if (SmbiosProto == NULL) {
    SmbiosProto = mSmbiosProtocol1;
    if (SmbiosProto == NULL) {
      return EFI_NOT_FOUND;
    }
  }

  //
  // Search for the first matching string.
  // The SMBIOS protocol GetNext function at offset +24 enumerates strings:
  //   - param 0: This pointer
  //   - param 1: Handle (IN/OUT, -2 = start enumeration)
  //   - param 2: Type ID
  //   - param 3: Buffer (output)
  //   - param 4: Buffer size
  //
  SearchType = TypeId;
  CurrentHandle = SMBIOS_HANDLE_UNINITIALIZED;
  Count = 0;

  while (((EFI_SMBIOS_GET_NEXT_STRING)((VOID **)SmbiosProto)[3])(
           SmbiosProto,
           &CurrentHandle,
           &SearchType,
           Buffer,
           NULL
         ) >= EFI_SUCCESS && CurrentHandle != 0xFFFE)
  {
    Count++;
    if (Count == 1) {
      *Handle = CurrentHandle;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Removes an existing SMBIOS string and adds a replacement.

  Uses the SMBIOS protocol to:
    1. Find the first string matching TypeId.
    2. Remove it via RemoveString (offset +16).
    3. Add the new string from Buffer via AddString (offset 0).

  @param[in] TypeId      SMBIOS string type to find and replace.
  @param[in] Buffer      Pointer to the replacement string record.

  @retval EFI_SUCCESS           Replacement completed.
  @retval EFI_PROTOCOL_ERROR    SMBIOS protocol not available.
**/
EFI_STATUS
RemoveAndAddSmbiosString (
  IN UINT8   TypeId,
  IN VOID    *Buffer
  )
{
  VOID        *SmbiosProto;
  EFI_STATUS  Status;
  UINT16      Handle;

  SmbiosProto = mSmbiosProtocol4;
  if (SmbiosProto == NULL) {
    Status = gBootServices->LocateProtocol (
                              &mSmbiosProtocolGuid,
                              NULL,
                              &mSmbiosProtocol4
                              );
    if (EFI_ERROR (Status)) {
      return Status;
    }
    SmbiosProto = mSmbiosProtocol4;
  }

  //
  // Find and remove the current string, then add the replacement.
  //
  Status = FindFirstSmbiosString (TypeId, &Handle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Remove the old string at protocol offset +16.
  //
  ((EFI_SMBIOS_REMOVE_STRING)((VOID **)SmbiosProto)[2])(
    SmbiosProto,
    Handle
    );

  //
  // Add the new string at protocol offset 0.
  //
  Handle = SMBIOS_HANDLE_UNINITIALIZED;
  ((EFI_SMBIOS_ADD_STRING)((VOID **)SmbiosProto)[0])(
    SmbiosProto,
    0,
    &Handle,
    Buffer
    );

  return EFI_SUCCESS;
}

/**
  Removes all SMBIOS strings of a given type.

  Enumerates all SMBIOS strings matching the specified type and removes
  each one via the SMBIOS protocol RemoveString function.

  @param[in] TypeId  SMBIOS string type to remove.
**/
VOID
RemoveAllSmbiosStringsOfType (
  IN UINT8  TypeId
  )
{
  VOID        *SmbiosProto;
  UINT16      CurrentHandle;
  UINT8       SearchType;
  UINT8       TypeBuf;
  UINT8       Buffer;
  UINTN       Count;

  //
  // Get or locate the SMBIOS protocol.
  //
  SmbiosProto = mSmbiosProtocol2;
  if (SmbiosProto == NULL) {
    //
    // Locate the SMBIOS protocol.
    //
    if (gBootServices->LocateProtocol (
          &mSmbiosProtocolGuid,
          NULL,
          &mSmbiosProtocol2
          ) < 0) {
      return;
    }
    SmbiosProto = mSmbiosProtocol2;
  }

  //
  // Enumerate and remove all strings of the given type.
  //
  SearchType = TypeId;
  CurrentHandle = SMBIOS_HANDLE_UNINITIALIZED;
  Count = 0;

  while (((EFI_SMBIOS_GET_NEXT_STRING)((VOID **)SmbiosProto)[3])(
           SmbiosProto,
           &CurrentHandle,
           &SearchType,
           &TypeBuf,
           NULL
         ) >= EFI_SUCCESS && CurrentHandle != 0xFFFE)
  {
    Count++;
  }

  //
  // Remove each string of this type.
  //
  for (; Count > 0; Count--) {
    RemoveAndAddSmbiosString (TypeId, NULL);
  }
}

/**
  Gets the SMBIOS structures after the current field position.

  Scans the SMBIOS string record starting from the current field to find
  the end of the structure. The function iterates through the string data
  to find the end of the structure region.

  @param[in,out] RecordBuffer  Pointer to the SMBIOS string record.
  @param[out]    TotalLength   Returns the total length of the structure
                               from the start to the end of the last field.
**/
VOID
GetSmbiosStructuresAfterField (
  IN OUT VOID    *RecordBuffer,
  OUT    UINTN   *TotalLength
  )
{
  UINT8   *Buffer;
  UINTN   Length;
  UINTN   Index;
  UINT8   *Scan;

  Buffer = (UINT8 *)RecordBuffer;
  Length = Buffer[1];  // FieldCount

  *TotalLength = Length;
  Scan = Buffer + Length;

  //
  // Scan through the string data to find the end.
  // Strings are terminated by a double-null (one after each string,
  // plus a final null to mark end of all strings).
  //
  while (TRUE) {
    if (*Scan == '\0') {
      //
      // Found a null terminator. Check if it's the end of strings
      // (double-null) or just a single string terminator.
      //
      if (*++Scan == '\0') {
        //
        // Double-null found - end of structures.
        //
        *TotalLength += 2;
        return;
      }
      (*TotalLength)++;
    }

    //
    // Count characters until next null.
    //
    for (Index = 0; Index < 64; Index++) {
      if (Scan[Index] == '\0') {
        break;
      }
    }

    if (Index == 64) {
      //
      // No null found in 64 chars - likely an error.
      //
      *TotalLength = 0;
      return;
    }

    Scan += Index;
    *TotalLength += Index;
  }
}

/**
  Writes a string value into the SMBIOS string record.

  This function replaces or inserts a string value at the appropriate
  position within the SMBIOS string record buffer. It handles string
  insertion by tracking positions, managing overlap-safe copies, and
  recalculating the record structure after modification.

  @param[in,out] RecordBuffer   Pointer to the SMBIOS string record.
  @param[in]     NewString      The new string value to write.
  @param[in]     FieldIndex     Index of the field within the record.
  @param[in]     RecordBuffer2  Second record buffer for overlap-safe
                                operations (for intermediate storage).

  @retval EFI_SUCCESS           String updated successfully.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
  @retval EFI_BAD_BUFFER_SIZE   Buffer size overflow.
**/
EFI_STATUS
UpdateSmbiosStringField (
  IN OUT VOID   *RecordBuffer,
  IN     CHAR8  *NewString,
  IN     UINTN  FieldIndex,
  IN     VOID   *RecordBuffer2
  )
{
  UINT8   *Buf;
  UINTN   StringLen;
  UINTN   FieldPos;
  UINTN   FieldLen;
  UINTN   TotalLen;
  UINTN   AfterFieldLen;
  UINT8   *FieldPtr;
  UINTN   NewLen;
  UINTN   v10;
  UINTN   v11;
  UINTN   v12;
  UINTN   v13;
  UINTN   v14;
  UINTN   v15;
  UINTN   v16;
  CHAR8   *SourceEnd;
  UINTN   OverlapCheck;

  Buf = (UINT8 *)RecordBuffer;

  //
  // Get the source string length.
  //
  StringLen = AsciiStrLen (NewString);

  //
  // Get the SMBIOS structure length.
  //
  GetSmbiosStructuresAfterField (RecordBuffer, &TotalLen);

  //
  // Calculate the field position within the record.
  //
  FieldPos = Buf[1];  // FieldCount (offset to first string)
  FieldPtr = &Buf[FieldPos];
  v12 = 1;
  v13 = 0;

  //
  // Scan through fields to find the target field position.
  //
  if (FieldIndex > 1) {
    do {
      v14 = v12 + 1;
      if (*FieldPtr != '\0') {
        v14 = v12;
      }
      FieldPtr++;
      v13++;
      v12 = v14;
    } while (v14 < FieldIndex);
  }

  //
  // Check if the new string length matches the field's existing length.
  // If AsciiStrLen of FieldPtr's region matches StringLen, we can do an
  // in-place replacement. Otherwise we need to insert/remove space.
  //
  FieldLen = AsciiStrLen (FieldPtr);

  if (FieldLen == StringLen) {
    //
    // Same length - in-place replacement.
    //
    if (FieldPtr != NULL) {
      //
      // Overlap-safe string copy.
      //
      if (FieldPtr >= (UINT8 *)NewString ||
          (UINT8 *)NewString >= &FieldPtr[StringLen + 1]) {
        //
        // No overlap, direct copy.
        //
        if (FieldPtr == (UINT8 *)NewString) {
          //
          // Same pointer, nothing to do.
          //
          return EFI_SUCCESS;
        }

        AsciiStrCpyS (FieldPtr, StringLen + 1, NewString);

        //
        // Recalculate the structure after the field.
        //
        GetSmbiosStructuresAfterField (RecordBuffer, &TotalLen);
        CopyMem (RecordBuffer, RecordBuffer2, TotalLen);

        return EFI_SUCCESS;
      }

      //
      // Overlap detected - use auxiliary buffer for safe copy.
      //
      {
        UINTN  TotalSize;
        UINTN  AuxBufSize;

        TotalSize = 0x300; // SMBIOS_STRING_RECORD_SIZE
        if (RecordBuffer2 == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        //
        // Copy the record to auxiliary buffer, modify, and copy back.
        //
        CopyMem (RecordBuffer2, RecordBuffer, FieldPos + v13 + Buf[1]);
        CopyMem (
          (UINT8 *)RecordBuffer2 + FieldPos + v13 + Buf[1],
          &Buf[FieldPos + v13 + Buf[1] + FieldLen + 1],
          TotalLen - FieldPos - v13 - Buf[1] - FieldLen - 1
          );

        //
        // Write new string.
        //
        AsciiStrCpyS (
          (CHAR8 *)((UINT8 *)RecordBuffer2 + FieldPos + v13 + Buf[1]),
          StringLen + 1,
          NewString
          );

        //
        // Copy back and recalculate.
        //
        GetSmbiosStructuresAfterField (RecordBuffer2, &TotalLen);

        //
        // Copy the updated record back.
        //
        CopyMem (&Buf[FieldPos + v13 + Buf[1]], &FieldPtr[FieldLen - StringLen + 1], StringLen + 1);

        //
        // Final size update.
        //
        Buf[FieldPos + v13 + Buf[1] + StringLen] = NewString[AfterFieldLen];

        FreePool (RecordBuffer2);
        FreePool (NewString);

        return EFI_SUCCESS;
      }
    }

    //
    // Null field pointer - append? This is a complex path.
    //
  }

  //
  // Different length - need to insert/remove space.
  //
  {
    UINTN  AuxBuffer;
    UINTN  *AuxPtr;
    UINTN  AuxTotalLen;

    //
    // Allocate auxiliary buffer for safe manipulation.
    //
    AuxBuffer = (UINTN)AllocateZeroPool (SMBIOS_STRING_RECORD_SIZE);
    if (AuxBuffer == 0) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Copy the part before the new string.
    //
    CopyMem (
      (VOID *)AuxBuffer,
      RecordBuffer,
      v13 + Buf[1] + FieldPos
      );

    //
    // Copy the part after the old string, skipping it.
    //
    CopyMem (
      (VOID *)(AuxBuffer + v13 + Buf[1] + FieldPos),
      &Buf[v13 + Buf[1] + FieldPos + FieldLen + 1],
      TotalLen - FieldPos - v13 - Buf[1] - FieldLen - 1
      );

    //
    // Calculate new total length.
    //
    AuxTotalLen = TotalLen - FieldLen + StringLen;

    //
    // Write new string.
    //
    AsciiStrCpyS (
      (CHAR8 *)(AuxBuffer + v13 + Buf[1] + FieldPos),
      StringLen + 1,
      NewString
      );

    //
    // Copy back to original buffer.
    //
    GetSmbiosStructuresAfterField ((VOID *)AuxBuffer, &TotalLen);
    CopyMem (
      RecordBuffer,
      (VOID *)AuxBuffer,
      TotalLen
      );

    //
    // Clean up.
    //
    FreePool ((VOID *)AuxBuffer);
  }

  return EFI_SUCCESS;
}

/**
  Builds a single SMBIOS string record for Type 2 (Baseboard) fields.

  Constructs a formatted SMBIOS string record in the output buffer based
  on the string descriptor table entry at the given index. The descriptor
  table (embedded in the code at sub_77C, address 0x77C) maps each index
  (0-29) to an SMBIOS Type 2 field with an associated HII string token.

  Each descriptor table entry is 10 bytes:
    +0: UINT16 StringId    (HII string token ID)
    +2: UINT8  FieldNumber (SMBIOS field number)
    +4: UINT8  Encoding    (string encoding type)
    +5: UINT8  MaxLength   (maximum string length)
    +6: UINT8  Offset      (byte offset in output buffer)
    +7: UINT8  Flags       (attribute flags)
    +8: UINT16 Reserved    (internal use)

  The output record has the format:
    Byte0:  SMBIOS structure type (8 for Type2)
    Byte1:  FieldCount (29 fields, 0-indexed as 30-1)
    Word2:  Handle (0xFFFE = uninitialized)
    +4:     FieldNumber (copied from descriptor)
    +5:     Encoding (copied from descriptor)
    +6:     MaxLength (copied from descriptor)
    +7:     Flags (copied from descriptor)
    +8..N:  String data (localized HII string)

  @param[out] Buffer     Output buffer for the SMBIOS string record.
                         Must be at least SMBIOS_STRING_RECORD_SIZE bytes.
  @param[in]  DescriptorIndex  Index into the Type 2 descriptor table (0-29).

  @retval EFI_SUCCESS           String record built successfully.
  @retval EFI_INVALID_PARAMETER DescriptorIndex >= 30.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed (from GetHiiString or UpdateSmbiosStringField).
**/
EFI_STATUS
BuildSmbiosStringRecord (
  OUT VOID    *Buffer,
  IN  UINTN   DescriptorIndex
  )
{
  UINT8   *OutBuf;
  CONST SMBIOS_STRING_DESC  *Desc;
  CHAR8   *LocalizedString;
  UINT8   Type;
  UINT8   FieldNum;
  UINT16  StringId;
  UINT8   Encoding;
  UINT8   OutputOffset;
  UINT8   MaxLength;
  UINT8   Flags;

  OutBuf = (UINT8 *)Buffer;

  if (DescriptorIndex >= SMBIOS_TYPE2_COUNT) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get the descriptor entry for this index.
  //
  Desc = &mSmbiosType2Descriptors[DescriptorIndex];

  FieldNum     = Desc->FieldNumber;
  StringId     = Desc->StringId;
  Encoding     = Desc->Encoding;
  OutputOffset = Desc->OutputOffset;
  MaxLength    = Desc->MaxLength;
  Flags        = Desc->Flags;

  //
  // Initialize the SMBIOS string record header.
  // Byte 0: Type (8 = Type 2 Baseboard)
  // Byte 1: FieldCount (29 = total fields -1)
  // Word 2-3: Handle (0xFFFE = uninitialized)
  //
  OutBuf[0] = 8;                         // SMBIOS type 2
  OutBuf[1] = 29;                        // 30 fields, index 0-29
  *(UINT16 *)&OutBuf[2] = SMBIOS_HANDLE_UNINITIALIZED;

  //
  // Copy the descriptor field metadata into the record header at offsets 4-7.
  // From the original binary (sub_77C, 0x77C):
  //   OutBuf[4] = FieldNumber
  //   OutBuf[5] = Encoding
  //   OutBuf[6] = MaxLength
  //   OutBuf[7] = Flags
  //
  OutBuf[4] = FieldNum;
  OutBuf[5] = Encoding;
  OutBuf[6] = MaxLength;
  OutBuf[7] = Flags;

  //
  // If StringId is non-zero, look up the localized string.
  // A zero StringId means this descriptor has no associated string.
  //
  if (StringId != 0) {
    //
    // Get the localized string from HII font protocol.
    //
    LocalizedString = GetHiiString (
                        gSmbiosStringPackHandle,
                        StringId,
                        2,
                        MaxLength
                        );

    if (LocalizedString != NULL) {
      //
      // Write the string into the SMBIOS record buffer.
      // The function handles buffer manipulation, overlap-safe
      // copy, and string insertion/splicing.
      //
      UpdateSmbiosStringField (
        Buffer,
        LocalizedString,
        DescriptorIndex,
        NULL
        );

      //
      // Note: UpdateSmbiosStringField manages memory of LocalizedString.
      // No explicit FreePool needed here.
      //
    }
  }

  return EFI_SUCCESS;
}

/**
  Builds a Type 9 (System Slot) SMBIOS string record.

  This function constructs an SMBIOS Type 9 string record based on the
  slot descriptor at the given index (0-7).

  @param[out] Buffer         Output buffer for the SMBIOS string record.
  @param[in]  DescriptorIndex  Index into the Type 9 descriptor table (0-7).

  @retval EFI_SUCCESS           String record built successfully.
  @retval Others               Error from internal functions.
**/
EFI_STATUS
BuildSmbiosType9Record (
  OUT VOID    *Buffer,
  IN  UINTN   DescriptorIndex
  )
{
  //
  // NOTE: The full implementation of this function could not be decompiled.
  // The function at address 0xA20 constructs Type 9 SMBIOS records.
  // It follows a similar pattern to BuildSmbiosStringRecord but for
  // SMBIOS Type 9 (System Slots) fields.
  //
  // From the dispatch function (SmbiosDataUpdateDispatch), this function
  // is called for 8 iterations (0-7). It takes a working buffer and index,
  // builds the record, and the caller then writes it to SMBIOS.
  //
  return EFI_UNSUPPORTED;
}

/**
  Builds a Type 41 (Onboard Device) SMBIOS string record.

  This function constructs an SMBIOS Type 41 string record based on the
  device descriptor at the given index (0-3).

  @param[out] Buffer         Output buffer for the SMBIOS string record.
  @param[in]  DescriptorIndex  Index into the Type 41 descriptor table (0-3).

  @retval EFI_SUCCESS           String record built successfully.
  @retval Others               Error from internal functions.
**/
EFI_STATUS
BuildSmbiosType41Record (
  OUT VOID    *Buffer,
  IN  UINTN   DescriptorIndex
  )
{
  //
  // NOTE: The full implementation of this function could not be decompiled.
  // The function at address 0xD98 constructs Type 41 SMBIOS records.
  // It follows a similar pattern to BuildSmbiosStringRecord but for
  // SMBIOS Type 41 (Onboard Devices Extended Information) fields.
  //
  // From the dispatch function (SmbiosDataUpdateDispatch), this function
  // is called for 4 iterations (0-3). It takes a working buffer and index,
  // builds the record, and the caller then writes it to SMBIOS.
  //
  return EFI_UNSUPPORTED;
}

// ===========================================================================
// MM PCI Configuration
// ===========================================================================

/**
  Writes a value to a PCIe configuration register via the MM PCIe base protocol.

  Encodes the bus/device/function into an MMIO address using:
    address = ((Func & 7) | (8 * ((Dev & 0x1F) | (32 * Bus)))) << 12

  The MM PCIe base protocol (gEfiMmPciBaseProtocolGuid) provides a Write
  function at offset +24 that takes an encoded address structure.

  @param[in] Bus       PCI bus number.
  @param[in] Device    PCI device number.
  @param[in] Function  PCI function number.
  @param[in] Register  PCI config register offset.
  @param[in] Value     32-bit value to write to the register.

  @return EFI_STATUS from the MM PCIe write operation.
**/
EFI_STATUS
MmPciWriteConfig (
  IN UINT8   Bus,
  IN UINT8   Device,
  IN UINT8   Function,
  IN UINT16  Register,
  IN UINT32  Value
  )
{
  //
  // Encode the PCI address.
  // Address format: ((Func & 7) | (8 * ((Dev & 0x1F) | (32 * Bus)))) << 12
  //
  UINT32  Address;
  UINT32  AddressBuf[6];

  //
  // Prepare address structure for MmPciBase->Write.
  // AddressBuf layout:
  //   [0]: Address (encoded BDF << 12)
  //   [1]: Register
  //   [2]: Size (512 = PCI config space)
  //   [3]: 0 (reserved)
  //
  AddressBuf[0] = 0;
  AddressBuf[1] = 0;
  AddressBuf[2] = 512;
  AddressBuf[3] = 0;

  //
  // Encode the PCI address: Bits [14:12] = Func, [19:15] = Dev, [24:20] = Bus.
  //
  AddressBuf[0] = (Value & 7 | (8 * ((Device & 0x1F) | (32 * Bus)))) << 12;

  //
  // Call MmPciUsra->Write (at offset +24) with the address structure.
  //
  if (mMmPciUsra == NULL) {
    return EFI_NOT_READY;
  }

  ((EFI_MM_PCI_WRITE)((VOID **)mMmPciUsra)[3])(
    AddressBuf
    );

  return EFI_SUCCESS;
}

// ===========================================================================
// SMBIOS Data Update Dispatch
// ===========================================================================

/**
  Dispatches SMBIOS data updates.

  Allocates a working buffer of SMBIOS_STRING_RECORD_SIZE bytes and
  iterates through three phases:
    1. 30 Type 2 (Baseboard) descriptors
    2. 8 Type 9 (System Slot) descriptors
    3. 4 Type 41 (Onboard Device) descriptors

  Before each phase, existing strings of that type are removed.
  After each successful record build, the string is added to SMBIOS tables.

  @return EFI_STATUS from the last SMBIOS add operation.
**/
EFI_STATUS
SmbiosDataUpdateDispatch (
  VOID
  )
{
  VOID        *WorkBuffer;
  UINTN       Status;
  UINTN       i;

  //
  // Allocate working buffer for SMBIOS string record construction.
  //
  WorkBuffer = AllocateZeroPool (SMBIOS_STRING_RECORD_SIZE);
  if (WorkBuffer == NULL) {
    AssertHandler (
      "e:\\hs\\PurleyRpPkg\\Uba\\UbaMain\\Dxe\\TypeLightningRidgeEXRP\\SmbiosDataUpdateDxe\\SmbiosDataUpdateDxe.c",
      625,
      "gSmbiosStringPackHandle != ((void *) 0)"
      );
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Phase 1: Process 30 SMBIOS Type 2 (Baseboard) string fields.
  //
  // Remove all existing Type 2 strings first.
  //
  RemoveAllSmbiosStringsOfType (SMBIOS_TYPE_BASEBOARD);

  //
  // Process each Type 2 string field.
  //
  for (i = 0; i < SMBIOS_TYPE2_COUNT; i++) {
    ZeroMem (WorkBuffer, SMBIOS_STRING_RECORD_SIZE);

    Status = BuildSmbiosStringRecord (WorkBuffer, i);
    if ((Status & SIGNATURE_64_ERROR_BIT) == 0) {
      AddSmbiosString (WorkBuffer);
    }
  }

  //
  // Phase 2: Process 8 SMBIOS Type 9 (System Slot) string fields.
  //
  RemoveAllSmbiosStringsOfType (SMBIOS_TYPE_SYSTEM_SLOTS);

  for (i = 0; i < SMBIOS_TYPE9_COUNT; i++) {
    ZeroMem (WorkBuffer, SMBIOS_STRING_RECORD_SIZE);

    Status = BuildSmbiosType9Record (WorkBuffer, i);
    if ((Status & SIGNATURE_64_ERROR_BIT) == 0) {
      AddSmbiosString (WorkBuffer);
    }
  }

  //
  // Phase 3: Process 4 SMBIOS Type 41 (Onboard Device) string fields.
  //
  RemoveAllSmbiosStringsOfType (SMBIOS_TYPE_ONBOARD_DEVICES);

  for (i = 0; i < SMBIOS_TYPE41_COUNT; i++) {
    ZeroMem (WorkBuffer, SMBIOS_STRING_RECORD_SIZE);

    Status = BuildSmbiosType41Record (WorkBuffer, i);
    if ((Status & SIGNATURE_64_ERROR_BIT) == 0) {
      AddSmbiosString (WorkBuffer);
    }
  }

  //
  // Clean up.
  //
  FreePool (WorkBuffer);

  return (EFI_STATUS)Status;
}

// ===========================================================================
// Main Entry Point (SmbiosDataUpdateEntry)
// ===========================================================================

/**
  Main SMBIOS data update entry routine.

  Called from ModuleEntryPoint after SmbiosDataUpdateInit().
  Performs the SMBIOS data update by:
    1. Printing a debug message identifying this module.
    2. Opening the UBA config protocol from ImageHandle to get board config.
    3. Copying the board-specific SMBIOS config GUID to a global.
    4. Registering the HII string package via RegisterHiiPackageList().
    5. Locating the UBA SMBIOS Data protocol.
    6. Calling UbaSmbiosData->SetSmbiosData() which triggers the dispatch.

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.

  @retval EFI_SUCCESS           SMBIOS data update initiated.
  @retval EFI_UNSUPPORTED       UBA config protocol not available.
  @retval EFI_NOT_FOUND         Required protocol not found.
**/
EFI_STATUS
SmbiosDataUpdateEntry (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS           Status;
  VOID                 *UbaConfig;
  UINT64               ConfigData[3];
  UBA_SMBIOS_DATA_PROTOCOL  *UbaDataProtocol = NULL;
  UINT32               ConfigBuffer[6];

  //
  // Open the UBA config protocol installed on ImageHandle.
  // gBS->OpenProtocol is at BootServices offset +152 (function index 19).
  //
  Status = gBootServices->OpenProtocol (
                            ImageHandle,
                            &mUbaConfigProtocolGuid,
                            &UbaConfig,
                            ImageHandle,
                            NULL,
                            EFI_OPEN_PROTOCOL_GET_PROTOCOL
                            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Print module identification string.
  //
  DebugPrint (
    UBA_DEBUG_ERROR,
    "UBA:SmbiosDataUpdateEntry Image GUID=%g\n",
    UbaConfig
    );

  //
  // Copy the board-specific SMBIOS config GUID from UBA config data.
  // The config data is at UbaConfig + 4 bytes (first 4 bytes are header).
  //
  CopyGuid (&mSmbiosConfigGuid, (EFI_GUID *)((UINT8 *)UbaConfig + 4));

  //
  // Register the HII string package.
  //
  gSmbiosStringPackHandle = RegisterHiiPackageList (
                              &mSmbiosStringPackageGuid,
                              &ImageHandle,
                              NULL,  // String data from HII table
                              0
                              );

  if (gSmbiosStringPackHandle == NULL) {
    AssertHandler (
      "e:\\hs\\PurleyRpPkg\\Uba\\UbaMain\\Dxe\\TypeLightningRidgeEXRP\\SmbiosDataUpdateDxe\\SmbiosDataUpdateDxe.c",
      625,
      "gSmbiosStringPackHandle != ((void *) 0)"
      );
  }

  //
  // Prepare the dispatch configuration buffer.
  // Format: 6 UINT32s = 24 bytes total
  //   [0]: Board type magic (0x42434150 = "PCAB"?)
  //   [1]: Version (1)
  //   [2]: Dispatch function index (9)
  //   [3]: 0 (reserved)
  //
  ZeroMem (ConfigBuffer, sizeof (ConfigBuffer));
  ConfigBuffer[0] = 0x42434150;  // "PCAB" or board type identifier
  ConfigBuffer[1] = 1;           // Version
  ConfigBuffer[2] = 9;           // Dispatch function index

  //
  // Locate the UBA SMBIOS Data protocol.
  //
  if (mUbaSmbiosDataProtocol == NULL) {
    Status = gBootServices->LocateProtocol (
                              &mUbaSmbiosDataProtocolGuid,
                              NULL,
                              &mUbaSmbiosDataProtocol
                              );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Register the SMBIOS config with the UBA protocol.
  // This call triggers the SmbiosDataUpdateDispatch callback.
  //
  return ((UBA_SMBIOS_DATA_PROTOCOL *)mUbaSmbiosDataProtocol)->SetSmbiosData (
           mUbaSmbiosDataProtocol,
           &mSmbiosConfigGuid,
           ConfigBuffer,
           sizeof (ConfigBuffer)
           );
}

// ===========================================================================
// Initialization Function (SmbiosDataUpdateInit)
// ===========================================================================

/**
  Initializes UEFI services and protocols used by this driver.

  Performs the following initialization steps:
    1. Saves ImageHandle, SystemTable, BootServices, RuntimeServices to globals.
    2. Validates all required table pointers (non-NULL checks via ASSERT).
    3. Locates HII Font protocol and caches in mHiiFont.
    4. Locates HII Database protocol and caches in mHiiDatabase.
    5. Locates HII Package List protocol and caches in mHiiPackageList.
    6. Locates HII String protocol and caches in mHiiString.
    7. Locates DXE Services Table via GetConfigTable().
    8. Optionally locates MM PCIe base protocol (may be pre-cached).

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.
  @param[in] SystemTable  A pointer to the EFI System Table.
**/
VOID
SmbiosDataUpdateInit (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  //
  // The initialization logic from the original sub_38C (address 0x38C)
  // has been inlined into ModuleEntryPoint() below.
  //
  // This function is kept as a stub for documentation purposes since the
  // original binary had this as a separate function called from the entry
  // point. All initialization (globals, HII protocols, DXE Services Table,
  // MM PCIe base protocol) is now performed directly in ModuleEntryPoint().
  //
}

// ===========================================================================
// Module Entry Point
// ===========================================================================

/**
  Entry point for the SMBIOS Data Update DXE driver.

  Standard UEFI driver entry point. Initializes global UEFI service table
  and protocol pointers, then performs the SMBIOS data update.

  The entry point performs the following:
    1. Saves ImageHandle and SystemTable to globals with NULL validation.
    2. Saves BootServices and RuntimeServices to globals with NULL validation.
    3. Locates all required HII and SMBIOS protocols.
    4. Finds the DXE Services Table from SystemTable->ConfigurationTable.
    5. Optionally locates the MM PCIe Base protocol.
    6. Calls SmbiosDataUpdateEntry() to perform SMBIOS string updates.

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.
  @param[in] SystemTable  A pointer to the EFI System Table.

  @return EFI_STATUS      Status code from SmbiosDataUpdateEntry().
**/
EFI_STATUS
EFIAPI
ModuleEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Step 1: Initialize global UEFI service table pointers.
  //
  gImageHandle = ImageHandle;
  if (ImageHandle == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
      51,
      "gImageHandle != ((void *) 0)"
      );
  }

  gSystemTable = SystemTable;
  if (SystemTable == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
      57,
      "gST != ((void *) 0)"
      );
  }

  gBootServices = SystemTable->BootServices;
  if (gBootServices == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
      63,
      "gBS != ((void *) 0)"
      );
  }

  gRuntimeServices = SystemTable->RuntimeServices;
  if (gRuntimeServices == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\UefiRuntimeServicesTableLib\\UefiRuntimeServicesTableLib.c",
      47,
      "gRT != ((void *) 0)"
      );
  }

  //
  // Step 2: Locate HII services protocols.
  //
  // Locate HII Font protocol.
  Status = gBootServices->LocateProtocol (
                            &mHiiFontProtocolGuid,
                            NULL,
                            &mHiiFont
                            );
  if (EFI_ERROR (Status)) {
    DebugPrint (
      UBA_DEBUG_ERROR,
      "\nASSERT_EFI_ERROR (Status = %r)\n",
      Status
      );
    AssertHandler (
      "e:\\hs\\MdeModulePkg\\Library\\UefiHiiServicesLib\\UefiHiiServicesLib.c",
      88,
      "!EFI_ERROR (Status)"
      );
  }

  // Locate HII String protocol.
  Status = gBootServices->LocateProtocol (
                            &mHiiStringProtocolGuid,
                            NULL,
                            &mHiiString
                            );
  if (EFI_ERROR (Status)) {
    DebugPrint (
      UBA_DEBUG_ERROR,
      "\nASSERT_EFI_ERROR (Status = %r)\n",
      Status
      );
    AssertHandler (
      "e:\\hs\\MdeModulePkg\\Library\\UefiHiiServicesLib\\UefiHiiServicesLib.c",
      94,
      "!EFI_ERROR (Status)"
      );
  }

  // Locate HII Database protocol.
  Status = gBootServices->LocateProtocol (
                            &mHiiDatabaseProtocolGuid,
                            NULL,
                            &mHiiDatabase
                            );
  if (EFI_ERROR (Status)) {
    DebugPrint (
      UBA_DEBUG_ERROR,
      "\nASSERT_EFI_ERROR (Status = %r)\n",
      Status
      );
    AssertHandler (
      "e:\\hs\\MdeModulePkg\\Library\\UefiHiiServicesLib\\UefiHiiServicesLib.c",
      100,
      "!EFI_ERROR (Status)"
      );
  }

  // Locate HII Package List protocol.
  Status = gBootServices->LocateProtocol (
                            &mHiiPackageListProtocolGuid,
                            NULL,
                            &mHiiPackageList
                            );

  // Locate HII Package List protocol interface.
  Status = gBootServices->LocateProtocol (
                            &mHiiPackageListProtocolGuid,
                            NULL,
                            &mHiiPackageListProtocol
                            );

  //
  // Step 3: Find DXE Services Table from SystemTable->ConfigurationTable.
  //
  Status = GetConfigTable (&mDxeServicesTableGuid, &mHobList);
  if (EFI_ERROR (Status)) {
    DebugPrint (
      UBA_DEBUG_ERROR,
      "\nASSERT_EFI_ERROR (Status = %r)\n",
      Status
      );
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\DxeServicesTableLib\\DxeServicesTableLib.c",
      64,
      "!EFI_ERROR (Status)"
      );
  }

  if (mHobList == NULL) {
    AssertHandler (
      "e:\\hs\\MdePkg\\Library\\DxeServicesTableLib\\DxeServicesTableLib.c",
      65,
      "gDS != ((void *) 0)"
      );
  }

  //
  // Step 4: Optionally locate MM PCIe base protocol.
  // This may already be cached from a previous lookup.
  //
  if (mMmPciUsra == NULL) {
    Status = gBootServices->LocateProtocol (
                              &mMmPciBaseProtocolGuid,
                              NULL,
                              &mMmPciUsra
                              );
    if (EFI_ERROR (Status)) {
      DebugPrint (
        UBA_DEBUG_ERROR,
        "\nASSERT_EFI_ERROR (Status = %r)\n",
        Status
        );
      AssertHandler (
        "e:\\hs\\CpRcPkg\\Library\\DxeMmPciBaseLib\\DxeMmPciBaseLib.c",
        52,
        "!EFI_ERROR (Status)"
        );
    }

    if (mMmPciUsra == NULL) {
      AssertHandler (
        "e:\\hs\\CpRcPkg\\Library\\DxeMmPciBaseLib\\DxeMmPciBaseLib.c",
        53,
        "mPciUsra != ((void *) 0)"
        );
    }
  }

  //
  // Step 5: Initialize HOB list.
  //
  HobLibInit ();

  //
  // Step 6: Perform SMBIOS data update.
  //
  Status = SmbiosDataUpdateEntry (ImageHandle);
  return Status;
}