/**
* @file SlotDataUpdateDxeLightningRidgeEXECB1.c
*
* @brief UEFI DXE driver implementation for LightningRidge EXEC B1 slot data update.
*
* This driver is part of the AMI UBA (Universal BIOS Architecture) framework.
* During the DXE phase, it locates the UBA Config protocol and reads PSLT
* (Platform Slot Table) configuration data that defines PCIe slot properties
* for the LightningRidge EXEC B1 platform.
*
* Build source path: PurleyRpPkg/Uba/UbaMain/Dxe/TypeLightningRidgeEXECB1/
* SlotDataUpdateDxe/SlotDataUpdateDxe/
* PDB: SlotDataUpdateDxeLightningRidgeEXECB1.pdb
* Build: VS2015, DEBUG, X64 (PE32+, IMAGE_FILE_MACHINE_AMD64)
*
* CRITICAL NOTE: Unlike the EXRP variant which uses UbaProtocol->SetData to
* install slot configuration, the EXEC B1 variant uses UbaProtocol->GetData
* to read EXISTING configuration. This reflects a different architectural
* role -- the EXEC B1 platform has slot configuration pre-prepared by another
* driver and this driver simply retrieves and validates it.
*
* FUNCTION ADDRESS MAP (from original PE binary):
* 0x390 _ModuleEntryPoint -- DXE driver entry point
* 0x4B0 GetSlotCount -- returns 2 (slot count)
* 0x4B4 GetSlotData -- identity pass-through
* 0x4B8 UbaGetProtocolInterface -- lazy UBA protocol resolve
* 0x538 UbaDebugPrint -- CMOS-filtered debug print
* 0x5C0 UbaDebugAssert -- ASSERT via UBA protocol
* 0x600 GetHobList -- HOB list from config table
* 0x6D8 IsHobGuidMatch -- 64-bit GUID compare
* 0x748 ReadUnaligned64 -- unaligned read w/ NULL check
*
* GLOBAL VARIABLE MAP (.data section):
* 0xBB0 mSlotDataBuffer1 -- PSLT output buffer 1 (32 bytes)
* 0xBE0 mSlotDataBuffer2 -- PSLT output buffer 2 (40 bytes)
* 0xC08 gSystemTable -- EFI_SYSTEM_TABLE*
* 0xC10 gBootServices -- EFI_BOOT_SERVICES*
* 0xC18 gImageHandle -- EFI_HANDLE
* 0xC20 gRuntimeServices -- EFI_RUNTIME_SERVICES*
* 0xC28 mUbaDebugProtocol -- UBA protocol interface
* 0xC30 mHobList -- HOB list pointer
* 0xC38 mPlatformType -- cached platform type byte
*/
#include "SlotDataUpdateDxeLightningRidgeEXECB1.h"
// =============================================================================
// GUID Definitions (.data at 0xB60-0xBAF)
// =============================================================================
/**
* UBA DEBUG protocol GUID. Address: 0xB60.
* GUID: 36232936-0E76-31C8-A13A-3AF2FC1C3932
*
* Used by UbaGetProtocolInterface() to locate DebugPrint/DebugAssert services.
* This is a SEPARATE protocol from the UBA Config protocol (at 0xB70).
*/
STATIC EFI_GUID mUbaDebugProtocolGuid = UBA_DEBUG_PROTOCOL_GUID;
/**
* UBA CONFIG protocol GUID. Address: 0xB70.
* GUID: E03E0D46-5263-4845-B0A4-58D57B3177E2
*
* Used directly in _ModuleEntryPoint to locate the UBA configuration protocol
* which provides GetData for PSLT reads. This is SEPARATE from the debug
* protocol used by UbaGetProtocolInterface().
*/
STATIC EFI_GUID mUbaConfigProtocolGuid = UBA_CONFIG_PROTOCOL_GUID;
/**
* UBA Slot Data PSLT Entry 1 GUID. Address: 0xB90.
* GUID: B93613E1-48F0-4B32-B3A8-4FEDFC7C1365
*/
STATIC EFI_GUID mUbaSlotDataPsl1Guid = UBA_SLOT_DATA_PSLT1_GUID;
/**
* UBA Slot Config PSLT Entry 2 GUID. Address: 0xB80.
* GUID: 226763AE-972C-4E3C-80D1-73B25E8CBBA3
*/
STATIC EFI_GUID mUbaSlotConfigGuid = UBA_SLOT_CONFIG_GUID;
/**
* DXE Services Table GUID (gEfiDxeServicesTableGuid). Address: 0xBA0.
* GUID: 7739F24C-93D7-11D4-9A3A-0090273FC14D
*/
STATIC EFI_GUID mEfiDxeServicesTableGuid = DXE_SERVICES_TABLE_GUID;
// =============================================================================
// GUID Externs (alias of STATIC definitions for any external consumers)
// =============================================================================
/** @brief extern alias for mUbaDebugProtocolGuid */
EFI_GUID gUbaDebugProtocolGuid __attribute__((used)) = UBA_DEBUG_PROTOCOL_GUID;
/** @brief extern alias for mUbaConfigProtocolGuid */
EFI_GUID gUbaConfigProtocolGuid __attribute__((used)) = UBA_CONFIG_PROTOCOL_GUID;
/** @brief extern alias for mUbaSlotDataPsl1Guid */
EFI_GUID gUbaSlotDataPsl1Guid __attribute__((used)) = UBA_SLOT_DATA_PSLT1_GUID;
/** @brief extern alias for mUbaSlotConfigGuid */
EFI_GUID gUbaSlotConfigGuid __attribute__((used)) = UBA_SLOT_CONFIG_GUID;
/** @brief extern alias for mEfiDxeServicesTableGuid */
EFI_GUID gEfiDxeServicesTableGuid __attribute__((used)) = DXE_SERVICES_TABLE_GUID;
// =============================================================================
// Global Variables (.data at 0xC08-0xC28)
// =============================================================================
/** @brief Saved ImageHandle from entry point. Address: 0xC18. */
EFI_HANDLE gImageHandle = NULL;
/** @brief Saved SystemTable entry point. Address: 0xC08. */
EFI_SYSTEM_TABLE *gSystemTable = NULL;
/** @brief Saved BootServices (SystemTable->BootServices). Address: 0xC10. */
EFI_BOOT_SERVICES *gBootServices = NULL;
/** @brief Saved RuntimeServices (SystemTable->RuntimeServices). Address: 0xC20. */
EFI_RUNTIME_SERVICES *gRuntimeServices = NULL;
// =============================================================================
// Module-Level Static Variables (BSS region, zero-initialized)
// =============================================================================
/** @brief Cached UBA protocol interface. Address: 0xC28. Init: NULL. */
STATIC UBA_DEBUG_PROTOCOL_INTERFACE *mUbaDebugProtocol = NULL;
/** @brief Cached HOB list pointer. Address: 0xC30. Init: NULL. */
STATIC VOID *mHobList = NULL;
/** @brief Cached platform type byte from CMOS/hardware. Address: 0xC38. */
STATIC UINT8 mPlatformType = 0;
// =============================================================================
// PSLT Output Buffers (.data initialized data)
// =============================================================================
/**
* PSLT buffer 1 -- slot data output. Address: 0xBB0 (32 bytes).
*
* Template: Signature="PSLT", Version=1, Length=3024, StructSize=1200,
* NumberOfSlots=1.
* Runtime: OVERWRITTEN by UbaProtocol->GetData(gUbaSlotDataPsl1Guid, ...).
* After GetData, contains the live platform slot table.
*/
STATIC PSLT_HEADER mSlotDataBuffer1 = {
.Signature = 0x544C5350, /* 'PSLT' */
.Version = 1,
.Length = 3024,
.StructSize = 1200,
.NumberOfSlots = 1
};
/**
* PSLT buffer 2 -- slot config output. Address: 0xBE0 (40 bytes).
*
* Same PSLT header as above, plus 8 bytes extended config (initialized
* to 0x04B4 = StructSize + 4 in the template).
* Runtime: OVERWRITTEN by UbaProtocol->GetData(gUbaSlotConfigGuid, ...).
*/
STATIC SLOT_CONFIG mSlotDataBuffer2 = {
.Header = {
.Signature = 0x544C5350,
.Version = 1,
.Length = 3024,
.StructSize = 1200,
.NumberOfSlots = 1
},
.ConfigData = 0x04B4
};
// =============================================================================
// Debug Strings (.rdata section, read-only)
// =============================================================================
STATIC CONST CHAR8 mAssertEfiErrorFormat[] = "\nASSERT_EFI_ERROR (Status = %r)\n"; /* 0x780 */
STATIC CONST CHAR8 mAssertExprStr[] = "!EFI_ERROR (Status)"; /* 0x7A8 */
STATIC CONST CHAR8 mDebugIdentStr[] = "UBA:SlotDataUpdate-TypeLightningRidgeEXECB1\n"; /* 0x7C0 */
STATIC CONST CHAR8 mAssertImageHandleStr[] = "gImageHandle != ((void *) 0)"; /* 0x7F0 */
STATIC CONST CHAR8 mBootServicesLibPath[] = /* 0x810 */
"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c";
STATIC CONST CHAR8 mAssertSystemTableStr[] = "gST != ((void *) 0)"; /* 0x860 */
STATIC CONST CHAR8 mAssertBootServicesStr[] = "gBS != ((void *) 0)"; /* 0x878 */
STATIC CONST CHAR8 mAssertRuntimeServicesStr[] = "gRT != ((void *) 0)"; /* 0x890 */
STATIC CONST CHAR8 mRuntimeServicesLibPath[] = /* 0x8B0 */
"e:\\hs\\MdePkg\\Library\\UefiRuntimeServicesTableLib\\UefiRuntimeServicesTableLib.c";
STATIC CONST CHAR8 mAssertBufferStr[] = "Buffer != ((void *) 0)"; /* 0x900 */
STATIC CONST CHAR8 mHobLibPath[] = /* 0x918 */
"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c";
STATIC CONST CHAR8 mAssertHobListStr[] = "mHobList != ((void *) 0)"; /* 0x940 */
STATIC CONST CHAR8 mUnalignedPath[] = /* 0x960 */
"e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c";
// =============================================================================
// GetSlotCount (0x4B0)
// =============================================================================
/**
* Returns the platform-specific PCIe slot count.
*
* LightningRidge EXEC B1 has 2 PCIe slots. This constant is consumed by
* the UBA PSLT framework for slot enumeration and SMBIOS slot type
* reporting.
*
* @return UINT8 Always 2 (number of PCIe slots on this platform).
*/
UINT8
EFIAPI
GetSlotCount (
VOID
)
{
return 2;
}
// =============================================================================
// GetSlotData (0x4B4)
// =============================================================================
/**
* Identity pass-through for slot data retrieval.
*
* Returns the DefaultData pointer unchanged. On EXEC B1, slot data is
* populated by UbaProtocol->GetData directly into mSlotDataBuffer1.
* No per-slot callback customization is needed.
*
* @param[in] Slot Slot index (0-based, unused).
* @param[in] DefaultData Pointer to default slot data.
* @return VOID* The unmodified DefaultData pointer.
*/
VOID *
EFIAPI
GetSlotData (
IN UINTN Slot,
IN VOID *DefaultData
)
{
(VOID)Slot;
return DefaultData;
}
// =============================================================================
// UbaGetProtocolInterface (0x4B8)
// =============================================================================
/**
* Lazily resolves and caches the UBA DEBUG protocol interface.
*
* This is a TPL-safe LocateProtocol wrapper for the UBA Debug protocol
* (GUID at 0xB60 = 36232936-0E76-31C8-A13A-3AF2FC1C3932):
* 1. Returns cached mUbaDebugProtocol immediately if non-NULL.
* 2. Raises TPL to TPL_HIGH_LEVEL (31) via gBS->RaiseTPL (at +0x18).
* 3. Restores previous TPL via gBS->RestoreTPL (at +0x20).
* 4. If previous TPL <= TPL_NOTIFY (0x10), calls
* gBS->LocateProtocol(&mUbaDebugProtocolGuid, NULL, &mUbaDebugProtocol).
* 5. If LocateProtocol fails, resets mUbaDebugProtocol to NULL.
*
* The TPL raise/restore validates we are at or below TPL_NOTIFY, which
* is a precondition for calling LocateProtocol as it may acquire event
* locks (only safe at <= TPL_NOTIFY).
*
* The resolved debug protocol interface provides:
* +0x00: DebugPrint (UINT64 Severity, CHAR8 *Format, UINT64 *VaList)
* +0x08: DebugAssert (CHAR8 *File, UINTN Line, CHAR8 *Expression)
* +0x10: Reserved (may be stub or null for this protocol)
*
* NOTE: This Debug protocol is SEPARATE from the UBA CONFIG protocol
* used directly in _ModuleEntryPoint (GUID at 0xB70 = E03E0D46-...).
*
* @return UBA_DEBUG_PROTOCOL_INTERFACE* Cached debug protocol, or NULL.
*/
UBA_DEBUG_PROTOCOL_INTERFACE *
EFIAPI
UbaGetProtocolInterface (
VOID
)
{
UBA_DEBUG_PROTOCOL_INTERFACE *Protocol;
EFI_TPL OldTpl;
Protocol = mUbaDebugProtocol;
if (Protocol != NULL) {
return Protocol;
}
//
// Raise to TPL_HIGH_LEVEL, then restore to sample current TPL level.
// LocateProtocol can only be called safely at TPL_NOTIFY or below.
//
OldTpl = gBootServices->RaiseTPL (TPL_HIGH_LEVEL);
gBootServices->RestoreTPL (OldTpl);
if (OldTpl <= TPL_NOTIFY) {
EFI_STATUS Status;
Status = gBootServices->LocateProtocol (
&mUbaDebugProtocolGuid,
NULL, // Registration key not used
(VOID **)&Protocol
);
if (!EFI_ERROR (Status)) {
mUbaDebugProtocol = Protocol;
} else {
mUbaDebugProtocol = NULL;
Protocol = NULL;
}
}
return Protocol;
}
// =============================================================================
// UbaDebugPrint (0x538)
// =============================================================================
/**
* Debug output routed through the UBA protocol, filtered by CMOS register
* 0x4B verbosity level and platform type.
*
* Algorithm:
* 1. Get UBA protocol via UbaGetProtocolInterface(); return if NULL.
* 2. Read CMOS[0x4B] via I/O ports 0x70/0x71 (preserving NMI bit 7).
* 3. Determine type/mask:
*
* CMOS[0x4B] <= 3: Direct verbosity level (0=no output, 1=DE|DI,
* 2+=DE|DV).
* CMOS[0x4B] > 3: Platform type. Check cached mPlatformType.
* If 0 (first access), derive from hardware strap
* at MMIO 0xFDAF0490:
* type = (MmioRead8(0xFDAF0490) & 2) | 1
* Cached type then used: all >= 1 get DE|DV mask.
*
* 4. If (DerivedMask & CallerDebugLevel) != 0, call protocol DebugPrint.
*
* @param[in] DebugLevel Severity mask (e.g., 0x8000000000000001 for ERROR).
* @param[in] Format Print format string.
* @param[in] ... Variable arguments for the format string.
*/
VOID
EFIAPI
UbaDebugPrint (
IN UINT64 DebugLevel,
IN CONST CHAR8 *Format,
...
)
{
UBA_DEBUG_PROTOCOL_INTERFACE *Protocol;
UINT64 DebugMask;
UINT8 CmosData;
UINT8 NmiSave;
UINT8 PlatformType;
VA_LIST VaList;
Protocol = UbaGetProtocolInterface ();
if (Protocol == NULL) {
return;
}
//
// Read CMOS register 0x4B.
// Preserve the NMI enable bit (bit 7) through the index write.
//
NmiSave = IoRead8 (CMOS_INDEX_PORT);
IoWrite8 (CMOS_INDEX_PORT, (NmiSave & BIT7) | CMOS_PLATFORM_TYPE_REG);
CmosData = IoRead8 (CMOS_DATA_PORT);
//
// Translate CMOS value into platform type for debug mask selection.
//
if (CmosData > 3) {
//
// Values > 3 are platform type indicators. Use cached type, or
// derive from hardware strap if first access.
//
PlatformType = mPlatformType;
if (PlatformType == 0) {
//
// Read hardware strap register from PCH MMIO.
// Bit 1 indicates platform variant; OR with 1 ensures non-zero.
//
PlatformType = (MmioRead8 (PLATFORM_STRAP_MMIO_ADDR) & 0x02) | 0x01;
mPlatformType = PlatformType;
}
} else {
//
// Values 0-3 are direct verbosity levels.
//
PlatformType = CmosData;
}
//
// Map platform type to debug severity mask.
// Type >= 1 produces either DE|DI (type 1) or DE|DV (type 2+).
// Type 0 suppresses all output.
//
if (PlatformType >= 1) {
if (PlatformType == 1) {
DebugMask = DEBUG_INFO_MASK; // 0x80000004: DebugError | DebugInfo
} else {
DebugMask = DEBUG_VERBOSE_MASK; // 0x80000006: DebugError | DebugVerbose
}
} else {
DebugMask = 0;
}
//
// Forward to protocol DebugPrint if severity matches.
//
if ((DebugMask & DebugLevel) != 0) {
VA_START (VaList, Format);
Protocol->DebugPrint (DebugLevel, (CHAR8 *)Format, (UINT64 *)&VaList);
VA_END (VaList);
}
}
// =============================================================================
// UbaDebugAssert (0x5C0)
// =============================================================================
/**
* ASSERT failure handler via the UBA protocol.
*
* Locates the UBA protocol and calls its DebugAssert function (at +0x08)
* with the file name, line number, and assertion expression. Returns
* silently if the UBA protocol is not available.
*
* @param[in] FileName Source file path where the assertion failed.
* @param[in] LineNumber Line number of the failed assertion.
* @param[in] Expression The assertion expression string.
*/
VOID
EFIAPI
UbaDebugAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Expression
)
{
UBA_DEBUG_PROTOCOL_INTERFACE *Protocol;
Protocol = UbaGetProtocolInterface ();
if (Protocol != NULL) {
Protocol->DebugAssert (
(CHAR8 *)FileName,
LineNumber,
(CHAR8 *)Expression
);
}
}
// =============================================================================
// GetHobList (0x600)
// =============================================================================
/**
* Locates and caches the HOB list from SystemTable->ConfigurationTable.
*
* Walks the EFI Configuration Table array comparing each entry's
* VendorGuid against gEfiDxeServicesTableGuid
* ({7739F24C-93D7-11D4-9A3A-0090273FC14D}). The comparison uses
* IsHobGuidMatch which reads GUIDs as two 64-bit unaligned values.
*
* On match, caches the VendorTable pointer (the HOB list) in mHobList.
* If no match or table empty:
* - Prints ASSERT_EFI_ERROR via UbaDebugPrint with EFI_NOT_FOUND.
* - Fires DebugAssert at HobLib.c:54 and :55.
*
* @return VOID* The HOB list pointer, or NULL if not found.
*/
VOID *
EFIAPI
GetHobList (
VOID
)
{
UINTN Index;
EFI_CONFIGURATION_TABLE *ConfigTable;
UINTN TableEntryCount;
if (mHobList != NULL) {
return mHobList;
}
ConfigTable = gSystemTable->ConfigurationTable;
TableEntryCount = gSystemTable->NumberOfTableEntries;
mHobList = NULL;
if (ConfigTable != NULL) {
for (Index = 0; Index < TableEntryCount; Index++) {
if (IsHobGuidMatch (
&mEfiDxeServicesTableGuid,
&ConfigTable[Index].VendorGuid
))
{
mHobList = ConfigTable[Index].VendorTable;
break;
}
}
}
//
// If HOB list not found, assert with EFI_NOT_FOUND.
//
if (mHobList == NULL) {
UbaDebugPrint (
DEBUG_ERROR,
mAssertEfiErrorFormat,
(UINT64)EFI_NOT_FOUND
);
UbaDebugAssert (
mHobLibPath,
54,
mAssertExprStr
);
}
if (mHobList == NULL) {
UbaDebugAssert (
mHobLibPath,
55,
mAssertHobListStr
);
}
return mHobList;
}
// =============================================================================
// IsHobGuidMatch (0x6D8)
// =============================================================================
/**
* Compares two EFI_GUID values as two 64-bit unsigned integer pairs.
*
* Reads bytes 0-7 and 8-15 of each GUID via ReadUnaligned64() and
* compares both halves. This matches the standard EDK2 GUID comparison
* pattern and avoids unaligned access faults on strict-alignment CPUs.
*
* @param[in] Guid1 Pointer to first EFI_GUID.
* @param[in] Guid2 Pointer to second EFI_GUID.
* @return BOOLEAN TRUE if both 64-bit halves match, FALSE otherwise.
*/
BOOLEAN
EFIAPI
IsHobGuidMatch (
IN EFI_GUID *Guid1,
IN EFI_GUID *Guid2
)
{
UINT64 Value1A, Value1B;
UINT64 Value2A, Value2B;
Value1A = ReadUnaligned64 ((CONST UINT64 *)Guid1);
Value1B = ReadUnaligned64 ((CONST UINT64 *)((UINT8 *)Guid1 + 8));
Value2A = ReadUnaligned64 ((CONST UINT64 *)Guid2);
Value2B = ReadUnaligned64 ((CONST UINT64 *)((UINT8 *)Guid2 + 8));
return (BOOLEAN)(Value1A == Value2A && Value1B == Value2B);
}
// =============================================================================
// ReadUnaligned64 (0x748)
// =============================================================================
/**
* Reads a UINT64 from a potentially unaligned address with NULL
* pointer assertion.
*
* Validates Buffer != NULL via UbaDebugAssert, then performs a direct
* 64-bit read. On x64 the CPU natively handles unaligned loads; on
* strict-alignment architectures the compiler may emit byte-by-byte
* loads for this dereference.
*
* @param[in] Buffer Pointer to UINT64 (must not be NULL).
* @return UINT64 The value read from Buffer.
*/
UINT64
EFIAPI
ReadUnaligned64 (
IN CONST UINT64 *Buffer
)
{
if (Buffer == NULL) {
UbaDebugAssert (
mUnalignedPath,
192,
mAssertBufferStr
);
}
return *Buffer;
}
// =============================================================================
// _ModuleEntryPoint (0x390)
// =============================================================================
/**
* UEFI DXE driver entry point.
*
* Called by the DXE Core dispatcher. Performs initialization in six
* sequential phases:
*
* Phase 1 - Cache globals:
* Saves ImageHandle, SystemTable, BootServices, RuntimeServices.
* Each pointer is NULL-asserted via UbaDebugAssert against its
* respective library file path.
*
* Phase 2 - HOB list init:
* Calls GetHobList() to find the HOB list from the configuration
* table. Required before any HOB-based data access.
*
* Phase 3 - Debug identification:
* Logs "UBA:SlotDataUpdate-TypeLightningRidgeEXECB1\n" if debug
* output is enabled by CMOS[0x4B] configuration.
*
* Phase 4 - Locate UBA protocol:
* gBS->LocateProtocol(&mUbaDebugProtocolGuid, NULL, &UbaProtocol).
* Returns EFI_NOT_FOUND if no UBA protocol is installed.
*
* Phase 5 - Get PSLT entry 1 (slot data):
* UbaProtocol->GetData(This, &mUbaSlotDataPsl1Guid,
* &mSlotDataBuffer1, sizeof(PSLT_HEADER)).
* Populates mSlotDataBuffer1 with platform PSLT data.
*
* Phase 6 - Get PSLT entry 2 (slot config):
* UbaProtocol->GetData(This, &mUbaSlotConfigGuid,
* &mSlotDataBuffer2, sizeof(SLOT_CONFIG)).
* Populates mSlotDataBuffer2 with extended slot config.
*
* Each GetData failure returns immediately with the error status --
* phase 6 is only reached if phase 5 succeeded.
*
* @param[in] ImageHandle Firmware-allocated handle for this image.
* @param[in] SystemTable Pointer to the EFI System Table.
* @return EFI_STATUS EFI_SUCCESS on success, or error from
* LocateProtocol or either GetData call.
*/
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UBA_CONFIG_PROTOCOL_INTERFACE *UbaProtocol;
// ---------------------------------------------------------------------
// Phase 1: Cache and validate global service table pointers.
// ---------------------------------------------------------------------
gImageHandle = ImageHandle;
if (ImageHandle == NULL) {
UbaDebugAssert (mBootServicesLibPath, 51, mAssertImageHandleStr);
}
gSystemTable = SystemTable;
if (SystemTable == NULL) {
UbaDebugAssert (mBootServicesLibPath, 57, mAssertSystemTableStr);
}
gBootServices = SystemTable->BootServices;
if (gBootServices == NULL) {
UbaDebugAssert (mBootServicesLibPath, 63, mAssertBootServicesStr);
}
gRuntimeServices = SystemTable->RuntimeServices;
if (gRuntimeServices == NULL) {
//
// NOTE: RT check uses UefiRuntimeServicesTableLib.c line 47,
// while the other three use UefiBootServicesTableLib.c.
// This reflects the different library each global comes from.
//
UbaDebugAssert (mRuntimeServicesLibPath, 47, mAssertRuntimeServicesStr);
}
// ---------------------------------------------------------------------
// Phase 2: Initialize HOB list from configuration table.
// ---------------------------------------------------------------------
GetHobList ();
// ---------------------------------------------------------------------
// Phase 3: Emit driver identification into debug output.
// ---------------------------------------------------------------------
UbaDebugPrint (DEBUG_ERROR, mDebugIdentStr);
// ---------------------------------------------------------------------
// Phase 4: Locate the UBA CONFIG protocol interface.
// This uses the PROTOCOL GUID AT 0xB70 (E03E0D46-...),
// which is SEPARATE from the DEBUG protocol at 0xB60
// used by UbaGetProtocolInterface/DebugPrint/DebugAssert.
//
// The config protocol provides GetData at vtable +0x10,
// which reads PSLT entries from the UBA configuration store.
// ---------------------------------------------------------------------
UbaProtocol = NULL;
Status = gBootServices->LocateProtocol (
&mUbaConfigProtocolGuid,
NULL, // No registration key
(VOID **)&UbaProtocol
);
if (EFI_ERROR (Status)) {
return Status;
}
// ---------------------------------------------------------------------
// Phase 5: Read PSLT entry 1 (slot data) from UBA configuration.
// ---------------------------------------------------------------------
Status = UbaProtocol->GetData (
UbaProtocol,
&mUbaSlotDataPsl1Guid,
&mSlotDataBuffer1,
sizeof (mSlotDataBuffer1) // 32 bytes = PSLT_HEADER
);
if (EFI_ERROR (Status)) {
return Status;
}
// ---------------------------------------------------------------------
// Phase 6: Read PSLT entry 2 (slot config) from UBA configuration.
// ---------------------------------------------------------------------
Status = UbaProtocol->GetData (
UbaProtocol,
&mUbaSlotConfigGuid,
&mSlotDataBuffer2,
sizeof (mSlotDataBuffer2) // 40 bytes = SLOT_CONFIG
);
return Status;
}