Newer
Older
AMI-Aptio-BIOS-Reversed / SmbiosType11 / SmbiosType11.c
@Ajax Dong Ajax Dong 2 days ago 35 KB Init
/**
 *SmbiosType11.efi - Full decompilation source
 *HR650X BIOS (index 0096)
 *MD5: 6d2aa6d0b791cb0f41cb511022e9e7ac
 *SHA256: 28c4358d6d6ab7ffc1e56ffbea88d5ee728cac4e973fef742666462ea8b87b1e
 *Image size: 0x3120
 *Functions: 33
 *
 *This driver installs SMBIOS Type 11 (OEM Strings) entries populated with
 *BMC firmware version, SPS/ME firmware version, and ME status information.
 *It communicates with the BMC via IPMI and IPMB protocols.
 */

#include "SmbiosType11.h"

// ---------------------------------------------------------------------------
// Global data
// ---------------------------------------------------------------------------
EFI_HANDLE ImageHandle; // unk_2EB8 EFI_SYSTEM_TABLE *SystemTable; // qword_2EA8 EFI_BOOT_SERVICES *BootServices; // qword_2EB0 EFI_RUNTIME_SERVICES *RuntimeServices; // qword_2EC0 EFI_SMM_PCI_BASE *mPciUsra; // qword_2EE0 EFI_SMBIOS_PROTOCOL *gSmbios; // qword_2EA0 PCD_PROTOCOL *mPcd; // qword_2ED0 EFI_SMM_COMMUNICATION *mSmmPciBase; // qword_2EC8 VOID *mHobList; // qword_2EE8

// ---------------------------------------------------------------------------
// GUID definitions
// ---------------------------------------------------------------------------
EFI_GUID gEfiSmbiosProtocolGuid = { 0x0358FF4A, 0xCB41, 0x4D36, { 0x8B, 0xDF, 0x0C, 0x6E, 0xDC, 0x09, 0x3E, 0x4E } };
EFI_GUID gEfiBmcSelfTestLogProtocolGuid = { 0xB9FBE53D, 0x96DC, 0x4C33, { 0x91, 0xDD, 0x01, 0x33, 0x64, 0xDD, 0x0D, 0x8F } };
EFI_GUID gEfiDxeIpmiTransportProtocolGuid = { 0x1A0DAEE1, 0xE1F8, 0x4E56, { 0x83, 0xC7, 0x1B, 0x09, 0xD2, 0xAE, 0x5F, 0x56 } };
EFI_GUID gEfiPciRootBridgeIoProtocolGuid = { 0x2EB5E19A, 0x58D2, 0x4BDD, { 0x9D, 0xAF, 0x7F, 0x08, 0x2B, 0x7A, 0x56, 0x37 } };
EFI_GUID gEfiHobListGuid = { 0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } };

// ---------------------------------------------------------------------------
// Forward declarations
// ---------------------------------------------------------------------------
char *sub_2A0(char *Buf, UINTN Size);
UINTN sub_C00(CONST CHAR16 *String);
UINTN sub_E78(CONST CHAR8 *String);
__int64 sub_EE4(void);
__int64 sub_FEC(__int64 a1, __int64 a2, __int64 a3);
BOOL sub_1090(__int64 a1, __int64 a2);
__int64 sub_10F8(void);
EFI_STATUS sub_1184(EFI_GUID *TableGuid, VOID **Table);
UINT32 sub_1248(void);
__int64 sub_1278(void);
__int64 sub_134C(__int64 Value, _BYTE *Buffer, int Radix, char Flag);
__int64 sub_13C0(char *String, char **EndPtr);
const char *sub_1498(__int64 Status);
INTN sub_1588(__int16 *Buffer, __int64 BufferSize, CONST CHAR16 *Format, __int64 VaList);
UINTN sub_1A00(__int16 *Buffer, __int64 BufferSize, CONST CHAR16 *Format, ...);
UINT32 sub_1A20(UINT32 DefaultFs1);
UINT64 sub_1AD8(__int64 a1);
void sub_1B50(__int64 Buffer, __int64 Value, int Size);
int *sub_1B5E(int *Buffer, UINTN Size, unsigned int Value);
char *sub_1BB0(char *Dst, const char *Src, UINTN Size);

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

EFI_STATUS EFIAPI ModuleEntryPoint (
 IN EFI_HANDLE ImageHandle,
 IN EFI_SYSTEM_TABLE *SystemTable
 )
{
 sub_384 ((__int64)ImageHandle, SystemTable);
 return sub_550 ();
}

// ===========================================================================
// Driver Initialization (sub_384)
// ===========================================================================

__int64 sub_384 (
 __int64 ImageHandle,
 EFI_SYSTEM_TABLE *SystemTable
 )
{
 __int64 v3;
 __int64 v4;
 __int64 v5;
 __int64 v6;

 ::ImageHandle = (EFI_HANDLE)ImageHandle;
 if (!ImageHandle)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
 51,
 (__int64)"gImageHandle != ((void *) 0)");

 ::SystemTable = (EFI_SYSTEM_TABLE *)SystemTable;
 if (!SystemTable)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
 57,
 (__int64)"gST != ((void *) 0)");

 BootServices = SystemTable->BootServices;
 if (!BootServices)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
 63,
 (__int64)"gBS != ((void *) 0)");

 RuntimeServices = SystemTable->RuntimeServices;
 if (!RuntimeServices)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\UefiRuntimeServicesTableLib\\UefiRuntimeServicesTableLib.c",
 47,
 (__int64)"gRT != ((void *) 0)");

 v3 = sub_1184 (&gEfiDxeServicesTableGuid, (VOID **)&gDS);
 v4 = v3;
 if (v3 < 0)
 {
 sub_F64 (0x80000000LL, "\nASSERT_EFI_ERROR (Status = %r)\n", v3);
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\DxeServicesTableLib\\DxeServicesTableLib.c",
 64,
 (__int64)"!EFI_ERROR (Status)");
 }
 if (!gDS)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\DxeServicesTableLib\\DxeServicesTableLib.c",
 65,
 (__int64)"gDS != ((void *) 0)");

 if (v4 < 0)
 {
 sub_F64 (0x80000000LL, "\nASSERT_EFI_ERROR (Status = %r)\n", v4);
 sub_FEC (
 (__int64)"e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\X64\\LenovoServerPkg\\SmbiosType11\\SmbiosType11\\DEBUG\\AutoGen.c",
 323,
 (__int64)"!EFI_ERROR (Status)");
 }

 if (!mPciUsra)
 {
 v5 = BootServices->LocateProtocol (
 &gEfiPciRootBridgeIoProtocolGuid,
 NULL,
 (VOID **)&mPciUsra);
 if (v5 < 0)
 {
 sub_F64 (0x80000000LL, "\nASSERT_EFI_ERROR (Status = %r)\n", v5);
 sub_FEC (
 (__int64)"e:\\hs\\CpRcPkg\\Library\\DxeMmPciBaseLib\\DxeMmPciBaseLib.c",
 52,
 (__int64)"!EFI_ERROR (Status)");
 }
 if (!mPciUsra)
 sub_FEC (
 (__int64)"e:\\hs\\CpRcPkg\\Library\\DxeMmPciBaseLib\\DxeMmPciBaseLib.c",
 53,
 (__int64)"mPciUsra != ((void *) 0)");
 }

 sub_1278 ();
 v6 = sub_10F8 ();
 return ((EFI_SMBIOS_PROTOCOL *)v6)->SetString (5);
}

// ===========================================================================
// SMBIOS Type 11 Support Install (sub_550)
// ===========================================================================

__int64 sub_550 (
 __int64 a1,
 __int64 a2
 )
{
 __int64 v2;
 __int64 v3;
 __int64 v5;
 __int64 v6;

 v6 = a2;
 v5 = a1;

 sub_F64 (-1, "SmbiosType11Support entered\n");

 v2 = BootServices->RegisterProtocolNotify (
 512,
 8,
 sub_954);
 if (v2 < 0)
 {
 sub_F64 (0x80000000LL, "\nASSERT_EFI_ERROR (Status = %r)\n", v2);
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
 167,
 (__int64)"!EFI_ERROR (Status)");
 }

 v3 = BootServices->InstallProtocolInterface (
 &gEfiDriverBindingProtocolGuid,
 v6,
 &v5);
 if (v3 < 0)
 {
 sub_F64 (0x80000000LL, "\nASSERT_EFI_ERROR (Status = %r)\n", v3);
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
 179,
 (__int64)"!EFI_ERROR (Status)");
 }

 BootServices->CloseEvent (v6);
 sub_F64 (-1, "SmbiosType11Support exiting.......\n");
 return 0;
}

// ===========================================================================
// ME Status IPMI SEL Logging (sub_640)
// ===========================================================================

unsigned __int64 sub_640 (
 void
 )
{
 UINT32 Fs;
 char FsLowNib;
 UINT32 Fs1;
 __int64 Status;
 UINT32 BmcStatus;
 __int64 Ipmi;
 __int64 V8;
 __int64 V9;
 __int64 V10;
 WORD Data[7];
 CHAR8 Reply;
 UINT16 RecordId;
 UINT32 V15;
 UINT32 V16;

 V10 = 0;
 ZeroMem (Data, sizeof (Data));

 sub_102C ((__int64)&V15, 4);
 sub_102C ((__int64)&V16, 4);

 Fs = *(UINT32 *)(sub_1248 () + 64);
 FsLowNib = (CHAR8)Fs;
 V15 = Fs;
 if (Fs == (UINT32)-1)
 {
 Fs1 = sub_1A20 (-1);
 FsLowNib = (CHAR8)Fs1;
 V15 = Fs1;
 }

 // Set PCD value based on FS[3:0]
 Status = sub_10F8 ();
 ((EFI_PCD_PROTOCOL *)Status)->Set8 (217, FsLowNib & 0xF);

 if ((V15 & 0xF) == 2)
 {
 // ME in recovery mode V16 = *(UINT32 *)(sub_1248 () + 72);
 sub_F64 (2, "[SPS] WARNING: ME is in recovery mode (cause: %d)\n", (V16 >> 8) & 7);
 }
 else if ((V15 & 0xF) != 5)
 {
 return EFI_UNSUPPORTED;
 }

 Ipmi = BootServices->LocateProtocol (
 &gEfiDxeIpmiTransportProtocolGuid,
 NULL,
 &V10);
 sub_F64 (-1, " LogFailDimmIntoSel gEfiDxeIpmiTransportProtocolGuid Status: %r \n", Ipmi);

 if (Ipmi >= 0)
 {
 // Build IPMI STORAGE_ADD_SEL_ENTRY command data
 // Record type, timestamp, event data format follow IPMI spec
 *(UINT64 *)((UINT8 *)&Data[1] + 1) = 0x2804002100000000ULL;
 Data[1] = (WORD)((Data[1] & 0xFF00) | 0x02);

 // Encode ME FS info into SEL event data bytes
 *((UINT8 *)&Data[5] + 1) = (UINT8)((16 *V15) | ((V15 >> 12) & 0xF));
 HIBYTE (Data[6]) = 0xA3;

 V9 = V16 >> 6;
 HIBYTE (Data[6]) |= ((V16 & 0x1000) != 0)
 | (2 * (((V16 & 0x40) != 0)
 | (2 * (((V15 & 0x20) != 0) | (2 * ((V15 & 0x400) != 0))))));

 if ((V15 & 0xF) != 5)
 {
 V8 = 68;
 V9 = 10;
 Ipmi = ((EFI_IPMI_TRANSPORT_PROTOCOL *)V10)->SendCommand (
 V10,
 V9,
 0,
 V8,
 (UINT8 *)Data,
 16,
 &RecordId,
 &Reply);
 sub_F64 (-1, " IPMI_STORAGE_ADD_SEL_ENTRY Status: %r RecordId: %x \n", Ipmi, RecordId);
 }
 }

 return Ipmi;
}

// ===========================================================================
// SPS/ME Version String (sub_7F8)
// ===========================================================================

__int64 sub_7F8 (
 __int64 a1
 )
{
 INTN Status;
 UINT32 CmdData;
 UINT16 Ver1, Ver2, Ver3, Ver4;
 UINT16 VerA, VerB, VerC, VerD;
 UINT8 CmdSize;
 EFI_IPMI_TRANSPORT_PROTOCOL *Ipmi;
 UINT32 Fs;
 UINT64 V13;

 Ipmi = NULL;

 sub_102C ((__int64)&V13, 4);
 V13 = *(UINT32 *)(sub_1248 () + 64);
 if ((UINT32)V13 == (UINT32)-1)
 V13 = sub_1A20 (-1);

 Status = BootServices->LocateProtocol (
 &gEfiDxeIpmiTransportProtocolGuid,
 NULL,
 (VOID **)&Ipmi);
 if (Status >= 0)
 {
 BootServices->CalculateCrc32 (&CmdData, 4);
 CmdData = (CmdData & 0xFFFF8000) | 0x2FF;
 CmdSize = 28;
 Status = Ipmi->SendCommand (
 0,
 &CmdData,
 4,
 &CmdSize,
 0,
 7);

 if (Status >= 0
 && (CmdData & 0xFF) == 0xFF
 && (CmdData & 0x8000)
 && (CmdData & 0x7F00) == 0x200)
 {
 if ((V13 & 0xF) == 2)
 {
 sub_1B5E ((int *)a1, 255, 0);
 sub_1560 (
 (__int16 *)a1,
 255,
 L"ME Version:%d.%d.%d.%d",
 (UINT8)VerA, VerB, VerC, VerD);
 }
 else
 {
 sub_1B5E ((int *)a1, 255, 0);
 sub_1560 (
 (__int16 *)a1,
 255,
 L"ME Verison:%d.%d.%d.%d",
 (UINT8)Ver1, Ver2, Ver3, Ver4);
 }
 }
 }
 return Status;
}

// ===========================================================================
// Main SMBIOS Type 11 Installer (sub_954)
// ===========================================================================

__int64 sub_954 (
 __int64 a1
 )
{
 INTN Status;
 INTN V5;
 INTN V6;
 INTN V7;
 INTN V8;
 INTN V9;
 int V10;
 UINTN N2;
 __int64 V12;
 UINT8 V13[8];
 UINT8 V14[8];
 CHAR8 BmcString[256];
 CHAR8 SpsString[256];
 WORD Buf[66];
 UINT8 Type;
 INT16 Handle;

 sub_1B50 ((__int64)Buf, 0, 510);
 V12 = 0;
 sub_1B50 ((__int64)SpsString, 0, 255);
 sub_1B50 ((__int64)BmcString, 0, 255);
 sub_E78 ("INVALID");
 N2 = 0;

 sub_F64 (-1, "InstallSmbiosType11Structure entered\n");

 Status = BootServices->LocateProtocol (
 &gEfiSmbiosProtocolGuid,
 NULL,
 (VOID **)&gSmbios);
 sub_F64 (-1, "gBS->LocateProtocol gEfiSmbiosProtocolGuid Status: %r\n", Status);

 if (Status >= 0)
 {
 V4 = BootServices->CloseEvent (a1);
 sub_F64 (-1, "CloseEvent Status: %r\n", V4);

 // Locate BMC Self Test Log Protocol V5 = BootServices->LocateProtocol (
 &gEfiBmcSelfTestLogProtocolGuid,
 NULL,
 &V12);
 if (V5 < 0)
 {
 sub_F64 (0x80000000LL,
 "InstallSmbiosType11Structure: Locate gEfiBmcSelfTestLogProtocolGuid status: %r\n", V5);
 sub_DD0 (BmcString);
 }
 else
 {
 sub_1560 (
 Buf,
 L"BMC Version:%d.%x.%4x",
 *(UINT8 *)(V12 + 91) & 0x7F,
 *(UINT8 *)(V12 + 92),
 *(UINT32 *)(V12 + 100),
 V10);
 sub_C00 (Buf);
 sub_C94 (Buf, BmcString);
 }

 // Get SPS version string V6 = sub_7F8 ((__int64)Buf);
 if (V6 < 0)
 {
 sub_F64 (0x80000000LL,
 "InstallSmbiosType11Structure: Locate GetSPSString status: %r\n", V6);
 sub_DD0 (SpsString);
 }
 else
 {
 sub_C00 (Buf);
 sub_C94 (Buf, SpsString);
 }

 // Log ME status to SEL V7 = sub_640 ();
 if (V7 < 0)
 sub_F64 (0x80000000LL,
 "InstallSmbiosType11Structure: LogMEStatusInfotoSel status: %r\n", V7);

 // Update SMBIOS Type 11 table Type = 11; // SMBIOS OEM Strings Handle = -2;

 V8 = gSmbios->GetNextTable (
 gSmbios,
 &Handle,
 &Type,
 V14,
 V13);
 if (V8 >= 0)
 {
 // Remove existing entries and add new ones N2 = 2;
 gSmbios->RemoveString (gSmbios, &Handle, &N2, BmcString);

 N2 = 3;
 V9 = gSmbios->UpdateString (gSmbios, &Handle, &N2, SpsString);
 if (V9 < 0)
 sub_F64 (0x80000000LL,
 "%a: UpdateHiiStringToSmbios - type: %d, status: %r\n",
 "InstallSmbiosType11Structure",
 Type,
 V9);
 }
 else
 {
 sub_F64 (0x80000000LL,
 "%a: Get next table - type: %d, status: %r\n",
 "InstallSmbiosType11Structure",
 Type,
 V8);
 }

 return sub_F64 (-1, "UpdateSmbiosType11Structure Exiting......\n");
 }
 return Status;
}

// ===========================================================================
// Unicode String Length (sub_C00)
// ===========================================================================

UINTN EFIAPI sub_C00 (
 IN CONST CHAR16 *String
 )
{
 CONST CHAR16 *Ptr;
 UINTN Length;

 Ptr = String;
 if (!String)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 172,
 (__int64)"String != ((void *) 0)");

 if (((UINTN)Ptr & 1) != 0)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 173,
 (__int64)"((UINTN) String & 0x00000001) == 0");

 Length = 0;
 while (*Ptr)
 {
 if (Length >= 0xF4240)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 181,
 (__int64)"Length < _gPcd_FixedAtBuild_PcdMaximumUnicodeStringLength");
 ++Ptr;
 ++Length;
 }
 return Length;
}

// ===========================================================================
// Unicode-to-ASCII Conversion (sub_C94)
// ===========================================================================

CHAR8 *EFIAPI sub_C94 (
 OUT CHAR8 *Destination,
 IN CONST CHAR16 *Source
 )
{
 CHAR8 *Dst;
 CHAR8 *Ret;

 Dst = Destination;
 if (!Destination)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 900,
 (__int64)"Destination != ((void *) 0)");

 if (2 *sub_C00 (Source) == (UINTN)-2)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 906,
 (__int64)"StrSize (Source) != 0");

 // Check for overlap if (Dst - (CHAR8 *)Source < 2 *sub_C00 (Source) + 2)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 911,
 (__int64)"(UINTN) (Destination - (CHAR8 *) Source) >= StrSize (Source)");

 if ((CHAR8 *)Source - Dst <= sub_C00 (Source))
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 912,
 (__int64)"(UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source)");

 Ret = Dst;
 while (*Source)
 {
 if (*Source >= 0x100)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 921,
 (__int64)"*Source < 0x100");
 *Dst++ = (CHAR8)*Source;
 Source++;
 }
 *Dst = '\0';

 if (sub_E78 (Ret) == (UINTN)-1)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 931,
 (__int64)"AsciiStrSize (ReturnValue) != 0");

 return Ret;
}

// ===========================================================================
// Copy "INVALID" string (sub_DD0)
// ===========================================================================

CHAR8 *EFIAPI sub_DD0 (
 OUT CHAR8 *Destination
 )
{
 CHAR8 *Dst;
 const CHAR8 *Src;
 CHAR8 Ch;

 Src = "INVALID";
 Dst = Destination;

 if (!Destination)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 971,
 (__int64)"Destination != ((void *) 0)");

 // Check overlap conditions if (Dst - Src <= sub_E78 (Src))
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 976,
 (__int64)"(UINTN)(Destination - Source) > AsciiStrLen (Source)");

 if (Src - Dst <= sub_E78 (Src))
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 977,
 (__int64)"(UINTN)(Source - Destination) > AsciiStrLen (Source)");

 Ch = *Src;
 do
 {
 Src++;
 *Dst++ = Ch;
 Ch = *Src;
 }
 while (Ch);

 *Dst = '\0';
 return Destination;
}

// ===========================================================================
// ASCII String Length (sub_E78)
// ===========================================================================

UINTN EFIAPI sub_E78 (
 IN CONST CHAR8 *String
 )
{
 CONST CHAR8 *Ptr;
 UINTN Length;

 Ptr = String;
 if (!String)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 1082,
 (__int64)"String != ((void *) 0)");

 for (Length = 0; *Ptr; Length++)
 {
 if (Length >= 0xF4240)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\String.c",
 1090,
 (__int64)"Length < _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength");
 Ptr++;
 }
 return Length;
}

// ===========================================================================
// Debug Print Protocol (lazy init) (sub_EE4)
// ===========================================================================

__int64 sub_EE4 (
 void
 )
{
 __int64 Result;
 UINTN BufferSize;
 __int64 Status;
 __int64 Protocol;

 Result = (__int64)mSmmPciBase;
 if (!mSmmPciBase)
 {
 BufferSize = BootServices->GetBootMode (31);
 BootServices->SetMem (BufferSize);
 if (BufferSize <= 0x10)
 {
 Status = BootServices->LocateProtocol (
 &gEfiPciRootBridgeIoProtocolGuid,
 NULL,
 (VOID **)&mSmmPciBase);
 Protocol = (__int64)mSmmPciBase;
 if (Status < 0)
 Protocol = 0;
 mSmmPciBase = (EFI_SMM_COMMUNICATION *)Protocol;
 return Protocol;
 }
 else
 {
 return 0;
 }
 }
 return Result;
}

// ===========================================================================
// Debug Print (sub_F64)
// ===========================================================================

char sub_F64 (
 __int64 a1,
 const char *Format,
 ...
 )
{
 __int64 DebugProtocol;
 __int64 Mask;
 INTN (**PrintFn)(__int64, const char *, __int64 *);
 UINT8 CmosVal;
 char DebugLevel;
 char Result;
 va_list Va;

 va_start (Va, Format);

 DebugProtocol = sub_EE4 ();
 Mask = 0;
 PrintFn = (INTN (**)(__int64, const char *, __int64 *))DebugProtocol;

 if (DebugProtocol)
 {
 // Read CMOS index 0x4B (debug level register)
 CmosVal = __inbyte (0x70);
 __outbyte (0x70, CmosVal & 0x80 | 0x4B);
 DebugLevel = __inbyte (0x71);

 if ((UINT8)DebugLevel > 3)
 {
 if (!DebugLevel)
 DebugLevel = (MEMORY[0xFDAF0490] & 2) | 1;
 }

 Result = DebugLevel - 1;
 if ((UINT8)(DebugLevel - 1) <= 0xFD)
 {
 Result = 4;
 Mask = 2147483718LL;
 if (DebugLevel == 1)
 Mask = 2147483652LL;
 }

 if ((Mask & a1) != 0)
 Result = (CHAR8)(*PrintFn)(a1, Format, (__int64 *)Va);
 }
 return Result;
}

// ===========================================================================
// Debug Assert Handler (sub_FEC)
// ===========================================================================

__int64 sub_FEC (
 __int64 a1,
 __int64 a2,
 __int64 a3
 )
{
 __int64 Result;

 Result = sub_EE4 ();
 if (Result)
 return (*(INTN (**)(__int64, __int64, __int64))(Result + 8))(a1, a2, a3);
 return Result;
}

// ===========================================================================
// ZeroMem (sub_102C)
// ===========================================================================

__int64 sub_102C (
 __int64 Buffer,
 UINTN Size
 )
{
 if (!Buffer)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
 53,
 (__int64)"Buffer != ((void *) 0)");

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

 sub_2A0 ((char *)Buffer, Size);
 return 0;
}

// ===========================================================================
// GUID Compare (sub_1090)
// ===========================================================================

BOOLEAN sub_1090 (
 __int64 a1,
 __int64 a2
 )
{
 UINT64 V1 = sub_1AD8 (a1);
 UINT64 V2 = sub_1AD8 (a2);
 UINT64 V3 = sub_1AD8 (a1 + 8);
 UINT64 V4 = sub_1AD8 (a2 + 8);
 return (V1 == V2) && (V3 == V4);
}

// ===========================================================================
// PCD Protocol Lookup (lazy init) (sub_10F8)
// ===========================================================================

PCD_PROTOCOL *sub_10F8 (
 void
 )
{
 PCD_PROTOCOL *Result;
 INTN Status;

 Result = mPcd;
 if (!mPcd)
 {
 Status = BootServices->LocateProtocol (
 &gEfiPcdProtocolGuid,
 NULL,
 (VOID **)&mPcd);
 if (Status < 0)
 {
 sub_F64 (0x80000000LL, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\DxePcdLib\\DxePcdLib.c",
 78,
 (__int64)"!EFI_ERROR (Status)");
 }
 Result = mPcd;
 if (!mPcd)
 {
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\DxePcdLib\\DxePcdLib.c",
 79,
 (__int64)"mPcd != ((void *) 0)");
 return mPcd;
 }
 }
 return Result;
}

// ===========================================================================
// Configuration Table Lookup by GUID (sub_1184)
// ===========================================================================

EFI_STATUS sub_1184 (
 IN EFI_GUID *TableGuid,
 OUT VOID **Table
 )
{
 UINTN Index;
 EFI_GUID *EntryGuid;

 if (!TableGuid)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
 97,
 (__int64)"TableGuid != ((void *) 0)");

 if (!Table)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
 98,
 (__int64)"Table != ((void *) 0)");

 *Table = NULL;

 if (!SystemTable->NumberOfTableEntries)
 return EFI_NOT_FOUND;

 for (Index = 0;
 !sub_1090 (
 (__int64)TableGuid,
 (__int64)&SystemTable->ConfigurationTable[Index].VendorGuid);
 Index++)
 {
 if (Index + 1 >= SystemTable->NumberOfTableEntries)
 return EFI_NOT_FOUND;
 }

 *Table = SystemTable->ConfigurationTable[Index].VendorTable;
 return EFI_SUCCESS;
}

// ===========================================================================
// MMIO PCI Read (sub_1248)
// ===========================================================================

UINT32 sub_1248 (
 void
 )
{
 UINT32 Param[6];
 UINT32 Result;

 Param[3] = 0;
 Param[1] = 0;
 Param[2] = 512; // MMIO address low part Param[0] = 0xB0000; // Command / access type return ((EFI_SMM_PCI_BASE_PROTOCOL *)mPciUsra)->Read (Param);
}

// ===========================================================================
// HOB List Initialization (sub_1278)
// ===========================================================================

__int64 sub_1278 (
 void
 )
{
 __int64 Result;
 INTN Status;

 Result = (__int64)mHobList;
 if (!mHobList)
 {
 Status = sub_1184 (&gEfiHobListGuid, &mHobList);
 if (Status < 0)
 {
 sub_F64 (0x80000000LL, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
 54,
 (__int64)"!EFI_ERROR (Status)");
 }
 Result = (__int64)mHobList;
 if (!mHobList)
 {
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
 55,
 (__int64)"mHobList != ((void *) 0)");
 return (__int64)mHobList;
 }
 }
 return Result;
}

// ===========================================================================
// Find Resource Descriptor HOB (sub_12FC)
// ===========================================================================

_WORD *sub_12FC (
 __int64 a1,
 _WORD *Hob
 )
{
 _WORD *HobPtr;

 HobPtr = Hob;
 if (!Hob)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
 108,
 (__int64)"HobStart != ((void *) 0)");

 while (TRUE)
 {
 if (*HobPtr == 0xFFFF) // HobType == END_OF_HOB_LIST return NULL;

 if (*HobPtr == 4) // HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR break;

 HobPtr = (_WORD *)((UINT8 *)HobPtr + HobPtr[1]); // Next HOB by Header.HobLength
 }
 return HobPtr;
}

// ===========================================================================
// Integer to ASCII (sub_134C)
// ===========================================================================

_BYTE *sub_134C (
 __int64 Value,
 _BYTE *Buffer,
 int Radix,
 char Flag
 )
{
 UINT64 UValue;
 _BYTE *Ptr;
 UINT64 Digit;
 char Ch;

 if (Flag)
 UValue = (UINT64)(UINT32)Value;
 else UValue = (UINT64)(INT64)Value;

 if (Radix == 10)
 UValue = -(INT64)UValue;

 if ((INT64)Value >= 0)
 UValue = (UINT64)Value;

 Ptr = Buffer;
 if (UValue)
 {
 do
 {
 Digit = UValue % (UINT64)Radix;
 UValue /= (UINT64)Radix;
 if (Digit >= 0xA)
 Ch = (char)Digit + 'W'; // 'a' - 10 = 87 => 0xa -> 'a'
 else Ch = (char)Digit + '0';
 *Ptr++ = Ch;
 }
 while (UValue);
 }
 else
 {
 *Buffer = '0';
 Ptr = Buffer + 1;
 }

 if (Radix == 10 && (INT64)Value < 0)
 *Ptr++ = '-';

 *Ptr = '\0';
 return Ptr - 1;
}

// ===========================================================================
// ASCII String to Integer (sub_13C0)
// ===========================================================================

__int64 sub_13C0 (
 char *String,
 char **EndPtr
 )
{
 char Sign;
 char Overflow;
 UINT32 Accum;
 char *Ptr;
 char Ch;
 char Digit;

 Sign = 0;
 Overflow = 1;
 Accum = 0;

 // Skip leading spaces and tabs while (*String == ' ' || *String == '\t')
 String += 2; // Actually CHAR16 stride? But String is char* - likely ASCII if (*String)
 {
 if (*String == '-')
 {
 Sign = -1;
 String += 2;
 }

 Ptr = String + 2;
 if (*String != '+')
 Ptr = String;

 while (TRUE)
 {
 Ch = *Ptr;
 if ((UINT8)(Ch - '0') > 9)
 {
 if ((UINT8)((Ch & 0xDF) - 'A') > 0x19)
 break;
 Digit = (Ch & 0xDF) - 'A' + 10;
 }
 else
 {
 Digit = Ch - '0';
 }

 if (Digit >= 10)
 break;

 Accum = Digit + 10 *Accum;

 if (Sign == 1)
 {
 if (Accum >= 0x80000000)
 Overflow = 1;
 }
 else if (Accum > 0x80000000)
 {
 Overflow = 1;
 }
 Ptr += 2;
 }

 *EndPtr = Ptr;

 if (Overflow)
 {
 Accum = 0x7FFFFFFF;
 if (Sign == -1)
 Accum = 0x80000000;
 }

 return (INT64)(INT32)(Accum *Sign);
 }
 else
 {
 *EndPtr = String;
 return 0;
 }
}

// ===========================================================================
// EFI Status Code to String (sub_1498)
// ===========================================================================

const char *sub_1498 (
 __int64 Status
 )
{
 UINT64 Index;
 INTN Offset;

 if (!Status)
 return "EFI_SUCCESS";

 if (Status < 0)
 {
 Index = Status & 0x1FFFFFFFFFFFFFFFLL;
 if ((Status & 0xA000000000000000ULL) == 0xA000000000000000ULL)
 {
 if (Index >= 3)
 return NULL;
 Offset = 25 *Index; // EFI_INTERRUPT_PENDING strings return "EFI_INTERRUPT_PENDING" + Offset;
 }

 if ((Status & 0xC000000000000000ULL) == 0xC000000000000000ULL)
 {
 if (Index > 2)
 return NULL;
 Offset = 25 *Index + 11015;
 }
 else
 {
 if (Index > 0x1E)
 return NULL;
 Offset = 25 *Index + 11079;
 }
 return (const char *)&_ImageBase + Offset;
 }

 // Warnings if ((Status & 0x2000000000000000LL) == 0)
 {
 if ((UINT64)Status > 4)
 return NULL;
 Offset = 26 *Index + 10726;
 return (const char *)&_ImageBase + Offset;
 }

 if ((UINT64)Status >= 2)
 return NULL;

 return "EFI_WARN_INTERRUPT_SOURCE_PENDING";
}

// ===========================================================================
// Unicode SPrint wrapper (sub_1560)
// ===========================================================================

UINTN sub_1560 (
 __int16 *Buffer,
 __int64 BufferSize,
 CONST CHAR16 *Format,
 ...
 )
{
 UINTN Result;
 va_list Va;

 va_start (Va, Format);
 Result = sub_1588 (Buffer, BufferSize, Format, (__int64)Va);
 va_end (Va);
 return Result;
}

// ===========================================================================
// Core Unicode VSPrint (sub_1588)
// ===========================================================================

INTN sub_1588 (
 __int16 *Buffer,
 __int64 BufferSize,
 CONST CHAR16 *Format,
 __int64 VaList
 )
{
 CONST CHAR16 *Fmt;
 __int64 SavedBufSize;
 __int16 *Buf;
 __int16 *BufStart;
 __int64 *ArgPtr;
 CHAR16 FmtCh;
 CHAR16 PadCh;
 CHAR16 *ArgStr;
 UINT32 Width;
 UINT32 *ArgU32;
 CONST CHAR8 *ArgS;
 CHAR16 *StrP;
 UINT32 IVal;
 UINTN I;
 UINT64 UVal;
 INTN Count;
 CHAR16 DigitStr[32];
 CHAR8 DigitBuf[256];
 CHAR8 DigitBuf2[304];
 CHAR16 Ch;
 CHAR16 *P;
 BOOLEAN LongArg;

 Fmt = Format;
 SavedBufSize = BufferSize;
 Buf = Buffer;
 BufStart = Buffer;
 ArgPtr = (__int64 *)(VaList - 8);

 if (!Buffer || !Format)
 return -1;

 if (BufferSize == 1)
 {
 *BufStart = 0;
 return 0;
 }

 while (TRUE)
 {
 FmtCh = *Fmt;
 if (!FmtCh)
 {
 *BufStart = 0;
 return (Buf - Buffer);
 }
 Fmt++;

 if (FmtCh != '%')
 {
 *Buf++ = FmtCh;
 SavedBufSize--;
 goto CheckSize;
 }

 if (*Fmt == '%')
 {
 Fmt++;
 *Buf++ = '%';
 goto CheckSize;
 }

 // Parse precision flag PadCh = ' ';
 if (*Fmt == '0')
 {
 PadCh = '0';
 Fmt++;
 }

 // Parse width switch (*Fmt)
 {
 case '*':
 Fmt++;
 ArgPtr++;
 Width = *(UINT32 *)ArgPtr;
 break;

 case 's':
 ArgPtr++;
 for (StrP = (CHAR16 *)ArgPtr[1]; *StrP; StrP++)
 {
 if (!--SavedBufSize)
 goto Overflow;
 *Buf++ = *StrP;
 }
 goto ContinueFmt;

 case 'S':
 case 'a':
 ArgPtr++;
 for (ArgS = (CHAR8 *)ArgPtr[1]; *ArgS; ArgS++)
 {
 if (!--SavedBufSize)
 goto Overflow;
 *Buf++ = (CHAR16)*ArgS;
 }
 goto ContinueFmt;

 default:
 {
 INTN Parsed = sub_13C0 ((char *)Fmt, (char **)&Fmt);
 Width = (UINT32)Parsed;
 }
 ArgPtr = (__int64 *)Fmt;
 break;
 }

 if (*Fmt != 'c')
 break;

 // %c ArgPtr++;
 *Buf++ = (CHAR16)((UINT16 *)ArgPtr)[4];
 goto ContinueFmt;

Overflow:
 *Buf = 0;
 return (Buf - Buffer);
 }

 // Handle %g / %G (GUID format)
 if ((*Fmt & 0xDF) == 'G')
 {
 CHAR16 *GuidBuf = Buf;
 ArgPtr++;
 ArgU32 = (UINT32 *)ArgPtr[1];

 Count = sub_1A00 (
 Buf,
 SavedBufSize,
 L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
 *ArgU32,
 (UINT16)ArgU32[1],
 (UINT16)ArgU32[2],
 (UINT8)ArgU32[3],
 *((UINT8 *)ArgU32 + 12),
 *((UINT8 *)ArgU32 + 13),
 *((UINT8 *)ArgU32 + 14),
 *((UINT8 *)ArgU32 + 15),
 *((UINT8 *)ArgU32 + 8),
 *((UINT8 *)ArgU32 + 9),
 *((UINT8 *)ArgU32 + 10),
 *((UINT8 *)ArgU32 + 11));
 Buf += Count;

 if (*Fmt == 'G')
 {
 for (P = GuidBuf; *P; P++)
 {
 if ((UINT16)(*P - 'a') <= 0x19)
 *P -= 32;
 }
 }
 SavedBufSize -= Count;
 goto ContinueFmt;
 }

 // %r (EFI_STATUS)
 if (*Fmt == 'r')
 {
 ArgPtr++;
 const char *StatusStr = sub_1498 (ArgPtr[1]);
 if (StatusStr)
 Count = sub_1A00 (Buf, SavedBufSize, L"%S", StatusStr);
 else Count = sub_1A00 (Buf, SavedBufSize, L"%S(%X)", "Status Code", ArgPtr[1] >> 32);
 Buf += Count;
 SavedBufSize -= Count;
 goto ContinueFmt;
 }

 // %l (long prefix)
 if (*Fmt == 'l')
 {
 Fmt++;
 LongArg = TRUE;
 }
 else
 {
 LongArg = FALSE;
 }

 // Now parse d, i, x, X, p CHAR16 TypeCh = *Fmt;
 int Radix;
 if (TypeCh == 'd' || TypeCh == 'i')
 Radix = 10;
 else if ((TypeCh & 0xDF) == 'X')
 Radix = 16;
 else goto ContinueFmt; // Skip unknown format ArgPtr++;
 CHAR16 *DigitEnd;

 if (LongArg)
 {
 // 64-bit value _BYTE *DigitP;
 if (LongArg == 'p')
 {
 // pointer DigitP = sub_134C (ArgPtr[1], DigitBuf2, Radix, 0);
 }
 else
 {
 DigitP = sub_134C (ArgPtr[1], DigitBuf2, Radix, 1);
 }
 for (DigitEnd = DigitStr; DigitP >= DigitBuf2; DigitP--)
 *DigitEnd++ = (CHAR16)*DigitP;
 }
 else
 {
 // 32-bit value _BYTE *DigitP;
 if (LongArg == 'p')
 DigitP = sub_134C (*(INT32 *)ArgPtr, DigitBuf, Radix, 0);
 else DigitP = sub_134C (*(INT32 *)ArgPtr, DigitBuf, Radix, 0);
 for (DigitEnd = DigitStr; DigitP >= DigitBuf; DigitP--)
 *DigitEnd++ = (CHAR16)*DigitP;
 }

 *DigitEnd = 0;

 if (TypeCh == 'X' || TypeCh == 'p')
 {
 // Uppercase hex digits for (P = DigitStr; *P; P++)
 {
 if ((UINT16)(*P - 'a') <= 0x19)
 *P -= 32;
 }
 }

 // Width padding I = 0;
 if (DigitStr[0])
 {
 do { I++; } while (DigitStr[I]);
 }

 while (I < Width)
 {
 I++;
 if (!--SavedBufSize)
 goto Overflow;
 *Buf++ = PadCh;
 }

 // Copy digits if (DigitStr[0])
 {
 for (P = DigitStr; *P; P++)
 {
 if (!--SavedBufSize)
 goto Overflow;
 *Buf++ = *P;
 }
 }

ContinueFmt:
 Fmt++;
 goto CheckSize;

CheckSize:
 if (SavedBufSize == 1)
 {
 *BufStart = 0;
 return (Buf - Buffer);
 }
}

// ===========================================================================
// Unicode SPrint (va_list) (sub_1A00)
// ===========================================================================

UINTN sub_1A00 (
 __int16 *Buffer,
 __int64 BufferSize,
 CONST CHAR16 *Format,
 ...
 )
{
 UINTN Result;
 va_list Va;

 va_start (Va, Format);
 Result = sub_1588 (Buffer, BufferSize, Format, (__int64)Va);
 va_end (Va);
 return Result;
}

// ===========================================================================
// Get ME Firmware Status from HOB (sub_1A20)
// ===========================================================================

UINT32 sub_1A20 (
 UINT32 DefaultFs1
 )
{
 UINT32 Fs1;
 _WORD *Hob;
 _WORD *MeHob;
 EFI_GUID *Guid;

 Fs1 = (UINT32)-1;
 Hob = (_WORD *)sub_1278 ();
 MeHob = sub_12FC (0, Hob);

 if (!MeHob)
 goto NotFound;

 do
 {
 Guid = (EFI_GUID *)(MeHob + 4);
 if (sub_1090 ((__int64)&gEfiMeFwHobGuid, (__int64)Guid))
 break;
 MeHob = sub_12FC (0, (_WORD *)((UINT8 *)MeHob + MeHob[1]));
 }
 while (MeHob);

 if (!MeHob)
 goto NotFound;

 if (((UINT32 *)MeHob)[7] != 0)
 {
 sub_FEC (
 (__int64)"e:\\hs\\PurleySktPkg\\Me\\Heci\\Library\\MeTypeLib\\MeTypeLib.c",
 67,
 (__int64)"MeFwHob->Group[0].FunNumber == HECI1_DEVICE");
 }
 else
 {
 Fs1 = ((UINT32 *)MeHob)[8];
 }

 if (Fs1 != (UINT32)-1)
 {
NotFound:
 sub_F64 (0x80000000LL, "HECI: GetMeFs1FromHob() Can't read correctly MeFwHob info\n");
 Fs1 = DefaultFs1;
 }

 sub_F64 (64, "HECI: GetMeFs1FromHob() returns MEFS1 = %d\n", Fs1);
 return Fs1;
}

// ===========================================================================
// Unaligned Read 8 bytes (sub_1AD8)
// ===========================================================================

UINT64 sub_1AD8 (
 __int64 a1
 )
{
 if (!a1)
 sub_FEC (
 (__int64)"e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
 192,
 (__int64)"Buffer != ((void *) 0)");
 return *(UINT64 *)a1;
}

// ===========================================================================
// CPUID Wrapper (sub_1B10)
// ===========================================================================

UINT32 sub_1B10 (
 UINT32 EaxIn,
 UINT32 *EaxOut,
 UINT32 *EbxOut,
 UINT32 *EcxOut,
 UINT32 *EdxOut
 )
{
 UINT32 Eax, Ebx, Ecx, Edx;

 AsmCpuid (EaxIn, &Eax, &Ebx, &Ecx, &Edx);

 if (EaxOut) *EaxOut = Eax;
 if (EbxOut) *EbxOut = Ebx;
 if (EcxOut) *EcxOut = Ecx;
 if (EdxOut) *EdxOut = Edx;

 return Eax;
}

// ===========================================================================
// ZeroMem (sub_1B50) - jump to sub_1B5E
// ===========================================================================

void sub_1B50 (
 __int64 Buffer,
 __int64 Value,
 int Size
 )
{
 sub_1B5E ((int *)Buffer, (UINTN)Size, (unsigned int)Value);
}

// ===========================================================================
// memset (sub_1B5E)
// ===========================================================================

int *sub_1B5E (
 int *Buffer,
 UINTN Size,
 unsigned int Value
 )
{
 int *Buf;
 UINTN Remaining;
 unsigned int FillWord;
 UINTN Align;

 Buf = Buffer;
 Remaining = Size;
 FillWord = (Value & 0xFFFF) | ((Value & 0xFFFF) << 16);

 if (Size >= 4)
 {
 Align = (UINTN)Buf & 3;
 if (Align != 0)
 {
 memset (Buf, (int)(UINT8)Value, 4 - Align);
 Buf = (int *)((UINT8 *)Buf + 4 - Align);
 Remaining -= 4 - Align;
 }

 // Write aligned dwords for (I = Remaining >> 2; I; I--)
 *Buf++ = FillWord;

 Remaining = Remaining & 3;
 }

 memset (Buf, (int)(UINT8)Value, Remaining);
 return Buffer;
}

// ===========================================================================
// memcpy (sub_1BB0)
// ===========================================================================

char *sub_1BB0 (
 char *Dst,
 const char *Src,
 UINTN Size
 )
{
 char *OrigDst;
 UINTN Count;
 BOOLEAN Reverse;
 UINTN Offset;
 UINTN Align;

 OrigDst = Dst;
 Count = Size;
 Reverse = FALSE;

 // If overlapping and Src < Dst, copy from end if ((Src < Dst) && (&Src[Size] > Dst))
 {
 Src += Size;
 Dst += Size;
 Reverse = TRUE;
 }

 // Use aligned copy for sizes >= 8 and sufficient distance if (Size >= 8 && ((Src > Dst) ? (Src - Dst) : (Dst - Src)) >= 8)
 {
 Offset = (UINTN)Src & 7;

 if (Reverse)
 {
 Src--;
 Dst--;
 }

 // Align Src and Dst to same offset if ((Offset == ((UINTN)Dst & 7)) && Offset)
 {
 if (!Reverse)
 Offset = 8 - Offset;
 CopyMem (Dst, Src, Offset);
 Src += Offset;
 Dst += Offset;
 Count = Size - Offset;
 }

 if (Reverse)
 {
 Src -= 7;
 Dst -= 7;
 }

 // Copy 8 bytes at a time UINT64 Chunks = Count >> 3;
 CopyMem (Dst, Src, 8 *Chunks);
 Src += 8 *Chunks;
 Dst += 8 *Chunks;
 Count = Count & 7;

 if (Count)
 {
 if (Reverse)
 {
 Src += 8;
 Dst += 8;
 }
 }
 }

 if (Count)
 {
 if (Reverse)
 {
 Src--;
 Dst--;
 }
 CopyMem (Dst, Src, Count);
 }

 return OrigDst;
}

// ===========================================================================
// Simple memset (sub_2A0)
// ===========================================================================

char *sub_2A0 (
 char *Buf,
 UINTN Size
 )
{
 memset (Buf, 0, 8 * (Size >> 3));
 memset (&Buf[8 * (Size >> 3)], 0, Size & 7);
 return Buf;
}