/**
* @file IioCfgUpdateDxeLightningRidgeEXECB1.c
*
* @brief IioCfgUpdateDxeLightningRidgeEXECB1 - UEFI DXE driver for registering
* IIO configuration data on the LightningRidgeEXECB1 platform.
*
* MODULE TYPE: DXE Driver
* UEFI PHASE: DXE (Driver Execution Environment)
*
* PURPOSE:
* Registers up to 4 IIO (Integrated IO) configuration protocol instances
* through the UBA (Unified Board Architecture) framework. Each instance
* corresponds to a CPU socket's IIO configuration table.
*
* SOURCE PATH (build machine):
* e:\hs\Build\HR6N0XMLK\DEBUG_VS2015\X64\PurleyRpPkg\Uba\UbaMain\Dxe\
* TypeLightningRidgeEXECB1\IioCfgUpdateDxe\IioCfgUpdateDxe\
* DEBUG\IioCfgUpdateDxeLightningRidgeEXECB1.pdb
*
* BOARD ID: 0x0D60 (LightningRidgeEXECB1)
* IIO CFG TABLE SIZE: 0x50C (1292 bytes, 21 entries of 12 bytes + padding)
*
* @see IioCfgUpdateDxeLightningRidgeEXECB1.h for type definitions and GUIDs.
*/
#include "IioCfgUpdateDxeLightningRidgeEXECB1.h"
// ============================================================================
// Module Globals
// ============================================================================
///
/// Cached debug protocol interface (initialized on first use).
///
VOID *gDebugProtocol = NULL;
///
/// Cached HOB list pointer (initialized on first use).
///
VOID *gHobList = NULL;
// ============================================================================
// GUID Definitions (instances)
// ============================================================================
///
/// EFI_HOB_LIST_GUID instance - used to locate HOB list in configuration table.
///
EFI_GUID gEfiHobListGuid = EFI_HOB_LIST_GUID;
///
/// UBA Board-Type Protocol GUID - interface to register configuration data.
///
EFI_GUID gUbaBoardTypeProtocolGuid = UBA_BOARD_TYPE_PROTOCOL_GUID;
///
/// UBA IIO Config Update protocol GUIDs (one per CPU socket).
///
static EFI_GUID gIioCfgUpdateProtocolGuid[IIO_CFG_UPDATE_PROTOCOL_COUNT] = {
UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_0, ///< Socket 0
UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_1, ///< Socket 1
UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_2, ///< Socket 2
UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_3 ///< Socket 3
};
///
/// UBA Debug Protocol GUID - protocol for debug output.
///
EFI_GUID gUbaDebugProtocolGuid = UBA_DEBUG_PROTOCOL_GUID;
// ============================================================================
// IIO Configuration Table
// ============================================================================
///
/// UBA_IIO_CFG_UPDATE_PROTOCOL - The IIO configuration protocol structure
/// that is registered for each CPU socket on this platform.
///
/// This structure describes the IIO configuration table layout:
/// - Signature: "PIIO"
/// - BoardId: 0x0D60
/// - SlotNumber: 0x3C (60)
/// - IioCfgTableSize: 0x50C (1292 bytes)
/// - IioCfgTable: offset to IioCfgTable[] below
/// - Reserved1: 0xFC
///
STATIC CONST UBA_IIO_CFG_UPDATE_PROTOCOL mIioCfgProtocol = {
UBA_IIO_CFG_UPDATE_SIGNATURE, ///< Signature "PIIO"
LIGHTNINGRIDGE_EXECB1_BOARD_ID, ///< BoardId = 0x0D60
0, ///< Reserved0 (padding)
LIGHTNINGRIDGE_EXECB1_SLOT_NUMBER, ///< SlotNumber = 0x3C
LIGHTNINGRIDGE_EXECB1_IIO_CFG_SIZE, ///< IioCfgTableSize = 0x50C
(UINT64)(UINTN)&mIioCfgTable[0], ///< IioCfgTable pointer
0xFC ///< Reserved1
};
///
/// IIO configuration table for LightningRidgeEXECB1.
///
/// This table contains 21 entries of 12 bytes each (252 bytes total),
/// with the remaining space (0x50C - 252 = 1040 bytes) being padding/reserved.
///
/// Each entry configures an IIO register/port for a specific socket function.
///
/// Entry format (UBA_IIO_CFG_UPDATE_TABLE_ENTRY):
/// Byte 0: Type (function/register selector)
/// Byte 1: SubType (sub-function or qualifier)
/// Bytes 2-3: Reserved
/// Bytes 4-7: Reserved
/// Byte 8: Value (target data)
/// Byte 9: Port (target port/address)
/// Bytes 10-11: Reserved
///
/// The 0xFF bytes in the reserved fields indicate "don't care" / unchecked.
/// The board config protocol performs the actual IIO register programming
/// based on these entries.
///
STATIC CONST UINT8 mIioCfgTable[0x50C] = {
// ---- Entry 0: UPT (0x01) PCIE (0x4C) Slot=01, Port=00 ----
0x01, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0x4C, 0x01,
// ---- Entry 1: UPT (0x02) PCIE (0x4C) Slot=01, Port=01 ----
0x02, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0x01, 0x4C, 0x01,
// ---- Entry 2: UPT (0x03) PCIE (0x4E) Slot=01, Port=00 ----
0x03, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0x4E, 0x01,
// ---- Entry 3: UPT (0x04) PCIE (0x4E) Slot=01, Port=01 ----
0x04, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0x01, 0x4E, 0x01,
// ---- Entry 4: UPT (0x05) None/Disabled ----
0x05, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 5: UPT (0x09) PCIE (0x40) ----
0x09, 0x01, 0x01, 0xFF, 0xFF, 0x01, 0x00, 0x40, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 6: UPT (0x15) None/Disabled ----
0x15, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01,
// ---- Entry 7: UPT (0x16) ----
0x16, 0x05, 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 8: UPT (0x1A) ----
0x1A, 0x07, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 9: UPT (0x1E) ----
0x1E, 0x0A, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0x40, 0x00,
// ---- Entry 10: UPT (0x1F) PCIE (0x40) ----
0x1F, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0x01, 0x40, 0x01,
// ---- Entry 11: UPT (0x20) PCIE (0x42) ----
0x20, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0x42, 0x01,
// ---- Entry 12: UPT (0x21) PCIE (0x42) ----
0x21, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0x01, 0x42, 0x01,
// ---- Entry 13: UPT (0x2A) ----
0x2A, 0x0E, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 14: UPT (0x2B) ----
0x2B, 0x06, 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 15: UPT (0x2F) ----
0x2F, 0x0F, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 16: UPT (0x33) ----
0x33, 0x08, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 17: UPT (0x3F) ----
0x3F, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01,
// ---- Entry 18: UPT (0x40) ----
0x40, 0x13, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 19: UPT (0x44) ----
0x44, 0x04, 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Entry 20: UPT (0x48) ----
0x48, 0x02, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
// ---- Padding to fill 0x50C bytes ----
[0x0FC ... 0x50B] = 0x00
};
// ============================================================================
// Static Data: UBA Board Config Table
// ============================================================================
///
/// UBA board configuration lookup table at offset 0xD60.
///
/// This small table provides a mapping between UBA protocol indices and
/// board configuration data. Format is 12 bytes per entry.
///
/// For LightningRidgeEXECB1, this table contains 20 entries mapping
/// protocol-to-protocol connections for the 4 IIO sockets.
///
STATIC CONST UINT8 mUbaBoardConfigTable[] = {
/* 00 */ 0x00, 0x04, 0x00, 0x01, 0x04, 0x00, 0x02, 0x04, 0x00, 0x03, 0x04, 0x00,
/* 04 */ 0x04, 0x04, 0x01, 0x00, 0x04, 0x01, 0x01, 0x04, 0x01, 0x02, 0x04, 0x01,
/* 03 */ 0x04, 0x01, 0x04, 0x04, 0x02, 0x00, 0x04, 0x02, 0x01, 0x04, 0x02, 0x02,
/* 04 */ 0x03, 0x04, 0x02, 0x04, 0x04, 0x03, 0x00, 0x04, 0x03, 0x01, 0x04, 0x03,
/* 02 */ 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04,
[0x3C ... 0x3F] = 0x00
};
// ============================================================================
// Function Implementations
// ============================================================================
/**
* Returns the UEFI status code for "Not Found".
*
* Trivial stub function at address 0x50C that returns EFI_NOT_FOUND.
* May be used as a fallback handler or placeholder by the UBA framework.
*
* @return EFI_NOT_FOUND (0x800000000000000E).
*/
EFI_STATUS
ReturnNotFound (
VOID
)
{
return EFI_NOT_FOUND;
}
/**
* Resolves and caches the UBA DebugLib protocol interface.
*
* This function implements the pattern found in other UBA DXE modules:
* 1. Check if the protocol is already cached in gDebugProtocol
* 2. If not cached, raise TPL to TPL_HIGH_LEVEL for atomic access
* 3. Call gBS->LocateProtocol() with UBA_DEBUG_PROTOCOL_GUID
* 4. Restore previous TPL
* 5. Cache and return the result
*
* The HOB allocation size check (>= 0x10) filters out single-package
* platforms that don't have the debug protocol.
*
* @return Pointer to the UBA DebugLib protocol interface.
* Returns NULL if the protocol could not be located.
*/
VOID *
GetDebugProtocol (
VOID
)
{
EFI_TPL OldTpl;
EFI_STATUS Status;
VOID *Protocol;
// Check cache first
if (gDebugProtocol != NULL) {
return gDebugProtocol;
}
// Raise TPL to TPL_HIGH_LEVEL (31) for critical section
OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
// Check if HOB allocation size indicates a multi-package platform
// (HOB with size > 0x10 means there are resources for protocol lookup)
if (gHobList != NULL && *(UINT16 *)((UINT8 *)gHobList + 4) > 0x10) {
// Restore TPL and return NULL - protocol not available on this platform
gBS->RestoreTPL (OldTpl);
return NULL;
}
// Locate the UBA Debug protocol
Status = gBS->LocateProtocol (
&gUbaDebugProtocolGuid, ///< Protocol GUID
NULL, ///< No registration handle
&Protocol ///< Returned protocol interface
);
if (!EFI_ERROR (Status)) {
gDebugProtocol = Protocol;
} else {
gDebugProtocol = NULL;
}
// Restore TPL
gBS->RestoreTPL (OldTpl);
return gDebugProtocol;
}
/**
* Debug print function (wraps the UEFI DebugLib protocol).
*
* Checks the CMOS board-type register to determine if debug output at the
* given severity level should be produced. If so, calls the DebugLib protocol's
* output function at interface offset 0x08.
*
* The CMOS register 0x4B encodes the board type:
* - 0 : Board type is derived from MMIO register 0xFDAF0490
* - 1-3: Direct board type values (standard types)
* - >3 : Non-standard type, used as-is
*
* The debug level mask 0x80000000 (DEBUG_INFO) is compared against the
* board type's configured debug mask to determine if output is enabled.
*
* @param[in] ErrorLevel The debug error level mask.
* Typically DEBUG_INFO (0x80000000).
* @param[in] Format A format string for the debug message.
* @param[in] ... Variable arguments for the format string.
*
* @return The return value from the DebugLib protocol's output function,
* or 0 if the protocol is not available.
*/
UINTN
EFIAPI
DebugPrint (
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
...
)
{
UINTN Result;
UINT8 BoardType;
UINT8 BoardTypeValue;
UINT64 DebugProtocol;
UINT64 DebugMask;
VA_LIST VaList;
UBA_BOARD_TYPE_PROTOCOL *Protocol;
// Get the DebugLib protocol interface
DebugProtocol = (UINTN)GetDebugProtocol ();
if (DebugProtocol == 0) {
return 0;
}
// Read CMOS register 0x4B to get board type
// Port 0x70 = index, port 0x71 = data
BoardType = IoRead8 (RTC_INDEX_PORT);
IoWrite8 (RTC_INDEX_PORT, (BoardType & 0x80) | CMOS_DEBUG_LEVEL_REGISTER);
BoardTypeValue = IoRead8 (RTC_DATA_PORT);
// Determine the board type value
if (BoardTypeValue <= BOARD_TYPE_STANDARD_MAX) {
if (BoardTypeValue == BOARD_TYPE_CMOS_NEEDS_MMIO) {
// When CMOS byte is 0, read from MMIO register and derive board type
BoardTypeValue = (MmioRead8 (BOARD_CONFIG_MMIO_ADDR) & BOARD_TYPE_MMIO_MASK)
| BOARD_TYPE_MMIO_FLAG_BIT;
}
}
// Board type 0 is reserved/invalid (subtract 1 to get index)
// Valid board types are 1, 2, 3 -> indices 0, 1, 2
if ((BoardTypeValue - 1) <= 0xFD) {
// Determine debug mask based on board type index
if (BoardTypeValue == 1) {
DebugMask = 0x80000004; ///< Board type 1: DIAG+ERROR mask
} else {
DebugMask = 0x80000006; ///< Board types 2, 3: VERBOSE+DIAG+ERROR mask
}
} else {
DebugMask = 0;
}
// Check if the requested error level is enabled by the board's debug mask
if ((DebugMask & ErrorLevel) == 0) {
return 0;
}
// Call the DebugLib protocol's output function (offset 0x08)
VA_START (VaList, Format);
Result = (*(UINTN (EFIAPI **)(UINTN, CONST CHAR8 *, VA_LIST))DebugProtocol) (
ErrorLevel, Format, VaList
);
VA_END (VaList);
return Result;
}
/**
* ASSERT assertion failure handler.
*
* Called when a runtime assertion fails (e.g., a NULL pointer check in
* a library function). Resolves the DebugLib protocol via GetDebugProtocol()
* and calls its assertion failure handler at interface offset 0x08.
*
* @param[in] FileName Source file name where the assertion occurred.
* @param[in] LineNumber Line number of the assertion.
* @param[in] Description Description of the failed assertion.
*
* @return 0 if the DebugLib protocol is not available.
*/
UINTN
DebugAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
)
{
UINT64 DebugProtocol;
DebugProtocol = (UINTN)GetDebugProtocol ();
if (DebugProtocol == 0) {
return 0;
}
// Call the DebugLib protocol's assert handler (offset 0x08)
// The assert handler takes (FileName, LineNumber, Description)
return (*(UINTN (EFIAPI **)(CONST CHAR8 *, UINTN, CONST CHAR8 *))DebugProtocol) (
FileName, LineNumber, Description
);
}
/**
* Compares a GUID against the EFI_HOB_LIST_GUID by comparing its first 8 bytes
* and second 8 bytes independently.
*
* Uses ReadUnaligned64() to safely read potentially unaligned GUID pointers.
*
* @param[in] ImageHandle Unused parameter.
* @param[in] GuidPtr Pointer to the GUID to compare.
*
* @retval TRUE The GUID matches EFI_HOB_LIST_GUID.
* @retval FALSE The GUID does not match.
*/
BOOLEAN
IsHobListGuid (
IN EFI_HANDLE ImageHandle,
IN EFI_GUID *GuidPtr
)
{
UINT64 GuidFirstHalf;
UINT64 GuidSecondHalf;
// Read the target GUID as two 64-bit values
GuidFirstHalf = ReadUnaligned64 (GuidPtr);
GuidSecondHalf = ReadUnaligned64 ((UINT8 *)GuidPtr + 8);
// Compare against EFI_HOB_LIST_GUID (7739F24C-93D7-11D4-9A3A-0090273FC14D)
// First 8 bytes: 0xD411D7934CF23977 (little-endian: 7739F24C-93D7-11D4)
// Second 8 bytes: 0x4DC13F2790003A9A (little-endian: 9A3A-0090273FC14D)
return (GuidFirstHalf == 0xD411D7934CF23977ULL)
&& (GuidSecondHalf == 0x4DC13F2790003A9AULL);
}
/**
* Reads an unaligned 64-bit value from memory.
*
* Wraps the BaseLib ReadUnaligned64() function with a NULL pointer check.
* Triggers an ASSERT if called with a NULL buffer.
*
* @param[in] Buffer Pointer to the memory to read. Must not be NULL.
*
* @return The 64-bit value read from the given address.
*/
UINT64
ReadUnaligned64 (
IN CONST VOID *Buffer
)
{
if (Buffer == NULL) {
// Trigger debug assertion via DebugLib
DebugAssert (
"e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
192,
"Buffer != ((void *) 0)"
);
}
// Read 8 bytes from potentially unaligned address
return *(UINT64 *)Buffer; ///< Simple 64-bit read (BaseLib handles unaligned access)
}
/**
* Locates the HOB (Hand-Off Block) list from the UEFI System Table's
* configuration table array.
*
* Iterates through SystemTable->ConfigurationTable[] looking for an entry
* whose VendorGuid matches EFI_HOB_LIST_GUID (7739f24c-93d7-11d4-9a3a-0090273fc14d).
* The comparison is done by matching the first 8 bytes and second 8 bytes of
* the GUID separately using IsHobListGuid().
*
* Results are cached in the global variable gHobList to avoid re-scanning.
*
* If the HOB list is not found, triggers an ASSERT_EFI_ERROR with
* status EFI_UNSUPPORTED (0x800000000000000E).
*
* @param[in] ImageHandle The driver image handle (passed through from entry,
* may be unused).
*
* @return Pointer to the HOB list, or NULL if not found.
*/
VOID *
GetHobList (
IN EFI_HANDLE ImageHandle
)
{
UINTN Index;
UINTN ConfigTableCount;
EFI_CONFIGURATION_TABLE *ConfigTable;
// Check if already cached
if (gHobList != NULL) {
return gHobList;
}
// Initialize to NULL
gHobList = NULL;
ConfigTableCount = gST->NumberOfTableEntries;
if (ConfigTableCount > 0) {
ConfigTable = gST->ConfigurationTable;
// Linear scan through configuration table entries
for (Index = 0; Index < ConfigTableCount; Index++) {
if (IsHobListGuid (ImageHandle, ConfigTable[Index].VendorGuid)) {
// Found the HOB list
gHobList = ConfigTable[Index].VendorTable;
break;
}
}
}
// If HOB list was not found, trigger assertion
if (gHobList == NULL) {
DebugPrint (DEBUG_INFO, "\nASSERT_EFI_ERROR (Status = %r)\n", EFI_UNSUPPORTED);
DebugAssert (
"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
54,
"!EFI_ERROR (Status)"
);
DebugAssert (
"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
55,
"mHobList != ((void *) 0)"
);
}
return gHobList;
}
/**
* Registers all IIO configuration protocol instances for this platform.
*
* This function implements the core purpose of this driver:
* 1. Print a debug banner identifying this module as
* "UBA:IioCfgUpdate-TypeLightningRidgeEXECB1"
* 2. Locate the UBA board-type protocol via gBS->LocateProtocol()
* 3. Register up to 4 IIO configuration protocol instances
* (one per CPU socket) by calling the board-type protocol's
* registration function at interface offset 0x10
*
* Each registration call passes:
* - A unique IIO config protocol GUID (one per socket)
* - The same UBA_IIO_CFG_UPDATE_PROTOCOL structure (48 bytes)
* containing the IIO configuration table
*
* @return EFI_SUCCESS All configurations were registered successfully.
* @return Other The board-type protocol could not be located, or
* one or more registration calls failed.
*/
EFI_STATUS
RegisterIioConfig (
VOID
)
{
EFI_STATUS Status;
UBA_BOARD_TYPE_PROTOCOL *Protocol;
UINTN Index;
// Print debug banner identifying this module
DebugPrint (DEBUG_INFO, "UBA:IioCfgUpdate-TypeLightningRidgeEXECB1\n");
// Locate the UBA board-type protocol
Status = gBS->LocateProtocol (
&gUbaBoardTypeProtocolGuid, ///< Board-type protocol GUID
NULL, ///< No registration handle
(VOID **)&Protocol ///< Returned protocol interface
);
if (EFI_ERROR (Status)) {
return Status;
}
// Register IIO configuration protocol for each CPU socket
for (Index = 0; Index < IIO_CFG_UPDATE_PROTOCOL_COUNT; Index++) {
Status = Protocol->RegisterConfig (
Protocol, ///< This protocol instance
&gIioCfgUpdateProtocolGuid[Index], ///< Socket-specific GUID
(UBA_IIO_CFG_UPDATE_PROTOCOL *)&mIioCfgProtocol, ///< IIO config data
sizeof (mIioCfgProtocol) ///< Size = 48 bytes
);
if (EFI_ERROR (Status)) {
break;
}
}
return Status;
}
/**
* Module entry point for IioCfgUpdateDxeLightningRidgeEXECB1.
*
* Called by the DXE Dispatcher when this driver is loaded. Performs:
* 1. Caches UEFI global variables (gImageHandle, gST, gBS, gRT)
* from the provided SystemTable
* 2. Locates the HOB list from the system configuration table
* (required by GetDebugProtocol() which checks HOB size)
* 3. Calls RegisterIioConfig() to register IIO configuration
* protocols for all CPU sockets
*
* @param[in] ImageHandle The firmware-allocated handle for this driver image.
* @param[in] SystemTable A pointer to the EFI System Table.
*
* @return EFI_SUCCESS IIO configuration was registered successfully.
* @return Other Registration failed.
*/
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
// ==================================================================
// Step 1: Cache UEFI global variables
// ==================================================================
// These are set by the UefiBootServicesTableLib and
// UefiRuntimeServicesTableLib libraries at image startup.
// The asserts below validate the pointers are non-NULL.
// ==================================================================
// gImageHandle: handle for this driver image
gImageHandle = ImageHandle;
if (gImageHandle == NULL) {
DebugAssert (
"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
51,
"gImageHandle != ((void *) 0)"
);
}
// gST: pointer to the UEFI System Table
gST = SystemTable;
if (gST == NULL) {
DebugAssert (
"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
57,
"gST != ((void *) 0)"
);
}
// gBS: pointer to the UEFI Boot Services Table
gBS = SystemTable->BootServices;
if (gBS == NULL) {
DebugAssert (
"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
63,
"gBS != ((void *) 0)"
);
}
// gRT: pointer to the UEFI Runtime Services Table
gRT = SystemTable->RuntimeServices;
if (gRT == NULL) {
DebugAssert (
"e:\\hs\\MdePkg\\Library\\UefiRuntimeServicesTableLib\\UefiRuntimeServicesTableLib.c",
47,
"gRT != ((void *) 0)"
);
}
// ==================================================================
// Step 2: Locate the HOB list
// ==================================================================
// The HOB list is needed by GetDebugProtocol() to check the HOB
// allocation size before deciding whether to locate the debug protocol.
// ==================================================================
GetHobList (ImageHandle);
// ==================================================================
// Step 3: Register IIO configuration protocols
// ==================================================================
Status = RegisterIioConfig ();
return Status;
}