/**
* NetworkStackSetupScreen.c
*
* Full decompilation of the NetworkStackSetupScreen DXE driver from Lenovo
* HR650X BIOS. This driver manages the "Network Stack" setup screen
* configuration variable. On first boot, it creates the "NetworkStackVar"
* UEFI variable with default settings. At each subsequent boot it reads the
* existing variable and checks CMOS NV storage to determine the enabled /
* disabled status.
*
* Binary: AmiBoardInfo2.efi (PE32+ X64, ~0x18A0 bytes)
* Source (PDB): e:\hs\AmiModulePkg\BoardInfo\AmiBoardInfo2.c
* https://github.com/ami/AmiModulePkg/BoardInfo/AmiBoardInfo2.c
*
* Reconstructed by: hr650x-bios-re
* Tools: IDA Pro 9.0 + Hex-Rays
*/
#include "AmiBoardInfo2.h"
//
// ---------------------------------------------------------------------------
// Global variable storage (mapped from .data section)
// ---------------------------------------------------------------------------
//
EFI_HANDLE gImageHandle_ = NULL; // 0xD00 (.data)
EFI_SYSTEM_TABLE *gST_ = NULL; // 0xCF0 (.data)
EFI_BOOT_SERVICES *gBS_ = NULL; // 0xCF8 (.data)
EFI_RUNTIME_SERVICES *gRT_ = NULL; // 0xD08 (.data)
//
// Cached protocol pointer (located by sub_4F8)
//
EFI_AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfoProtocol = NULL; // 0xD10 (.data)
//
// Cached HOB list pointer (located by sub_600 -> GetHobList)
//
EFI_PHYSICAL_ADDRESS gHobListRva = 0; // 0xD18 (.data)
//
// Second copies of service pointers (aliased .data at 0xD20/0xD28/0xD30)
//
UINT64 gBS_1 = 0; // 0xD20
UINT64 gRT_1 = 0; // 0xD28
UINT64 gST_1 = 0; // 0xD30
//
// NetworkStackVar data buffer (10 bytes at 0xD40)
//
NETWORK_STACK_VAR gNvData; // 0xD40..0xD49
//
// Byte-level aliases into gNvData (overlay)
//
UINT8 gNvBootFlag = 0; // byte_D45 (offset 5)
UINT16 gNvReservedWord = 0; // word_D46 (offset 6)
//
// ---------------------------------------------------------------------------
// GUID definitions
// ---------------------------------------------------------------------------
//
//
// GUID for the AMI Board Info Protocol.
// The protocol interface is located via gBS->LocateProtocol.
// Stored at .data 0xCC0.
//
EFI_GUID gAmiBoardInfoProtocolGuid = {
0xCC0, 0xCC1, 0xCC2,
{ 0xCC3, 0xCC4, 0xCC5, 0xCC6, 0xCC7, 0xCC8, 0xCC9, 0xCCA }
};
//
// PiHobList GUID (standard UEFI PiHobList GUID).
// Used to locate the HOB list from the system table configuration table.
// Stored as two halves at .data 0xCD0 (first 8 bytes) and 0xCD8 (second 8).
//
EFI_GUID gPiHobListGuid = {
0xCD0, 0xCD1, 0xCD2,
{ 0xCD3, 0xCD4, 0xCD5, 0xCD6, 0xCD7, 0xCD8, 0xCD9, 0xCDA }
};
//
// Vendor GUID for the NetworkStackVar variable.
// Stored at .data 0xCE0.
//
EFI_GUID gAmiBoardInfoVarGuid = {
0xCE0, 0xCE1, 0xCE2,
{ 0xCE3, 0xCE4, 0xCE5, 0xCE6, 0xCE7, 0xCE8, 0xCE9, 0xCEA }
};
//
// ---------------------------------------------------------------------------
// Forward declarations
// ---------------------------------------------------------------------------
//
UINT64
EFIAPI
ReadUnalignedQword (
IN VOID *Buffer
);
BOOLEAN
EFIAPI
CompareGuidQword (
IN VOID *Buffer1,
IN VOID *Buffer2
);
UINTN
EFIAPI
CmosReadNvStorage (
VOID
);
EFI_AMI_BOARD_INFO_PROTOCOL *
EFIAPI
LocateAmiBoardInfoProtocol (
VOID
);
VOID
EFIAPI
AmiBoardInfoAssert (
IN CHAR8 *FileName,
IN UINTN LineNumber,
IN CHAR8 *Expression
);
EFI_STATUS
EFIAPI
AmiBoardInfoConditionalSend (
IN UINTN Mask,
IN UINTN Arg2,
...
);
EFI_PHYSICAL_ADDRESS
EFIAPI
GetHobList (
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
EFIAPI
AmiBoardInfoInit (
IN UINTN N10Param,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
EFIAPI
AmiBoardInfoEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
//
// ---------------------------------------------------------------------------
// sub_798: ReadUnalignedQword
// ---------------------------------------------------------------------------
//
/**
Read an unaligned 64-bit value from a buffer.
Dereferences the pointer as UINT64*.
@param[in] Buffer Pointer to read from (must not be NULL).
@return UINT64 value at the address.
**/
UINT64
EFIAPI
ReadUnalignedQword (
IN VOID *Buffer
)
{
ASSERT (Buffer != NULL);
return *(UINT64 *)Buffer;
}
//
// ---------------------------------------------------------------------------
// sub_728: CompareGuidQword
// ---------------------------------------------------------------------------
//
/**
Compare two 8-byte (QWORD) values by unaligned read.
Reads 8 bytes from each pointer and returns TRUE if equal.
@param[in] Buffer1 First buffer.
@param[in] Buffer2 Second buffer.
@return TRUE if first 8 bytes are equal, FALSE otherwise.
**/
BOOLEAN
EFIAPI
CompareGuidQword (
IN VOID *Buffer1,
IN VOID *Buffer2
)
{
return (BOOLEAN)(
ReadUnalignedQword (Buffer1) == ReadUnalignedQword (Buffer2)
);
}
//
// ---------------------------------------------------------------------------
// sub_6D8: CmosReadNvStorage
// ---------------------------------------------------------------------------
//
/**
Read the CMOS NV storage diagnostic status register (0x4B) to determine
whether the network stack has been enabled or disabled by the platform
setup utility.
CMOS register 0x4B layout (diagnostic status byte):
Bit 7 : RTC power-good flag (1 = valid)
Bits 6:2 : other diagnostic flags (unused)
Bit 1 : when Bit 0 is 0, set = network stack disabled (value 2)
Bit 0 : set = network stack enabled (value 1)
Fallback: if the CMOS register reads 0 but appears valid (>3), it
reads a fixed byte at physical address 0xFDAF0490 as override.
@return UINTN
EFI_NETWORK_STACK_ENABLED (0x80000004) if NvStorage == 1,
EFI_NETWORK_STACK_DISABLED (0x80000006) if NvStorage == 2,
0 if NvStorage is invalid/unavailable.
**/
UINTN
EFIAPI
CmosReadNvStorage (
VOID
)
{
UINT8 DiagnosticValue;
UINT8 NvStorage;
//
// Save current index, select CMOS diagnostic register (0x4B).
// Mask bit 7 (power good flag) to access the register number.
//
IoWrite8 (
CMOS_REG_INDEX_PORT,
(IoRead8 (CMOS_REG_INDEX_PORT) & CMOS_DIAG_STATUS_MASK) |
CMOS_DIAGNOSTIC_STATUS_REG
);
//
// Read the diagnostic status value.
//
DiagnosticValue = IoRead8 (CMOS_REG_DATA_PORT);
NvStorage = DiagnosticValue;
if (DiagnosticValue > 3) {
//
// Value appears accessible.
//
if (NvStorage == 0) {
//
// Fallback: read a fixed byte in SPI/flash memory (0xFDAF0490)
// and use bit 1 combined with bit 0 as override indicator.
//
NvStorage = (*(volatile UINT8 *)0xFDAF0490 & 2) | 1;
}
}
//
// Validate: only 1 and 2 are acceptable.
// (NvStorage - 1) > 0xFD catches value == 1 (0), 2 (1), or invalid.
//
if ((UINT8)(NvStorage - 1) > 0xFD) {
//
// NvStorage is not 1 or 2 (or is 0xFF) -> undetermined.
//
return 0;
}
if (NvStorage == 1) {
return EFI_NETWORK_STACK_ENABLED; // 0x80000004
}
return EFI_NETWORK_STACK_DISABLED; // 0x80000006
}
//
// ---------------------------------------------------------------------------
// sub_4F8: LocateAmiBoardInfoProtocol
// ---------------------------------------------------------------------------
//
/**
Locate the AMI Board Info Protocol via gBS->LocateProtocol.
This protocol is installed by the board/platform drivers.
It provides:
- Offset 0x00: Debug assertion callback (VOID*)(CHAR8*, UINTN, CHAR8*)
- Offset 0x08: Status/event send callback (EFI_STATUS*)(...)
@return Pointer to EFI_AMI_BOARD_INFO_PROTOCOL, or NULL if
not available or pool allocation fails.
**/
EFI_AMI_BOARD_INFO_PROTOCOL *
EFIAPI
LocateAmiBoardInfoProtocol (
VOID
)
{
EFI_STATUS Status;
VOID *Pool;
if (gAmiBoardInfoProtocol != NULL) {
return gAmiBoardInfoProtocol;
}
//
// Allocate a small pool (EfiBootServicesData) as scratch.
//
Pool = AllocatePool (31); // 31 = EfiBootServicesData
ZeroMem (Pool, 31);
if ((UINTN)Pool > 0x10) {
//
// Unlikely: pool allocation was larger than 16 bytes, fail.
//
FreePool (Pool);
return NULL;
}
//
// Locate the protocol.
//
Status = gBS_->LocateProtocol (
&gAmiBoardInfoProtocolGuid,
NULL, // Registration
(VOID **)&gAmiBoardInfoProtocol
);
if (EFI_ERROR (Status)) {
gAmiBoardInfoProtocol = NULL;
}
return gAmiBoardInfoProtocol;
}
//
// ---------------------------------------------------------------------------
// sub_5C0: AmiBoardInfoAssert
// ---------------------------------------------------------------------------
//
/**
Debug assertion output via the AMI Board Info Protocol.
@param[in] FileName Source file name string.
@param[in] LineNumber Line number of the assertion.
@param[in] Expression Assertion expression string.
**/
VOID
EFIAPI
AmiBoardInfoAssert (
IN CHAR8 *FileName,
IN UINTN LineNumber,
IN CHAR8 *Expression
)
{
EFI_AMI_BOARD_INFO_PROTOCOL *Protocol;
Protocol = LocateAmiBoardInfoProtocol ();
if (Protocol != NULL) {
//
// Offset 0x00: AssertCallback.
// Signature: VOID (*)(CHAR8 *File, UINTN Line, CHAR8 *Expr)
//
Protocol->AssertCallback (FileName, LineNumber, Expression);
}
}
//
// ---------------------------------------------------------------------------
// sub_578: AmiBoardInfoConditionalSend
// ---------------------------------------------------------------------------
//
/**
Conditional status send.
Locates the AMI Board Info Protocol, reads the CMOS NV storage
status via CmosReadNvStorage(), and if (NvResult & Mask) is
non-zero, invokes the protocol's StatusSend callback with
the given arguments.
@param[in] Mask Status mask to compare against CmosReadNvStorage.
@param[in] Arg2 Second argument to StatusSend callback.
@param[in] ... Third argument (varargs, passed as VOID* pointer).
@return EFI_STATUS Result from StatusSend, or EFI_UNSUPPORTED
if protocol/NV check fails.
**/
EFI_STATUS
EFIAPI
AmiBoardInfoConditionalSend (
IN UINTN Mask,
IN UINTN Arg2,
...
)
{
EFI_AMI_BOARD_INFO_PROTOCOL *Protocol;
EFI_STATUS Status;
UINTN NvResult;
VA_LIST Args;
VOID *VaPtr;
Protocol = LocateAmiBoardInfoProtocol ();
if (Protocol == NULL) {
return EFI_UNSUPPORTED;
}
NvResult = CmosReadNvStorage ();
if ((NvResult & Mask) == 0) {
//
// CMOS NV storage status does not match Mask.
//
return EFI_UNSUPPORTED;
}
//
// Status matches; invoke StatusSend callback at offset 0x08.
//
VA_START (Args, Arg2);
VaPtr = VA_ARG (Args, VOID *);
VA_END (Args);
Status = Protocol->StatusSend (Mask, Arg2, (UINTN)VaPtr);
return Status;
}
//
// ---------------------------------------------------------------------------
// sub_600: GetHobList
// ---------------------------------------------------------------------------
//
/**
Get the HOB (Hand-Off Block) list pointer.
Walks the system table's configuration table array searching for
the entry whose VendorGuid matches the PiHobList GUID. The HOB
list pointer is cached in the global gHobListRva.
@param[in] SystemTable Pointer to the UEFI system table.
@return EFI_PHYSICAL_ADDRESS Pointer to the HOB list, or 0 on failure.
**/
EFI_PHYSICAL_ADDRESS
EFIAPI
GetHobList (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINTN Index;
UINTN TableCount;
if (gHobListRva != 0) {
return gHobListRva;
}
//
// Initialize to NULL.
//
gHobListRva = 0;
TableCount = SystemTable->NumberOfTableEntries;
if (TableCount == 0) {
goto FAIL;
}
//
// Walk the configuration table array.
// Each entry is sizeof(EFI_CONFIGURATION_TABLE) bytes = 24 bytes:
// 16 bytes VendorGuid + 8 bytes VendorTable pointer.
//
for (Index = 0; Index < TableCount; Index++) {
EFI_CONFIGURATION_TABLE *ConfigEntry;
ConfigEntry = (EFI_CONFIGURATION_TABLE *)
((UINT8 *)SystemTable->ConfigurationTable +
(Index * sizeof (EFI_CONFIGURATION_TABLE)));
if (CompareGuidQword (
&gPiHobListGuid,
&ConfigEntry->VendorGuid
)) {
//
// Found the HOB list entry.
//
gHobListRva = (EFI_PHYSICAL_ADDRESS)ConfigEntry->VendorTable;
break;
}
}
if (gHobListRva == 0) {
FAIL:
//
// ASSERT failure on debug builds. The original binary called
// sub_578 (conditional send) with:
// mask = 0x80000000LL
// arg2 = "\nASSERT_EFI_ERROR (Status = %r)\n" string ref
// arg3 = 0x800000000000000EuLL (EFI_NOT_FOUND)
//
AmiBoardInfoConditionalSend (
0x80000000LL,
(UINTN)"\nASSERT_EFI_ERROR (Status = %r)\n",
0x800000000000000EuLL
);
AmiBoardInfoAssert (
"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
54,
"!EFI_ERROR (Status)"
);
}
if (gHobListRva == 0) {
AmiBoardInfoAssert (
"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
55,
"mHobList != ((void *) 0)"
);
}
return gHobListRva;
}
//
// ---------------------------------------------------------------------------
// sub_41C: AmiBoardInfoInit
// ---------------------------------------------------------------------------
//
/**
Initialize the AmiBoardInfo variable.
Reads the "NetworkStackVar" (AmiBoardInfoVar) UEFI variable. If not
found (EFI_NOT_FOUND = 0x800000000000000EuLL), allocates a buffer,
sets default values, and writes the variable.
Default values:
Flags = 0x1000000
BootFlag = 1
word_D46 = 0
@param[in] N10Param Unused parameter (always 10).
@param[in] SystemTable Pointer to the UEFI system table.
@return EFI_SUCCESS Always returns success.
**/
EFI_STATUS
EFIAPI
AmiBoardInfoInit (
IN UINTN N10Param,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINTN VarSize;
EFI_STATUS Status;
//
// Cache services if not already set (by entry point).
//
if (gST_ == NULL) {
gST_ = SystemTable;
gBS_ = SystemTable->BootServices;
gRT_ = SystemTable->RuntimeServices;
}
//
// Try to read the existing variable.
//
VarSize = sizeof (gNvData); // = NETWORK_STACK_VAR_DATA_SIZE = 10
Status = gRT_->GetVariable (
NETWORK_STACK_VAR_NAME,
&gAmiBoardInfoVarGuid,
NULL, // Attributes (returned)
&VarSize,
&gNvData
);
if (Status == EFI_NOT_FOUND) {
//
// Variable does not exist: zero the buffer and set defaults.
//
gBS_->SetMem (&gNvData, sizeof (gNvData), 0);
gNvReservedWord = 0; // word_D46
gNvBootFlag = 1; // byte_D45
gNvData.Flags = 0x1000000; // default flag value
//
// Write the variable as non-volatile + boot + runtime.
//
Status = gRT_->SetVariable (
NETWORK_STACK_VAR_NAME,
&gAmiBoardInfoVarGuid,
(EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS),
sizeof (gNvData),
&gNvData
);
//
// Original driver does not check SetVariable status.
//
}
return EFI_SUCCESS;
}
//
// ---------------------------------------------------------------------------
// _ModuleEntryPoint (0x370) -> AmiBoardInfoEntryPoint
// ---------------------------------------------------------------------------
//
/**
Entry point for the AMI Board Info (NetworkStackSetupScreen) DXE driver.
Saves ImageHandle, SystemTable, BootServices, and RuntimeServices
into global variables, then initializes the HOB list, and finally
calls AmiBoardInfoInit().
@param[in] ImageHandle Handle of this driver image.
@param[in] SystemTable Pointer to the UEFI system table.
@return EFI_STATUS Return value from AmiBoardInfoInit().
**/
EFI_STATUS
EFIAPI
AmiBoardInfoEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
//
// Save global handles (standard UEFI boot services library pattern).
//
gImageHandle_ = ImageHandle;
ASSERT (gImageHandle_ != NULL);
gST_ = SystemTable;
ASSERT (gST_ != NULL);
gBS_ = SystemTable->BootServices;
ASSERT (gBS_ != NULL);
gRT_ = SystemTable->RuntimeServices;
ASSERT (gRT_ != NULL);
//
// Locate and cache the HOB list pointer.
//
GetHobList (SystemTable);
//
// Initialize the board info variable ("NetworkStackVar").
//
return AmiBoardInfoInit (10, SystemTable);
}