Newer
Older
AMI-Aptio-BIOS-Reversed / Platform / SetupPlatform.c
@Ajax Dong Ajax Dong 2 days ago 30 KB Init
/**
 * @file SetupPlatform.c
 * @brief Platform DXE Setup Driver - Purley Refresh (HR650X)
 *
 * This is the DxePlatform Setup driver from the Lenovo HR650X BIOS.
 * It manages platform setup configuration via UEFI HII (Human Interface Infrastructure),
 * including BIOS setup options, ME (Management Engine) configuration,
 * disk information records, and boot option maintenance.
 *
 * Source files:
 *   - PurleyRpPkg/Platform/Dxe/Setup/SetupPlatform.c (main)
 *   - PurleyRpPkg/Platform/Dxe/Setup/SetupInfoRecords.c
 *   - PurleyRpPkg/Library/SetupLib/DxeSetupLib.c
 *   - PurleyRpPkg/Platform/Dxe/Setup/MeSpsSetup.c
 *
 * Image: Platform.efi (index 0340)
 * Size: 0x405a0 bytes
 * Arch: x86-64 (UEFI DXE driver)
 * IDA Port: 13345
 */

#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiLib.h>
#include <Protocol/HiiDatabase.h>
#include <Protocol/HiiPackageList.h>
#include <Protocol/HiiString.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/HiiConfigKeyword.h>

// ============================================================================
// Global Variables
// ============================================================================

EFI_HANDLE           gImageHandle       = NULL;  // 0xFED8
EFI_SYSTEM_TABLE    *gST                = NULL;  // 0xFEC8
EFI_BOOT_SERVICES   *gBS                = NULL;  // 0xFED0
EFI_RUNTIME_SERVICES *gRT               = NULL;  // 0xFEE0
EFI_DXE_SERVICES    *gDS                = NULL;  // 0xFEF8

// Protocol pointers
VOID *gHiiDatabase        = NULL;  // 0xFF68
VOID *gHiiString          = NULL;  // 0xFF88
VOID *gHiiPackageList     = NULL;  // 0xFF78
VOID *gHiiConfigRouting   = NULL;  // 0xFF70
VOID *gHiiConfigAccess    = NULL;  // 0xFF80
VOID *mUsra               = NULL;  // 0xFFA0
VOID *mPciUsra            = NULL;  // 0xFF00

// ============================================================================
// Forward Declarations
// ============================================================================

/* Entry Point */
EFI_STATUS EFIAPI
_ModuleEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  );

/* Driver Init and Main Logic */
EFI_STATUS
DriverInit (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  );

EFI_STATUS
DriverEntryMain (
  IN EFI_HANDLE ImageHandle
  );

/* HII Callbacks */
EFI_STATUS EFIAPI
HiiRouteConfig (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
  IN CONST CHAR16                         *Configuration,
  OUT CHAR16                              **Progress
  );

EFI_STATUS EFIAPI
HiiExtractConfig (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
  IN CONST EFI_STRING                     Request,
  OUT EFI_STRING                          *Progress,
  OUT EFI_STRING                          *Results
  );

EFI_STATUS EFIAPI
SetupFormCallback (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
  IN EFI_BROWSER_ACTION                   Action,
  IN EFI_QUESTION_ID                      QuestionId,
  IN UINT8                                *Type,
  IN EFI_IFR_TYPE_VALUE                   *Value
  );

/* Setup Functions */
VOID
PopulateDiskInfoRecords (
  VOID
  );

EFI_STATUS
MeInitSpsInfo (
  VOID
  );

EFI_STATUS
MeExtractSpsConfigOnSetupEnter (
  IN VOID *MeRcConfiguration
  );

EFI_STATUS
InstallSetupVariables (
  VOID
  );

EFI_STATUS
GetAndSetSocketIioConfig (
  VOID
  );

// ============================================================================
// Library Functions
// ============================================================================

/**
  Copies a source ASCII string to destination with safety checks.

  @param[out] Dst      Destination buffer.
  @param[in]  DstSize  Size of destination buffer in bytes.
  @param[in]  Src      Source ASCII string.

  @return RETURN_SUCCESS if the string was copied successfully.
          RETURN_BUFFER_TOO_SMALL if the destination buffer was too small.
 */
RETURN_STATUS
AsciiStrCpyS (
  OUT CHAR8       *Dst,
  IN  UINTN       DstSize,
  IN  CONST CHAR8 *Src
  );

/**
  Copies memory between buffers, handling overlapping regions.

  @param[out] Dst     Pointer to destination buffer.
  @param[in]  Src     Pointer to source buffer.
  @param[in]  Count   Number of bytes to copy.

  @return Dst.
 */
VOID *
CopyMemOverlap (
  OUT VOID       *Dst,
  IN  CONST VOID *Src,
  IN  UINTN      Count
  );

/**
  Fills a buffer with zeros. Optimized for aligned buffers.

  @param[out] Buf   Buffer to zero.
  @param[in]  Size  Size in bytes.

  @return Buf.
 */
VOID *
ZeroMemFast (
  OUT VOID   *Buf,
  IN  UINTN  Size
  );

/**
  Fills a buffer with a 32-bit pattern.

  @param[out] Buf    Buffer to fill.
  @param[in]  Value  32-bit pattern to fill with.
  @param[in]  Count  Number of bytes to fill.

  @return Buf.
 */
VOID *
SetMem32 (
  OUT VOID   *Buf,
  IN  UINT32 Value,
  IN  UINTN  Count
  );

/**
  Reads a 32-bit I/O port, stalling the CPU briefly.

  @param[in]  Port   I/O port address.

  @return Value read from the port.
 */
UINT32
IoRead32Stall (
  IN  UINTN  Port
  );

/**
  Disables CPU interrupts (CLI instruction).

  @return Previous interrupt state.
 */
BOOLEAN
DisableInterrupts (
  VOID
  );

/**
  Enables CPU interrupts (STI instruction).
 */
VOID
EnableInterrupts (
  VOID
  );

/**
  Disables CPU caching.
 */
VOID
DisableCache (
  VOID
  );

/**
  Checks CPU features via CPUID instruction.

  @param[in]  Leaf    CPUID leaf.
  @param[in]  SubLeaf CPUID sub-leaf.

  @return CPUID feature flags.
 */
UINT32
CpuIdFeatureCheck (
  IN  UINT32 Leaf,
  IN  UINT32 SubLeaf
  );

/**
  Reads a Model-Specific Register (MSR).

  @param[in]  Index  MSR index.

  @return 64-bit MSR value.
 */
UINT64
ReadMsr (
  IN  UINT32  Index
  );

// ============================================================================
// ME (Management Engine) Configuration Functions
// ============================================================================

/**
  Configures ME SPS (Server Platform Services) information.
  Sets up ME-related setup options including ME mode, firmware mode,
  HECI interface, PECI, and various ME features.
 */
EFI_STATUS
MeSetupConfiguration (
  VOID
  );

/**
  Handles ME firmware update operations.

  @param[in]  MeRcConfiguration  Pointer to ME RC configuration data.
 */
EFI_STATUS
MeFirmwareUpdateHandler (
  IN VOID *MeRcConfiguration
  );

/**
  Extracts SPS configuration data from ME registers.

  @param[in]  MeRcConfiguration  Pointer to ME RC configuration data.
 */
VOID
ExtractMeSpsConfig (
  IN VOID *MeRcConfiguration
  );

// ============================================================================
// Setup Configuration Functions
// ============================================================================

/**
  Main entry point that installs HII Config Access protocol and
  registers the setup form callback handlers.

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

  @return EFI_STATUS.
 */
EFI_STATUS
DxePlatformDriverEntry (
  IN EFI_HANDLE ImageHandle
  );

/**
  Handles form actions during setup navigation.

  @param[in]  Action     The browser action.
  @param[in]  QuestionId The question identifier.
  @param[in]  Type       The type of value.

  @return EFI_STATUS.
 */
EFI_STATUS
HiiFormActions (
  IN  EFI_BROWSER_ACTION Action,
  IN  EFI_QUESTION_ID    QuestionId,
  IN  UINT8              *Type
  );

/**
  Routes configuration requests to the appropriate handler.

  @param[in]  ConfigHdr   Configuration header.
  @param[out] Progress    Progress pointer.
  @param[out] Results     Results buffer.

  @return EFI_STATUS.
 */
EFI_STATUS
HiiConfigRouting (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
  IN  CONST EFI_STRING                     Configuration,
  OUT EFI_STRING                           *Progress
  );

/**
  Handles setup configuration routing.

  @param[in]  This         Pointer to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Action       The browser action.
  @param[in]  QuestionId   The question identifier.
  @param[in]  Type         The type of value.
  @param[in]  Value        The value.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupBootOptionMaint (
  VOID
  );

/**
  Initializes setup policy structures.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupPolicyInit (
  VOID
  );

/**
  Gets a setup string from HII database.

  @param[in]  StringId  The string ID.
  @param[out] Buffer    Buffer to hold the string.
  @param[in]  Size      Buffer size.

  @return EFI_STATUS.
 */
EFI_STATUS
GetSetupString (
  IN  EFI_STRING_ID  StringId,
  OUT EFI_STRING     Buffer,
  IN  UINTN          Size
  );

/**
  Sets a setup configuration variable.

  @param[in]  VariableName  The name of the variable.
  @param[in]  VendorGuid    The vendor GUID.
  @param[in]  Buffer        Data buffer.
  @param[in]  Size          Data size.

  @return EFI_STATUS.
 */
EFI_STATUS
SetSetupVariable (
  IN  CHAR16    *VariableName,
  IN  EFI_GUID  *VendorGuid,
  IN  VOID      *Buffer,
  IN  UINTN     Size
  );

/**
  Writes a protocol variable for setup communication.

  @param[in]  Buffer   Data buffer.
  @param[in]  Size     Data size.

  @return EFI_STATUS.
 */
EFI_STATUS
WriteProtocolVar (
  IN  VOID   *Buffer,
  IN  UINTN  Size
  );

/**
  Installs all setup-related UEFI variables.

  @return EFI_STATUS.
 */
EFI_STATUS
InstallSetupVariables (
  VOID
  );

/**
  Migrates setup variables from old to new format.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupVarMigrate (
  VOID
  );

/**
  Checks the size of a setup variable.

  @param[in]  Name        Variable name.
  @param[in]  Guid        Variable GUID.

  @return Variable size or 0 if not found.
 */
UINTN
SetupVarSizeCheck (
  IN  CHAR16    *Name,
  IN  EFI_GUID  *Guid
  );

// ============================================================================
// Disk Info Records (SetupInfoRecords.c)
// ============================================================================

/**
  Enumerates ATA/ATAPI devices and builds disk information strings
  for display in the BIOS setup utility.

  For each detected ATA device:
  1. Reads IDENTIFY data via ATA protocol
  2. Extracts model name, serial number, and capacity
  3. Formats as " - XX GB" or " - ATAPI" depending on device type
  4. Populates the setup form with disk info records
 */
VOID
PopulateDiskInfoRecords (
  VOID
  );

/**
  Gets or sets setup info records.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupRecordsGetSet (
  VOID
  );

/**
  Lists all setup info records.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupRecordsList (
  VOID
  );

/**
  Displays setup info records in the HII form.

  @return VOID.
 */
VOID
SetupInfoRecordsDisplay (
  VOID
  );

/**
  Navigates through setup records.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupRecordsNavigate (
  VOID
  );

/**
  Writes setup info records to the HII database.

  @param[in]  Token    HII string token.
  @param[in]  String   String to write.
  @param[in]  Buffer   Additional data buffer.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupInfoRecordsWriter (
  IN  EFI_STRING_ID  Token,
  IN  CONST CHAR16   *String,
  IN  VOID           *Buffer
  );

// ============================================================================
// HII Infrastructure Functions
// ============================================================================

/**
  Locates the HII setup protocol.

  @return EFI_HII_HANDLE or NULL.
 */
EFI_HII_HANDLE
LocateHiiSetup (
  VOID
  );

/**
  Registers HII package list to the HII database.

  @param[in]  PackageListGuid  GUID of the package list.
  @param[in]  PackageList      Pointer to package list.

  @return HII handle or 0 on error.
 */
EFI_HII_HANDLE
RegisterHiiPackage (
  IN  EFI_GUID  *PackageListGuid,
  IN  VOID      *PackageList
  );

/**
  Constructs a HII configuration request header.

  @param[in]  Guid   The configuration GUID (e.g., "IntelSetup").
  @param[in]  Handle The HII handle.

  @return Configuration request header string, or NULL.
 */
EFI_STRING
ConstructConfigHdr (
  IN  EFI_GUID       *Guid,
  IN  EFI_HII_HANDLE Handle
  );

/**
  Checks if the HII action flag was set.

  @param[in]  ConfigHdr  Configuration request header.

  @return TRUE if action flag was set.
 */
BOOLEAN
CheckActionFlag (
  IN  CONST EFI_STRING  ConfigHdr
  );

/**
  Extracts configuration from HII database.

  @param[in]  ConfigHdr  Configuration request header.

  @return EFI_STATUS.
 */
EFI_STATUS
ExtractConfig (
  IN  CONST EFI_STRING  ConfigHdr
  );

/**
  Packs HII strings into a buffer.

  @param[in]  Token   String token.
  @param[in]  Buffer  Destination buffer.

  @return EFI_STATUS.
 */
EFI_STATUS
HiiStringPacker (
  IN  EFI_STRING_ID  Token,
  IN  VOID           *Buffer
  );

/**
  Converts an HII string token to a string.

  @param[in]  Token   String token.

  @return String or NULL.
 */
EFI_STRING
HiiStringToToken (
  IN  EFI_STRING_ID  Token
  );

/**
  Converts an HII string token to a string (alternate).

  @param[in]  Token   String token.

  @return String or NULL.
 */
EFI_STRING
HiiStringToToken2 (
  IN  EFI_STRING_ID  Token
  );

// ============================================================================
// Variable Services
// ============================================================================

/**
  Initializes variable services in the S3 boot script.

  Initializes MMIO, I/O port ranges and S3 boot script tables
  for variable access during S3 resume path.
 */
VOID
VariableServicesInit (
  VOID
  );

/**
  Publishes an interface to the UEFI protocol database.

  @return EFI_STATUS.
 */
EFI_STATUS
PublishInterface (
  VOID
  );

/**
  Gets the size of a UEFI variable.

  @param[in]  Name     Variable name.
  @param[in]  Guid     Variable GUID.

  @return Size of the variable, or 0.
 */
UINTN
GetVariableSize (
  IN  CHAR16    *Name,
  IN  EFI_GUID  *Guid
  );

// ============================================================================
// Platform Setup Functions
// ============================================================================

/**
  Processes a setup configuration action from the HII browser.

  Handles SocketMPLink, SocketIOConfiguration, SocketProcessorConfiguration
  and other platform-specific setup options.

  @param[in]  Action       The browser action.
  @param[in]  QuestionId   The question identifier.
  @param[in]  Type         The type of value.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupActionHandler (
  IN  EFI_BROWSER_ACTION Action,
  IN  EFI_QUESTION_ID    QuestionId,
  IN  UINT8              *Type
  );

/**
  Handles value changes from the setup form.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupValueChangeHandler (
  VOID
  );

/**
  Main setup configuration route handler.

  @param[in]  Action       The browser action.
  @param[in]  QuestionId   The question identifier.
  @param[in]  Type         The type of value.
  @param[in]  Value        The value.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupRouteHandler (
  IN  EFI_BROWSER_ACTION Action,
  IN  EFI_QUESTION_ID    QuestionId,
  IN  UINT8              *Type,
  IN  EFI_IFR_TYPE_VALUE *Value
  );

/**
  Navigates IFR (Internal Forms Representation) elements.

  @return UINTN.
 */
UINTN
SetupIfrNavigator (
  VOID
  );

/**
  Dispatches setup actions to appropriate handlers.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupActionDispatcher (
  VOID
  );

/**
  Sets a setup configuration value.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupValueSetter (
  VOID
  );

/**
  Formats a setup value for display.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupValueFormatter (
  VOID
  );

/**
  Processes setup configuration options.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupOptionProcessor (
  VOID
  );

/**
  Queries a setup option.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupOptionQuery (
  VOID
  );

/**
  Checks a setup value.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupValueCheck (
  VOID
  );

/**
  Platform setup policy implementation.

  @return EFI_STATUS.
 */
EFI_STATUS
PlatformSetupPolicy (
  VOID
  );

/**
  Displays setup strings in the HII form.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupDisplayStrings (
  VOID
  );

/**
  Processes the complete setup configuration.

  @return EFI_STATUS.
 */
EFI_STATUS
ProcessSetupConfig (
  VOID
  );

/**
  Gets the size of a setup configuration variable.

  @return UINTN.
 */
UINTN
GetSetupVarSize (
  VOID
  );

/**
  Converts a boolean value to a display string.

  @param[in]  Value  Boolean value.

  @return Display string ("TRUE"/"FALSE").
 */
CHAR16 *
BoolToString (
  IN  BOOLEAN  Value
  );

/**
  Locates HII setup configuration protocol.

  @return EFI_HII_HANDLE or NULL.
 */
EFI_HII_HANDLE
LocateHiiSetupConfig (
  VOID
  );

// ============================================================================
// S3 Boot Script Support
// ============================================================================

/**
  Writes S3 boot script entries.

  @return EFI_STATUS.
 */
EFI_STATUS
WriteS3BootScript (
  VOID
  );

// ============================================================================
// MM PCI / USRA Protocol Access
// ============================================================================

/**
  Reads a value from MM PCI configuration space.

  @param[in]  Address   The PCI configuration address.

  @return The value read.
 */
UINT32
ReadCpuPciCfg (
  IN  UINT64  Address
  );

/**
  Reads a value from CPU PCI configuration for CpRc (CpuRC).

  @param[in]  Register  The CpRc register number.

  @return CpRc value.
 */
UINT32
ReadCpRcCfg (
  IN  UINT32  Register
  );

/**
  Reads from CpRc config space (alternate).

  @return UINT32.
 */
UINT32
ReadCpRcCfg2 (
  VOID
  );

/**
  Checks manufacturing mode flag.

  @return Manufacturing mode (non-zero = manufacturing mode).
 */
UINT8
GetManufacturingMode (
  VOID
  );

/**
  Gets the DXE services table.

  @return EFI_DXE_SERVICES pointer or NULL.
 */
EFI_DXE_SERVICES *
GetDxeServicesTable (
  VOID
  );

// ============================================================================
// Low-Level I/O Access (IoLib Replacement)
// ============================================================================

/**
  Reads a 8-bit MMIO/IO register.

  @param[in]  Address  The register address.

  @return The value read.
 */
UINT8
IoRead8 (
  IN  UINTN  Address
  );

/**
  Writes a 8-bit MMIO/IO register.

  @param[in]  Address  The register address.
  @param[in]  Value    The value to write.
 */
VOID
IoWrite8 (
  IN  UINTN  Address,
  IN  UINT8  Value
  );

/**
  Reads a 16-bit MMIO/IO register.

  @param[in]  Address  The register address.

  @return The value read.
 */
UINT16
IoRead16 (
  IN  UINTN  Address
  );

/**
  Writes a 16-bit MMIO/IO register.

  @param[in]  Address  The register address.
  @param[in]  Value    The value to write.
 */
VOID
IoWrite16 (
  IN  UINTN  Address,
  IN  UINT16 Value
  );

/**
  Reads a 32-bit MMIO/IO register.

  @param[in]  Address  The register address.

  @return The value read.
 */
UINT32
IoRead32 (
  IN  UINTN  Address
  );

/**
  Writes a 32-bit MMIO/IO register.

  @param[in]  Address  The register address.
  @param[in]  Value    The value to write.
 */
VOID
IoWrite32 (
  IN  UINTN  Address,
  IN  UINT32 Value
  );

/**
  Reads a 32-bit MMIO register (memory-mapped directly).

  @param[in]  Address  The MMIO address.

  @return The value read.
 */
UINT32
MmIoRead32 (
  IN  UINTN  Address
  );

/**
  Reads from PCI configuration space.

  @param[in]  Address  PCI config address.

  @return Value read.
 */
UINT32
ReadPciCfg (
  IN  UINT64  Address
  );

/**
  Writes to PCI configuration space.

  @param[in]  Address  PCI config address.
  @param[in]  Value    Value to write.
 */
VOID
WritePciCfg (
  IN  UINT64  Address,
  IN  UINT32  Value
  );

/**
  Gets the current timer value for delay calculation.

  @param[out]  TimerValue  Current timer value.

  @return EFI_STATUS.
 */
EFI_STATUS
GetTimerValue (
  OUT UINT64  *TimerValue
  );

// ============================================================================
// String and Print Functions
// ============================================================================

/**
  Internal SPrint implementation for Unicode strings.

  @param[out] Buffer     Output buffer.
  @param[in]  BufferSize Buffer size in bytes.
  @param[in]  Flags      Format flags.
  @param[in]  Value      Integer value to format.
  @param[in]  Width      Minimum field width.

  @return Number of characters written.
 */
UINTN
PrintLibInternalSPrint (
  OUT CHAR16  *Buffer,
  IN  UINTN   BufferSize,
  IN  UINT8   Flags,
  IN  INT64   Value,
  IN  UINTN   Width
  );

/**
  Unicode VSPrint implementation.

  @param[out] Buffer     Output buffer.
  @param[in]  BufferSize Buffer size in bytes.
  @param[in]  Format     Format string (Unicode or ASCII).
  @param[in]  Marker     VA_LIST marker.

  @return Number of characters written.
 */
UINTN
PrintLibUnicodeVSPrint (
  OUT CHAR16        *Buffer,
  IN  UINTN         BufferSize,
  IN  CONST CHAR16  *Format,
  IN  VA_LIST       Marker
  );

/**
  Calculates ASCII string length safely.

  @param[in]  String  ASCII string.
  @param[in]  MaxSize Maximum size to check.

  @return String length.
 */
UINTN
AsciiStrnLenS (
  IN  CONST CHAR8  *String,
  IN  UINTN        MaxSize
  );

/**
  Converts a wide character string (Unicode) to ASCII.

  @param[in]  Source      Unicode source string.
  @param[in]  Dest        ASCII destination buffer.
  @param[in]  DestSize    Destination buffer size.

  @return EFI_STATUS.
 */
EFI_STATUS
UnicodeToString (
  IN  CONST CHAR16  *Source,
  OUT CHAR8         *Dest,
  IN  UINTN         DestSize
  );

/**
  Gets the length of an ASCII string.

  @param[in]  String  ASCII string.

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

/**
  Converts a UINT64 value to a string representation.

  @param[out] Buffer     Output buffer.
  @param[in]  BufferSize Buffer size.
  @param[in]  Flags      Format flags.
  @param[in]  Value      Value to convert.

  @return Status.
 */
RETURN_STATUS
Uint64ToStr (
  OUT CHAR16  *Buffer,
  IN  UINTN   BufferSize,
  IN  UINT32  Flags,
  IN  UINT64  Value
  );

/**
  Appends information to a string buffer.

  @param[out] Dst     Destination buffer.
  @param[in]  Src     Source string.
  @param[in]  DstSize Destination size.
 */
VOID
StrAppendInfo (
  OUT CHAR16  *Dst,
  IN  VOID    *Src
  );

/**
  Converts Unicode string to upper case.

  @param[in]  String  Unicode string.

  @return Upper case string.
 */
CHAR16 *
UnicodeStrToUpper (
  IN  CHAR16  *String
  );

/**
  Concatenates two wide strings safely.

  @param[out] Dst       Destination buffer.
  @param[in]  DstSize   Size of destination in bytes.
  @param[in]  Src       Source string.

  @return RETURN_STATUS.
 */
RETURN_STATUS
StrCatS (
  OUT CHAR16        *Dst,
  IN  UINTN         DstSize,
  IN  CONST CHAR16  *Src
  );

/**
  Compares two wide strings safely.

  @param[in]  Str1  First string.
  @param[in]  Str2  Second string.
  @param[in]  MaxSize  Maximum length.

  @return 0 if equal, negative if Str1 < Str2, positive otherwise.
 */
INTN
StrCmpS (
  IN  CONST CHAR16  *Str1,
  IN  CONST CHAR16  *Str2,
  IN  UINTN         MaxSize
  );

/**
  Returns the length of a wide string (up to a max).

  @param[in]  String   The NULL-terminated string.
  @param[in]  MaxSize  The maximum number of characters.

  @return Length of the string (not counting NULL terminator).
 */
UINTN
StrLen (
  IN  CONST CHAR16  *String,
  IN  UINTN         MaxSize
  );

// ============================================================================
// Setup IFR (Internal Forms Representation) Functions
// ============================================================================

/**
  Extracts IFR data from the HII database.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrExtractor (
  VOID
  );

/**
  Loads strings from the IFR package.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrStringLoader (
  VOID
  );

/**
  Loads the IFR pack from the HII database.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrPackLoader (
  VOID
  );

/**
  Routes setup configuration requests.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupConfigRouting (
  VOID
  );

/**
  Extracts setup configuration via ConfigAccess protocol.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupConfigAccessExtract (
  VOID
  );

/**
  Handles HII keyword requests.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupKeywordHandler (
  VOID
  );

/**
  Builds IFR data for setup.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrBuilder (
  VOID
  );

/**
  Configures setup IFR access.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrConfigAccess (
  VOID
  );

/**
  Looks up an IFR option by ID.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrOptionLookup (
  VOID
  );

/**
  Gets the value of an IFR option.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrOptionValue (
  VOID
  );

/**
  Handles IFR keyword operations.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrKeywordHandle (
  VOID
  );

/**
  Supplements IFR with additional entries.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrSupplement (
  VOID
  );

// ============================================================================
// Setup Variable Access (Read/Write)
// ============================================================================

/**
  Gets a setup UEFI variable.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupVariableGet (
  VOID
  );

/**
  Sets a UEFI variable for setup.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupVariableSet (
  VOID
  );

/**
  Extracts setup configuration from variable store.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupConfigExtract (
  VOID
  );

/**
  Routes setup configuration requests.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupConfigRoute (
  VOID
  );

/**
  Final setup callback handler.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupCallbackFinal (
  VOID
  );

/**
  Sets up IFR configuration access.

  @return VOID.
 */
VOID
SetupIfrConfigAccess (
  VOID
  );

/**
  Reads back a setup variable for verification.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupVariableReadback (
  VOID
  );

/**
  Performs setup buffer operations.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupBufferOps (
  VOID
  );

/**
  Migrates old setup variable to new format.

  @return EFI_STATUS.
 */
EFI_STATUS
MigrateOldSetupVar (
  VOID
  );

/**
  Migrates setup data between generations.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupDataMigrate (
  VOID
  );

/**
  Sub-callback for HII operations.

  @return EFI_STATUS.
 */
EFI_STATUS
HiiSubCallback (
  VOID
  );

/**
  Helper for HII callback operations.

  @return EFI_STATUS.
 */
EFI_STATUS
HiiCallbackHelper (
  VOID
  );

// ============================================================================
// Error Handling / Misc
// ============================================================================

/**
  Enters an infinite loop with debug assertion.

  @param[in]  FileName  Source file name.
  @param[in]  LineNumber Source line number.
  @param[in]  Description  Assertion description.
 */
VOID
Assert (
  IN  CONST CHAR8  *FileName,
  IN  UINTN        LineNumber,
  IN  CONST CHAR8  *Description
  );

/**
  Enters CPU dead loop (infinite halt loop).

  This function is called when an unrecoverable error occurs.
  It disables interrupts and enters an infinite loop.
 */
VOID
CpuDeadLoop (
  VOID
  );

/**
  Debug print/log function.

  @param[in]  ErrorLevel  Debug message error level.
  @param[in]  Format      Format string.
  @param[in]  ...         Additional arguments.
 */
VOID
DebugPrint (
  IN  UINTN        ErrorLevel,
  IN  CONST CHAR8  *Format,
  ...
  );

/**
  Calculates a CRC value for data integrity.

  @param[in]  Buffer   Data buffer.
  @param[in]  Size     Size of data.

  @return CRC value.
 */
UINT32
CalculateCrc (
  IN  VOID    *Buffer,
  IN  UINTN   Size
  );

/**
  Gets a 16-bit value at a specified index in a buffer
  (endian-aware byte extraction).

  @param[in]  Buffer  Data buffer.
  @param[in]  Index   Byte index.

  @return 16-bit value.
 */
UINT16
GetUint16AtIndex (
  IN  UINT16  *Buffer,
  IN  UINTN   Index
  );

/**
  Gets a 32-bit value from an address.

  @param[in]  Address  Memory address.

  @return 32-bit value.
 */
UINT32
GetUint32 (
  IN  UINT32  *Address
  );

/**
  Sets a UINT8 value at a memory address.

  @param[in]  Address  Memory address.
  @param[in]  Value    Value to write.
 */
VOID
SetUint8 (
  OUT UINT8  *Address,
  IN  UINT8  Value
  );

/**
  Sets a range of memory to a value.

  @param[out] Buffer   Memory buffer.
  @param[in]  Size     Size in bytes.
  @param[in]  Value    Value to fill with.
 */
VOID
SetMemRange (
  OUT VOID   *Buffer,
  IN  UINTN  Size,
  IN  UINT8  Value
  );

/**
  Allocates memory pool.

  @param[in]  Size  Size in bytes.

  @return Pointer to allocated memory, or NULL.
 */
VOID *
AllocatePool (
  IN  UINTN  Size
  );

/**
  Allocates zeroed memory pool.

  @param[in]  Size  Size in bytes.

  @return Pointer to allocated memory, or NULL.
 */
VOID *
AllocateZeroPool (
  IN  UINTN  Size
  );

/**
  Copies memory and allocates the copy.

  @param[in]  Size  Size in bytes.
  @param[in]  Buffer  Source buffer.

  @return Pointer to allocated copy, or NULL.
 */
VOID *
AllocateCopyPool (
  IN  UINTN      Size,
  IN  CONST VOID *Buffer
  );

/**
  Locates a protocol handler.

  @param[in]  Protocol   Protocol GUID.
  @param[out] Interface  Pointer to receive protocol interface.

  @return EFI_STATUS.
 */
EFI_STATUS
LocateProtocol (
  IN  EFI_GUID  *Protocol,
  OUT VOID      **Interface
  );

/**
  Locates a handle buffer for a given protocol.

  @param[in]  Protocol      Protocol GUID.
  @param[out] NoHandles     Number of handles.
  @param[out] Buffer        Handle buffer.

  @return EFI_STATUS.
 */
EFI_STATUS
LocateHandleBuffer (
  IN  EFI_GUID       *Protocol,
  OUT UINTN          *NoHandles,
  OUT EFI_HANDLE     **Buffer
  );

/**
  Gets all handles that support a given protocol.

  @param[in]  Protocol  Protocol GUID.

  @return Handle buffer, or NULL.
 */
EFI_HANDLE *
GetAllHandlesByProtocol (
  IN  EFI_GUID  *Protocol
  );

/**
  Creates a device path node.

  @param[in]  Guid   Vendor GUID.
  @param[in]  Data   Additional data.

  @return Device path protocol, or NULL.
 */
EFI_DEVICE_PATH_PROTOCOL *
CreateDevicePath (
  IN  EFI_GUID  *Guid,
  IN  VOID      *Data
  );

/**
  Gets the DXE services table.

  @return Pointer to DXE services table, or NULL if not found.
 */
EFI_DXE_SERVICES *
GetDxeServicesTable (
  VOID
  );

// ============================================================================
// IFR (Internal Forms Representation) Setup Functions
// ============================================================================

/**
  Submits setup form callback responses via ConfigAccess protocol.

  @return EFI_STATUS.
 */
EFI_STATUS
HiiSubCallback (
  VOID
  );

/**
  Setup IFR configuration access.

  @return EFI_STATUS.
 */
EFI_STATUS
SetupIfrConfigAccess (
  VOID
  );