/**
 * @file SmbiosDataUpdateDxeLightningRidgeEXECB1.h
 *
 * @brief SMBIOS Data Update DXE Driver for Lightning Ridge EXECB1 (Purley Refresh)
 *
 * This driver is part of the UBA (Universal BIOS Architecture) framework.
 * It reads board-specific SMBIOS string data from the UBA config protocol,
 * uses HII string packages to look up localized SMBIOS strings (in the
 * platform's current language), and writes them into SMBIOS tables via the
 * EFI SMBIOS protocol.
 *
 * Handles up to 30 SMBIOS Type 2 (Baseboard), 8 Type 9 (System Slot),
 * and 4 Type 41 (Onboard Device) string fields.
 *
 * Build path: e:\hs\Build\HR6N0XMLK\DEBUG_VS2015\X64\PurleyRpPkg\Uba\UbaMain
 *   \Dxe\TypeLightningRidgeEXECB1\SmbiosDataUpdateDxe\SmbiosDataUpdateDxe
 *   \DEBUG\AutoGen.c
 *
 * @note This module has NO import table -- all imports resolved at runtime
 *       via LocateProtocol.
 */

#ifndef SMBIOS_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXECB1_H
#define SMBIOS_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXECB1_H

#include "../uefi_headers/Uefi.h"

// ============================================================================
// GUID Definitions
// ============================================================================

// {5B1B31A1-9562-11D2-8E3F-00A0C969723B}
#define EFI_SMBIOS_PROTOCOL_GUID \
  { 0x5B1B31A1, 0x9562, 0x11D2, \
    { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } }

// {03583FF6-36CB-4049-947E-B9B39F4AFAF7}  -- second SMBIOS protocol instance
#define SMBIOS_PROTOCOL_GUID_2 \
  { 0x03583FF6, 0x36CB, 0x4049, \
    { 0x94, 0x7E, 0xB9, 0xB3, 0x9F, 0x4A, 0xFA, 0xF7 } }

// {0FD96974-23AA-DC4C-B9CB-98D17750322A}
#define EFI_HII_FONT_PROTOCOL_GUID \
  { 0x0FD96974, 0x23AA, 0xDC4C, \
    { 0xB9, 0xCB, 0x98, 0xD1, 0x77, 0x50, 0x32, 0x2A } }

// {EF9FC172-A1B2-9346-B327-6D32FC416042}
#define EFI_HII_STRING_PROTOCOL_GUID \
  { 0xEF9FC172, 0xA1B2, 0x9346, \
    { 0xB3, 0x27, 0x6D, 0x32, 0xFC, 0x41, 0x60, 0x42 } }

// {587E7258-CC50-4F79-8209-CA291FC1A10F}
#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \
  { 0x587E7258, 0xCC50, 0x4F79, \
    { 0x82, 0x09, 0xCA, 0x29, 0x1F, 0xC1, 0xA1, 0x0F } }

// {E9CA4775-8657-FC47-97E7-7ED65A084324}
#define EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID \
  { 0xE9CA4775, 0x8657, 0xFC47, \
    { 0x97, 0xE7, 0x7E, 0xD6, 0x5A, 0x08, 0x43, 0x24 } }

// {31A6406A-DF6B-464E-B2A2-EBAA89C40920}
#define EFI_HII_IMAGE_PROTOCOL_GUID \
  { 0x31A6406A, 0xDF6B, 0x464E, \
    { 0xB2, 0xA2, 0xEB, 0xAA, 0x89, 0xC4, 0x09, 0x20 } }

// {05AD34BA-6F02-1442-952E-4DA0398E2BB9}
#define EFI_DXE_SERVICES_TABLE_GUID \
  { 0x05AD34BA, 0x6F02, 0x1442, \
    { 0x95, 0x2E, 0x4D, 0xA0, 0x39, 0x8E, 0x2B, 0xB9 } }

// {7739F24C-D793-D411-9A3A-0090273FC14D}
#define EFI_HOB_LIST_GUID \
  { 0x7739F24C, 0xD793, 0xD411, \
    { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }

// {8BE4DF61-CA93-11D2-AA0D-00E098032B8C}
#define EFI_GLOBAL_VARIABLE_GUID \
  { 0x8BE4DF61, 0xCA93, 0x11D2, \
    { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } }

// {FD480A76-B134-F74E-ADFE-B0E054639807}
#define EFI_MM_PCI_BASE_PROTOCOL_GUID \
  { 0xFD480A76, 0xB134, 0xF74E, \
    { 0xAD, 0xFE, 0xB0, 0xE0, 0x54, 0x63, 0x98, 0x07 } }

// Board-specific SMBIOS config GUID (UBA, at 0x38F0):
// {E2D6FD7B-2E3B-FD46-BDED-512A7F032AA0}
#define UBA_SMBIOS_CONFIG_GUID_EXECB1 \
  { 0xE2D6FD7B, 0x2E3B, 0xFD46, \
    { 0xBD, 0xED, 0x51, 0x2A, 0x7F, 0x03, 0x2A, 0xA0 } }

// UBA SMBIOS Data Protocol GUID (at 0x3200):
// {E03E0D46-5263-4548-B0A4-58D57B3177E2}
#define UBA_SMBIOS_DATA_PROTOCOL_GUID \
  { 0xE03E0D46, 0x5263, 0x4548, \
    { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }

// DebugLib protocol GUID (at 0x31E0):
// {36232936-0E76-C831-A13A-3AF2FC1C3932}
#define GARMIN_DEBUG_LIB_PROTOCOL_GUID \
  { 0x36232936, 0x0E76, 0xC831, \
    { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }

// UBA SMBIOS protocol (at 0x3900):
// {AAC6CAFD-C642-440A-B958-9FD4C84B50EA}
#define UBA_SMBIOS_PROTOCOL_GUID \
  { 0xAAC6CAFD, 0xC642, 0x440A, \
    { 0xB9, 0x58, 0x9F, 0xD4, 0xC8, 0x4B, 0x50, 0xEA } }

// ============================================================================
// SMBIOS String Types
// ============================================================================

#define SMBIOS_STRING_TYPE_BASEBOARD    8   ///< SMBIOS Type 2 (Baseboard)
#define SMBIOS_STRING_TYPE_SLOT         9   ///< SMBIOS Type 9 (System Slot)
#define SMBIOS_STRING_TYPE_ONBOARD_DEV  41  ///< SMBIOS Type 41 (Onboard Device)

// ============================================================================
// SMBIOS String Record Buffer Format
// ============================================================================

#pragma pack(push, 1)

typedef struct {
  UINT8   Type;         ///< SMBIOS structure type (e.g., 8=Type2)
  UINT8   FieldCount;   ///< Number of string fields in this record
  UINT16  Handle;       ///< SMBIOS structure handle (0xFFFE = placeholder)
  CHAR8   Strings[1];   ///< Variable-length concatenated string data
} SMBIOS_STRING_RECORD;

/**
 * SMBIOS String Descriptor Entry
 *
 * Each entry describes one SMBIOS string field to update.
 * The descriptor table is embedded as local variable initialization
 * in BuildSmbiosStringRecord (sub_77C), with 30 entries for Type2,
 * plus Type9 and Type41 entries from sub_A20 and sub_D98.
 */
typedef struct {
  UINT8   Type;         ///< SMBIOS structure type
  UINT8   Number;       ///< Field number within the SMBIOS structure
  UINT16  StringId;     ///< HII string token ID
  UINT8   Encoding;     ///< String format/encoding
  UINT8   Offset;       ///< Byte offset in output record buffer
  UINT8   MaxLength;    ///< Maximum string length allowed
  UINT8   Flags;        ///< Flags / attribute bits
  UINT8   Reserved1;    ///< Reserved (part of encoding high bits)
  UINT8   Reserved2;    ///< Reserved (part of maxlen high bits)
} SMBIOS_STRING_DESCRIPTOR;

#pragma pack(pop)

// ============================================================================
// UBA SMBIOS Data Protocol Interface
// ============================================================================

typedef struct _UBA_SMBIOS_DATA_PROTOCOL UBA_SMBIOS_DATA_PROTOCOL;

/**
 * UBA SMBIOS Data protocol (located via LocateProtocol at 0x3200).
 */
struct _UBA_SMBIOS_DATA_PROTOCOL {
  // ... standard protocol header ...
  // +8: reserved
  // +16: SetSmbiosData(This, Guid, Buffer, Size)
  EFI_STATUS (EFIAPI *SetSmbiosData)(
    IN UBA_SMBIOS_DATA_PROTOCOL *This,
    IN EFI_GUID                  *Guid,
    IN VOID                      *Buffer,
    IN UINTN                     Size
    );
};

// ============================================================================
// MM PCIe Base Protocol Interface
// ============================================================================

typedef struct _MM_PCI_BASE_PROTOCOL MM_PCI_BASE_PROTOCOL;

struct _MM_PCI_BASE_PROTOCOL {
  // ... standard protocol header ...
  // +24: ExecutePciCfg(Address)
  UINT32 (EFIAPI *PciCfgRead)(IN UINT32 *Address);
};

// ============================================================================
// DebugLib Protocol Interface
// ============================================================================

typedef struct _GARMIN_DEBUG_LIB_PROTOCOL GARMIN_DEBUG_LIB_PROTOCOL;

struct _GARMIN_DEBUG_LIB_PROTOCOL {
  // +0: reserved
  // +8: Assert(File, Line, Expression)
  VOID (EFIAPI *Assert)(
    IN CHAR8    *File,
    IN UINTN    Line,
    IN CHAR8    *Expression
    );
  // ... additional methods ...
};

// ============================================================================
// Global Variables (in .data section)
// ============================================================================

extern EFI_HANDLE           gImageHandle;
extern EFI_SYSTEM_TABLE     *gST;
extern EFI_BOOT_SERVICES    *gBS;
extern EFI_RUNTIME_SERVICES *gRT;
extern EFI_DXE_SERVICES     *gDS;

extern EFI_HII_HANDLE       gSmbiosStringPackHandle;
extern VOID                 *mHobList;
extern VOID                 *mHiiFont;
extern VOID                 *mHiiString;
extern VOID                 *mHiiDatabase;
extern VOID                 *mHiiPackageList;
extern VOID                 *mHiiPackageListProtocol;
extern VOID                 *mSmbiosProtocol1;  // for string add
extern VOID                 *mSmbiosProtocol2;  // for string remove
extern VOID                 *mSmbiosProtocol3;  // for string add (2nd instance)
extern VOID                 *mSmbiosProtocol4;  // for remove+add
extern VOID                 *mMmPciUsra;        // MM PCIe base protocol
extern VOID                 *mDebugProtocol;    // DebugLib protocol
extern VOID                 *mUbaSmbiosDataProtocol;
extern EFI_GUID             mSmbiosConfigGuid;  // board-specific config GUID

// ============================================================================
// Function Prototypes
// ============================================================================

/**
 * UEFI DXE Driver Entry Point
 *
 * @param[in] ImageHandle  Handle for this driver image
 * @param[in] SystemTable  Pointer to the UEFI System Table
 * @return EFI_SUCCESS or error code
 */
EFI_STATUS
EFIAPI
SmbiosDataUpdateDxeEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  );

/**
 * Global initialization routine
 *
 * Saves ImageHandle, SystemTable, BootServices, RuntimeServices globals.
 * Locates HII Font, HII Database, HII Package List, HII String protocols.
 * Finds DXE Services Table. Optionally locates MM PCIe base protocol.
 *
 * @param[in] ImageHandle  Driver image handle
 * @param[in] SystemTable  UEFI System Table
 * @return EFI_SUCCESS or error from protocol lookups
 */
EFI_STATUS
EFIAPI
SmbiosDataUpdateInit (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  );

/**
 * Main driver entry -- called after init
 *
 * Opens UBA config protocol from ImageHandle, registers HII string package
 * list, then calls SmbiosDataUpdateDispatch via UBA protocol.
 *
 * @param[in] ImageHandle  Driver image handle
 * @return EFI_SUCCESS or error code
 */
EFI_STATUS
EFIAPI
SmbiosDataUpdateEntry (
  IN EFI_HANDLE ImageHandle
  );

/**
 * SMBIOS data update dispatch
 *
 * Main orchestrator: builds 30 Type2 (Baseboard), 8 Type9 (System Slot),
 * and 4 Type41 (Onboard Device) SMBIOS string records, then updates
 * the SMBIOS tables.
 *
 * Uses 768-byte working buffer (allocated via AllocateZeroPool).
 * Phase 1: 30 iterations for SMBIOS Type 2 strings
 * Phase 2: 8 iterations for SMBIOS Type 9 strings (sub_A20)
 * Phase 3: 4 iterations for SMBIOS Type 41 strings (sub_D98)
 *
 * @return EFI_SUCCESS or error code
 */
EFI_STATUS
EFIAPI
SmbiosDataUpdateDispatch (
  VOID
  );

/**
 * Build a single SMBIOS string record in the output buffer
 *
 * Creates a formatted SMBIOS record from a descriptor table entry.
 * The descriptor table (30 entries) is embedded as local variable initializer
 * (data at v19..v32). Each 10-byte entry defines Type, Number, StringId,
 * Encoding, Offset, MaxLength, and Flags for one SMBIOS field.
 *
 * @param[out] Buffer   Output buffer for the SMBIOS string record
 * @param[in]  Index    Index into the descriptor table (0-29 for Type2)
 * @return EFI_SUCCESS, EFI_OUT_OF_RESOURCES, or EFI_INVALID_PARAMETER
 */
EFI_STATUS
EFIAPI
BuildSmbiosStringRecord (
  OUT UINT8    *Buffer,
  IN  UINTN    Index
  );

/**
 * Build SMBIOS Type 9 (System Slot) record
 *
 * Creates a Type 9 record with board-specific slot configuration.
 * Uses MmPciBase protocol (sub_2064) to probe for slot presence
 * via PCIe config reads. Handles 8 slot positions (index 0-7).
 *
 * @param[out] Buffer   Output buffer for the SMBIOS record
 * @param[in]  Index    Slot index (0-7)
 * @return EFI_SUCCESS, EFI_NOT_FOUND, or EFI_INVALID_PARAMETER
 */
EFI_STATUS
EFIAPI
BuildSmbiosType9Record (
  OUT UINT8    *Buffer,
  IN  UINTN    Index
  );

/**
 * Build SMBIOS Type 41 (Onboard Device) record
 *
 * Creates a Type 41 record with onboard device information.
 * Uses MmPciBase protocol (sub_2064) to probe for device presence.
 * Handles 4 device positions (index 0-3).
 *
 * @param[out] Buffer   Output buffer for the SMBIOS record
 * @param[in]  Index    Device index (0-3)
 * @return EFI_SUCCESS, EFI_NOT_FOUND, or EFI_INVALID_PARAMETER
 */
EFI_STATUS
EFIAPI
BuildSmbiosType41Record (
  OUT UINT8    *Buffer,
  IN  UINTN    Index
  );

/**
 * Allocate + Locate DebugLib protocol (cached in mDebugProtocol)
 *
 * Checks CMOS register 0x4B for debug level. Returns cached protocol
 * pointer or attempts to locate it.
 *
 * @return DebugLib protocol pointer, or NULL if debug is disabled
 */
GARMIN_DEBUG_LIB_PROTOCOL *
EFIAPI
GetDebugLibProtocol (
  VOID
  );

/**
 * Debug print (with CMOS SKU filtering)
 *
 * Reads CMOS register 0x4B (NMI index 0x4B) to determine debug level.
 * Only prints if the error level mask matches.
 *
 * @param[in]  ErrorLevel  Error level bitmask
 * @param[in]  Format      Format string
 * @param[in]  ...         Variable arguments
 */
VOID
EFIAPI
DebugPrint (
  IN UINTN       ErrorLevel,
  IN CONST CHAR8 *Format,
  ...
  );

/**
 * Assert handler
 *
 * Calls DebugLib->Assert(File, Line, Expression)
 *
 * @param[in] File        Source file name
 * @param[in] Line        Line number
 * @param[in] Expression  Assertion expression string
 */
VOID
EFIAPI
AssertHandler (
  IN CHAR8 *File,
  IN UINTN Line,
  IN CHAR8 *Expression
  );

/**
 * Copy 16-byte GUID (two 64-bit writes)
 *
 * @param[out] Dst   Destination GUID
 * @param[in]  Src   Source GUID
 * @return Pointer to destination
 */
EFI_GUID *
EFIAPI
CopyGuid (
  OUT EFI_GUID *Dst,
  IN  EFI_GUID *Src
  );

/**
 * Compare two GUIDs as 128-bit values
 *
 * @param[in]  Guid1  First GUID
 * @param[in]  Guid2  Second GUID
 * @return TRUE if equal, FALSE otherwise
 */
BOOLEAN
EFIAPI
CompareGuid (
  IN EFI_GUID *Guid1,
  IN EFI_GUID *Guid2
  );

/**
 * Zero memory (wrapper with assertion checks)
 *
 * @param[out] Buffer  Buffer to zero
 * @param[in]  Length  Number of bytes to zero
 * @return Pointer to buffer
 */
VOID *
EFIAPI
ZeroMem (
  OUT VOID   *Buffer,
  IN  UINTN  Length
  );

/**
 * Read UINT32 from potentially unaligned address
 *
 * @param[in]  Buffer  Pointer to read from
 * @return The UINT32 value
 */
UINT32
EFIAPI
ReadUnaligned32 (
  IN CONST UINT32 *Buffer
  );

/**
 * Read UINT64 from potentially unaligned address
 *
 * @param[in]  Buffer  Pointer to read from
 * @return The UINT64 value
 */
UINT64
EFIAPI
ReadUnaligned64 (
  IN CONST UINT64 *Buffer
  );

/**
 * Write UINT64 to potentially unaligned address
 *
 * @param[out] Buffer  Destination pointer
 * @param[in]  Value   Value to write
 * @return The value written
 */
UINT64
EFIAPI
WriteUnaligned64 (
  OUT UINT64 *Buffer,
  IN  UINT64 Value
  );

/**
 * Allocate boot services pool memory
 *
 * @param[in]  Size     Allocation size
 * @return Pointer to allocated memory, or NULL on failure
 */
VOID *
EFIAPI
AllocatePool (
  IN UINTN Size
  );

/**
 * Allocate + zero memory
 *
 * @param[in]  Size     Allocation size
 * @return Pointer to zeroed memory, or NULL on failure
 */
VOID *
EFIAPI
AllocateZeroPool (
  IN UINTN Size
  );

/**
 * Free pool memory with ASSERT on failure
 */
VOID
EFIAPI
FreePool (
  IN VOID *Buffer
  );

/**
 * Find configuration table by GUID in SystemTable
 *
 * Searches SystemTable->ConfigurationTable[] for matching GUID.
 *
 * @param[in]  TableGuid  GUID to find
 * @param[out] Table      Output pointer to the table data
 * @return EFI_SUCCESS or EFI_NOT_FOUND
 */
EFI_STATUS
EFIAPI
GetConfigTable (
  IN  EFI_GUID  *TableGuid,
  OUT VOID      **Table
  );

/**
 * Get platform language via RuntimeServices->GetVariable
 *
 * Reads the "PlatformLang" UEFI global variable.
 *
 * @param[out] Value  Allocated string containing the platform language
 * @return EFI_SUCCESS, EFI_NOT_FOUND, or EFI_OUT_OF_RESOURCES
 */
EFI_STATUS
EFIAPI
GetPlatformLang (
  OUT CHAR16 **Value
  );

/**
 * Match supported language against available languages
 *
 * Parses a semicolon-separated list of supported languages and finds
 * the best match for the target language, with prefix matching support.
 *
 * @param[in]  SupportedLanguages  Semicolon-separated language list
 * @param[in]  IsoLanguage         Whether input uses ISO 639-2 codes
 * @param[in]  ...                 Variable list of languages to try
 * @return Pointer to matched language string, or NULL
 */
CHAR8 *
EFIAPI
GetSupportedLanguage (
  IN CHAR8   *SupportedLanguages,
  IN BOOLEAN IsoLanguage,
  ...
  );

/**
 * HobLib initialization -- find HOB list
 *
 * Locates the HOB list via SystemTable->ConfigurationTable.
 *
 * @return HOB list pointer (cached in mHobList)
 */
VOID *
EFIAPI
HobLibInit (
  VOID
  );

/**
 * Get localized SMBIOS string from HII
 *
 * Uses HII Font protocol to retrieve a localized string by string ID.
 * Handles language matching via GetPlatformLang and GetSupportedLanguage.
 *
 * @param[in]  HiiHandle HII handle for the string package
 * @param[in]  StringId  HII string token ID
 * @param[in]  Reserved1 Unused/alignment parameter
 * @param[in]  Reserved2 Unused/alignment parameter
 * @return Pointer to the localized ASCII string, or NULL on failure
 */
CHAR8 *
EFIAPI
GetHiiString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN EFI_STRING_ID   StringId,
  IN UINTN           Reserved1,
  IN UINTN           Reserved2
  );

/**
 * Register HII package list and return HII handle
 *
 * Takes a GUID and an array of null-terminated strings, concatenates
 * them into an HII package list, and registers it via HII Database.
 *
 * @param[in]  PackageListGuid  GUID for the package list
 * @param[out] ImageHandle      EFI handle for the driver image
 * @param[in]  StringArray      Array of string pointers (terminated by NULL)
 * @param[in]  Reserved         Unused
 * @return HII handle, or NULL on failure
 */
EFI_HII_HANDLE
EFIAPI
RegisterHiiPackageList (
  IN  EFI_GUID     *PackageListGuid,
  OUT EFI_HANDLE   *ImageHandle,
  IN  CONST CHAR8  **StringArray,
  IN  UINTN        Reserved
  );

/**
 * Get supported languages for an HII handle
 *
 * Retrieves the list of languages supported by a given HII string package.
 *
 * @param[in]  HiiHandle  HII handle
 * @return Allocated string with supported languages, or NULL
 */
CHAR8 *
EFIAPI
GetHiiSupportedLanguages (
  IN EFI_HII_HANDLE HiiHandle
  );

/**
 * Update a single SMBIOS string field
 *
 * Complex operation: takes an existing SMBIOS string record, finds a
 * specific field slot, and inserts or replaces the string. Handles
 * string overlap detection and safe copy.
 *
 * @param[in,out] Dst     SMBIOS string record buffer (input/output)
 * @param[in]     Src     Source string to insert
 * @param[in]     FieldId Field number within the SMBIOS structure
 * @return EFI_SUCCESS or error
 */
EFI_STATUS
EFIAPI
UpdateSmbiosStringField (
  IN OUT CHAR8  *Dst,
  IN     CHAR8  *Src,
  IN     UINTN  FieldId
  );

/**
 * Find the next SMBIOS structure after current field position
 *
 * Parses a packed SMBIOS structure buffer and finds the structure
 * that follows the field at the given position.
 *
 * @param[in,out] pBuffer  Pointer to SMBIOS buffer pointer (updated)
 * @param[out]    pCount   Total count of structures traversed
 * @return EFI_SUCCESS or overflow error
 */
EFI_STATUS
EFIAPI
GetSmbiosStructuresAfterField (
  IN OUT CHAR8         **pBuffer,
  OUT    UINT64        *pCount
  );

/**
 * Add a string to the SMBIOS table via SMBIOS protocol
 *
 * Uses SMBIOS protocol's Add/Remove functions. Locates the protocol
 * on first call and caches it.
 *
 * @param[in]  Buffer  SMBIOS string record buffer
 * @return EFI_SUCCESS or error from SMBIOS protocol
 */
EFI_STATUS
EFIAPI
AddSmbiosString (
  IN VOID *Buffer
  );

/**
 * Find first matching SMBIOS string by type
 *
 * Uses SMBIOS protocol GetNext function to find the first string
 * record matching the specified type.
 *
 * @param[in]  Type    SMBIOS string type to find
 * @param[in]  Index   Which SMBIOS protocol instance to use
 * @param[out] Handle  Output SMBIOS handle
 * @return EFI_SUCCESS, EFI_NOT_FOUND, or protocol error
 */
EFI_STATUS
EFIAPI
FindFirstSmbiosString (
  IN  CHAR8         Type,
  IN  UINTN         Index,
  OUT EFI_HANDLE    *Handle
  );

/**
 * Remove old SMBIOS string then add replacement
 *
 * Atomically removes the first string of a given type and adds
 * a new one.
 *
 * @param[in]  Type    SMBIOS string type
 * @param[in]  Param2  Second parameter
 * @param[in]  Param3  Third parameter
 * @return EFI_SUCCESS or error
 */
EFI_STATUS
EFIAPI
RemoveAndAddSmbiosString (
  IN CHAR8  Type,
  ...
  );

/**
 * Remove all SMBIOS strings of a given type
 *
 * Enumerates and removes all strings of the specified type
 * via the SMBIOS protocol.
 *
 * @param[in]  Type  SMBIOS type to remove
 * @return EFI_SUCCESS or error
 */
EFI_STATUS
EFIAPI
RemoveAllSmbiosStringsOfType (
  IN CHAR8 Type
  );

/**
 * Write PCIe config register via MM PCIe protocol
 *
 * Encodes bus/device/function into address:
 *   ((Func & 7) | (8 * ((Dev & 0x1F) | (32 * Bus)))) << 12
 * Reads the register value at offset+25 from the result.
 *
 * @param[in]  Bus    PCIe bus number
 * @param[in]  Device PCIe device number
 * @param[in]  Func   PCIe function number
 * @return Pointer to the register value
 */
UINT32 *
EFIAPI
MmPciWriteConfig (
  IN UINT8  Bus,
  IN UINT8  Device,
  IN UINT8  Func
  );

/**
 * Copy memory with overlap-safe handling
 *
 * Wrapper around CopyMemBase (sub_300) with assertion checks.
 * If destination and source overlap in a forward direction, uses
 * reverse copy.
 *
 * @param[out] Dst    Destination buffer
 * @param[in]  Src    Source buffer
 * @param[in]  Count  Number of bytes to copy
 * @return Pointer to destination
 */
VOID *
EFIAPI
CopyMem (
  OUT VOID       *Dst,
  IN  CONST VOID *Src,
  IN  UINTN      Count
  );

/**
 * Return ASCII string length (max PcdMaximumAsciiStringLength = 0xF4240)
 *
 * @param[in]  String  ASCII string (null-terminated)
 * @return Length of the string
 */
UINTN
EFIAPI
AsciiStrLen (
  IN CONST CHAR8 *String
  );

/**
 * Compare two ASCII strings (up to n characters)
 *
 * @param[in]  FirstString   First string
 * @param[in]  SecondString  Second string
 * @param[in]  Length         Maximum comparison length
 * @return 0 if equal, difference otherwise
 */
INTN
EFIAPI
AsciiStrnCmp (
  IN CONST CHAR8  *FirstString,
  IN CONST CHAR8  *SecondString,
  IN UINTN        Length
  );

/**
 * Return UCS-2 string length (max PcdMaximumUnicodeStringLength)
 *
 * @param[in]  String  UCS-2 string (null-terminated, must be 2-byte aligned)
 * @param[in]  MaxLen  Maximum length to check
 * @return Length of the string (in characters), or 0 on error
 */
UINTN
EFIAPI
StrLen (
  IN CONST CHAR16 *String,
  IN UINTN        MaxLen
  );

/**
 * Safe ASCII string length (maximum n)
 *
 * @param[in]  String   ASCII string (null-terminated)
 * @param[in]  MaxSize  Maximum length to check
 * @return Length of the string (min of strlen, MaxSize-1), or 0
 */
UINTN
EFIAPI
AsciiStrnLenS (
  IN CONST CHAR8  *String,
  IN UINTN        MaxSize
  );

/**
 * Convert UCS-2 string to ASCII (safe)
 *
 * Converts a UCS-2 (UTF-16LE) string to an ASCII string with
 * overlap protection and bounds checking. Each UCS-2 character
 * must be < 0x100.
 *
 * @param[in]   Source       UCS-2 source string (2-byte aligned)
 * @param[out]  Destination  ASCII destination buffer (8-bit)
 * @param[in]   DestMax      Maximum characters in destination
 * @return EFI_SUCCESS, EFI_BUFFER_TOO_SMALL, or EFI_INVALID_PARAMETER
 */
EFI_STATUS
EFIAPI
UnicodeStrnToAsciiStrS (
  IN  CONST CHAR16 *Source,
  OUT CHAR8        *Destination,
  IN  UINTN        DestMax
  );

#endif // SMBIOS_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXECB1_H