/**
*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;
}