/** @file
SlotDataUpdateDxeLightningRidgeEXECB2 - Platform Slot Table (PSLT) update driver
for LightningRidge EXEC B2 platforms.
This driver is part of the Lenovo UBA (Universal BIOS Architecture) framework.
It provides platform-specific PCIe slot configuration data for the LightningRidge
EXEC B2 platform by registering PSLT entries through the UBA protocol.
Build source path: PurleyRpPkg/Uba/UbaMain/Dxe/TypeLightningRidgeEXECB2/
SlotDataUpdateDxe/SlotDataUpdateDxe/
PDB: SlotDataUpdateDxeLightningRidgeEXECB2.pdb
Build: VS2015, DEBUG, X64
Image size: 0xD00 (3328 bytes)
Entry point: 0x390 (_ModuleEntryPoint)
Copyright (C) 2026, Lenovo. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B2_H
#define SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B2_H
#include "../uefi_headers/Uefi.h"
// =============================================================================
// GUID Definitions
// =============================================================================
/**
UBA Protocol GUID.
GUID: 36232936-0E76-31C8-A13A-3AF2FC1C3932
This is the UBA protocol identification GUID for the LightningRidge EXEC B2
platform. It is located via gBS->LocateProtocol() to obtain the UBA protocol
interface, which provides three services:
+0x00: DebugPrint (debug message output)
+0x08: DebugAssert (assertion handler)
+0x10: Register (SetData - register config data by GUID)
This GUID is shared across all LightningRidge EXEC variants (B1, B2, B3, B4).
The NeonCity FPGA variant uses a different GUID
(76232936-C80E-A131-3A3A-F2FC1C3932).
**/
#define UBA_PROTOCOL_GUID \
{ 0x36232936, 0x0E76, 0x31C8, \
{ 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }
/** Pointer to UBA_PROTOCOL_GUID as EFI_GUID */
extern EFI_GUID gUbaProtocolGuid;
/**
UBA Slot Data PSLT Entry 1 GUID.
GUID: B93613E1-48F0-4B32-B3A8-4FEDFC7C1365
Used with UbaProtocol->Register (at v4+0x10) to register the first PSLT
(Platform Slot Table) entry for the EXEC B2 platform. The data is 32 bytes
sourced from gSlotDataBuffer1 (at 0xBC0).
**/
#define UBA_SLOT_DATA_PSLT1_GUID \
{ 0xB93613E1, 0x48F0, 0x4B32, \
{ 0xB3, 0xA8, 0x4F, 0xED, 0xFC, 0x7C, 0x13, 0x65 } }
extern EFI_GUID gUbaSlotDataPsl1Guid;
/**
UBA Slot Data PSLT Entry 2 GUID.
GUID: 226763AE-972C-4E3C-80D1-73B25E8CBBA3
Used with UbaProtocol->Register (at v4+0x10) to register the second PSLT
entry for the EXEC B2 platform. The data is 40 bytes sourced from
gSlotDataBuffer2 (at 0xBE0).
**/
#define UBA_SLOT_CONFIG_GUID \
{ 0x226763AE, 0x972C, 0x4E3C, \
{ 0x80, 0xD1, 0x73, 0xB2, 0x5E, 0x8C, 0xBB, 0xA3 } }
extern EFI_GUID gUbaSlotConfigGuid;
/**
DXE Services Table GUID (gEfiDxeServicesTableGuid).
GUID: 7739F24C-93D7-11D4-9A3A-0090273FC14D
Standard UEFI GUID used to locate the HOB (Hand-Off Block) list from the
EFI System Table's ConfigurationTable. The driver scans the config table for
this GUID to find the HOB list pointer, which is used for HOB-based data
access (GetHobList function at 0x600).
**/
#define DXE_SERVICES_TABLE_GUID \
{ 0x7739F24C, 0x93D7, 0x11D4, \
{ 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
extern EFI_GUID gEfiDxeServicesTableGuid;
// =============================================================================
// Data Structure Definitions
// =============================================================================
/**
PSLT_HEADER - Platform Slot Table Header.
This structure defines the layout of a PSLT entry that gets registered with
the UBA protocol. The template instances are stored in the .data section at:
gSlotDataBuffer1 (0xBC0, 32 bytes): Primary PSLT entry
gSlotDataBuffer2 (0xBE0, 40 bytes): Secondary PSLT entry (with extended config)
The PSLT format embeds function pointers:
- SlotCount offset refers to GetSlotCount (sub_4B0 at 0x4B0, returns 2)
- SlotDataOffset refers to GetSlotData (sub_4B4 at 0x4B4, identity passthrough)
**/
#pragma pack(push, 1)
typedef struct {
UINT32 Signature; ///< "PSLT" (0x544C5350) - Platform Slot Table signature
UINT32 Version; ///< Format version (1 for current generation)
UINT32 TotalDataSize; ///< Total slot table data size in bytes (0xBB0 = 2992 for B2)
UINT32 SlotCountFunc; ///< RVA of GetSlotCount function (0x4B0 for B2)
UINT32 Reserved; ///< Reserved / padding (0)
UINT32 SlotDataFunc; ///< RVA of GetSlotData function (0x4B4 for B2)
UINT8 ConfigData[8]; ///< Platform-specific slot configuration flags
} PSLT_HEADER;
/**
SLOT_CONFIG - Extended slot configuration structure (40 bytes).
Used for the second Register call (GUID: 226763AE-972C-4E3C-...).
Extends PSLT_HEADER with an additional function pointer slot for
platform-specific customization.
**/
typedef struct {
PSLT_HEADER Header; ///< PSLT header (32 bytes)
UINT64 ExtraConfig; ///< Extended platform config data (RVA to sub_4B4 at 0x4B4)
} SLOT_CONFIG;
#pragma pack(pop)
/** Check that PSLT_HEADER matches expected size. */
STATIC_ASSERT (sizeof (PSLT_HEADER) == 32, "PSLT_HEADER must be 32 bytes");
STATIC_ASSERT (sizeof (SLOT_CONFIG) == 40, "SLOT_CONFIG must be 40 bytes");
// =============================================================================
// UBA Protocol Interface
// =============================================================================
/**
UBA protocol interface structure.
The UBA protocol is located via LocateProtocol (gUbaProtocolGuid) and provides:
+0x00: DebugPrint (DebugLib print service)
+0x08: DebugAssert (Assert handler)
+0x10: Register (SetData - register config by GUID + Data + Size)
For the EXEC B2 platform (as opposed to EXEC B1 which reads via GetData,
and NeonCity FPGA which also registers via GetData+SetData), the protocol
function at +0x10 is used to REGISTER (push) platform slot data into the
UBA framework, rather than to read (pull) from it.
**/
typedef struct {
//
// +0x00: DebugPrint
// VOID (*)(UINTN DebugLevel, CONST CHAR8 *Format, VA_LIST Va)
//
UINT64 DebugPrint;
//
// +0x08: DebugAssert
// VOID (*)(UINT64 FileName, UINTN LineNumber, UINT64 Expression)
//
UINT64 DebugAssert;
//
// +0x10: Register (SetData)
// EFI_STATUS (*)(UBA_PROTOCOL *This, EFI_GUID *Guid, VOID *Data, UINTN Size)
//
UINT64 RegisterFunc;
} UBA_PROTOCOL;
/**
Type definition for the UBA protocol Register function.
@param[in] Uba Pointer to the UBA protocol interface.
@param[in] Guid GUID identifying the configuration data.
@param[in] Data Pointer to the configuration data buffer.
@param[in] Size Size of the configuration data buffer.
@return EFI_STATUS from the registration operation.
**/
typedef
EFI_STATUS
(EFIAPI *UBA_REGISTER) (
IN UBA_PROTOCOL *Uba,
IN EFI_GUID *Guid,
IN VOID *Data,
IN UINTN Size
);
/**
Type definition for UBA DebugPrint function.
@param[in] DebugLevel Debug message severity (mask).
@param[in] Format Print format string.
@param[in] Va Variable argument list.
**/
typedef
VOID
(EFIAPI *UBA_DEBUG_PRINT) (
IN UINTN DebugLevel,
IN CONST CHAR8 *Format,
IN UINT64 *Va
);
/**
Type definition for UBA DebugAssert function.
@param[in] FileName Source file name (as UINT64 pointer).
@param[in] LineNumber Line number of the assertion.
@param[in] Description Assertion expression string (as UINT64 pointer).
**/
typedef
VOID
(EFIAPI *UBA_DEBUG_ASSERT) (
IN UINT64 FileName,
IN UINTN LineNumber,
IN UINT64 Description
);
// =============================================================================
// Global Variables (declared in .c)
// =============================================================================
/** Saved ImageHandle from entry point parameter. Initialized at 0xC18. */
extern EFI_HANDLE gImageHandle;
/** Saved SystemTable pointer from entry point parameter. Initialized at 0xC08. */
extern EFI_SYSTEM_TABLE *gSystemTable;
/** Saved BootServices pointer (SystemTable->BootServices). Initialized at 0xC10. */
extern EFI_BOOT_SERVICES *gBootServices;
/** Saved RuntimeServices pointer (SystemTable->RuntimeServices). Initialized at 0xC20. */
extern EFI_RUNTIME_SERVICES *gRuntimeServices;
/** Cached UBA protocol interface pointer (lazy-initialized by UbaGetProtocolInterface). Initialized at 0xC28. */
extern VOID *gUbaProtocol;
/** Cached HOB list pointer (initialized by GetHobList from config table). Initialized at 0xC30. */
extern VOID *gHobList;
/** Cached platform type from CMOS[0x4B] (read by UbaDebugPrint). Initialized at 0xC38. */
extern UINT8 gPlatformType;
/**
Slot data buffer 1 - PSLT entry template (32 bytes at 0xBC0).
Contains a PSLT entry with:
- Signature "PSLT"
- Version 1
- TotalDataSize 0xBB0 (2992 bytes)
- SlotCountFunc RVA 0x4B0 (GetSlotCount)
- SlotDataFunc RVA 0x4B4 (GetSlotData)
- ConfigData all zeros
- NumberOfSlots = 1
Registered with UBA via gUbaSlotDataPsl1Guid.
**/
extern PSLT_HEADER gSlotDataBuffer1;
/**
Slot data buffer 2 - Extended PSLT entry template (40 bytes at 0xBE0).
Contains a PSLT_HEADER plus an extra 8 bytes:
- PSLT header (32 bytes, same format as buffer 1)
- ExtraConfig: RVA 0x4B4 (extended callback to GetSlotData)
Registered with UBA via gUbaSlotConfigGuid.
**/
extern SLOT_CONFIG gSlotDataBuffer2;
// =============================================================================
// Function Declarations
// =============================================================================
/**
UEFI DXE driver entry point.
Called by the DXE Core during driver dispatch. Performs the following:
1. Caches ImageHandle, SystemTable, BootServices, and RuntimeServices
globals (with NULL-assert checks via UbaDebugAssert).
2. Calls GetHobList() to locate the HOB list from configuration table.
3. Calls UbaDebugPrint to log "UBA:SlotDataUpdate-TypeLightningRidgeEXECB2".
4. Locates the UBA protocol via gBS->LocateProtocol().
5. Registers PSLT entry 1 via UbaProtocol->Register(gUbaSlotDataPsl1Guid,
gSlotDataBuffer1, 32).
6. Registers PSLT entry 2 via UbaProtocol->Register(gUbaSlotConfigGuid,
gSlotDataBuffer2, 40).
@param[in] ImageHandle The firmware-allocated handle for this driver image.
@param[in] SystemTable A pointer to the EFI System Table.
@return EFI_STATUS EFI_SUCCESS on success, or error from LocateProtocol/Register.
**/
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Returns the supported slot count for this platform.
Always returns 2 for LightningRidge EXEC B2.
This function is referenced by the UBA framework at RVA 0x4B0.
@return UINT8 2 (number of PCIe slots for this platform).
**/
UINT8
EFIAPI
GetSlotCount (
VOID
);
/**
Platform slot data identity pass-through.
Returns its second argument (DefaultData) unchanged. This function is the
GetSlotData callback at RVA 0x4B4 and allows platform-specific slot data
customization, though for EXEC B2 no customization is needed beyond the
template PSLT data registered with the UBA protocol.
@param[in] Slot Slot index (unused in B2).
@param[in] DefaultData Default slot data to pass through.
@return VOID* The unmodified DefaultData pointer.
**/
VOID *
EFIAPI
GetSlotData (
IN UINTN Slot,
IN VOID *DefaultData
);
/**
Lazily resolves and caches the UBA protocol interface.
Checks the cache at gUbaProtocol first. If not yet resolved, allocates a
test buffer of 31 bytes (EfiBootServicesData pool type) and frees it to
verify pool is operational. Then calls gBS->LocateProtocol to find the
UBA protocol interface by gUbaProtocolGuid.
The located protocol interface is cached in gUbaProtocol (at 0xC28).
@return UBA_PROTOCOL* The cached UBA protocol interface, or NULL if not
found or pool allocation fails.
**/
UBA_PROTOCOL *
EFIAPI
UbaGetProtocolInterface (
VOID
);
/**
UBA-aware debug print with CMOS platform-type filtering.
Reads CMOS register 0x4B via I/O ports 0x70/0x71 to determine the platform
debug verbosity level:
- CMOS[0x4B] > 3: Use as-is for routing
- CMOS[0x4B] == 0: Read hardware strap from 0xFDAF0490 bit 1 | 1
- CMOS[0x4B] == 1: DebugRoute = 0x80000004 (EFI_D_INFO)
- CMOS[0x4B] >= 2: DebugRoute = 0x80000006 (EFI_D_VERBOSE)
If the severity mask from the caller matches the DebugRoute (bitwise AND),
the message is forwarded to the UBA protocol's DebugPrint function at +0x00.
@param[in] Severity Debug message severity mask (e.g., 0x80000000 for ERROR).
@param[in] Format Print format string.
@param[in] ... Variable arguments for the format string.
**/
VOID
EFIAPI
UbaDebugPrint (
IN UINT64 Severity,
IN CONST CHAR8 *Format,
...
);
/**
UBA-aware ASSERT failure handler.
Called when a DEBUG condition fails. Locates the UBA protocol and calls
its DebugAssert function (at +0x08) with the file name, line number, and
assertion expression.
@param[in] FileName Source file name 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
);
/**
Locates and caches the HOB list from the EFI System Table configuration table.
Scans SystemTable->ConfigurationTable for an entry matching
gEfiDxeServicesTableGuid ({7739F24C-93D7-11D4-9A3A-0090273FC14D}).
The GUID comparison uses IsHobGuidMatch for unaligned-safe comparison of
64-bit halves.
If the GUID is found, caches the associated pointer in gHobList and returns
it. If not found, triggers a debug assert via UbaDebugAssert and
UbaDebugPrint.
Result is cached in gHobList (at 0xC30) so subsequent calls return immediately.
@return VOID* Pointer to the HOB list, or NULL if not found.
**/
VOID *
EFIAPI
GetHobList (
VOID
);
/**
Compares two EFI_GUID values via unaligned 64-bit reads.
Reads both halves (first 8 bytes and last 8 bytes) of each GUID using
ReadUnaligned64 and compares them. This avoids unaligned access faults
on strict-alignment architectures.
@param[in] Guid1 Pointer to first EFI_GUID.
@param[in] Guid2 Pointer to second EFI_GUID.
@return BOOLEAN TRUE if both halves match, FALSE otherwise.
**/
BOOLEAN
EFIAPI
IsHobGuidMatch (
IN EFI_GUID *Guid1,
IN EFI_GUID *Guid2
);
/**
Reads a UINT64 from a potentially unaligned address with NULL check.
Asserts via UbaDebugAssert if Buffer is NULL, then performs a 64-bit read
from the given address. The function does not handle misalignment specially;
it trusts the target CPU architecture to support unaligned reads.
@param[in] Buffer Pointer to the UINT64 to read (must not be NULL).
@return UINT64 The 64-bit value at Buffer.
**/
UINT64
EFIAPI
ReadUnaligned64 (
IN CONST UINT64 *Buffer
);
#endif // SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B2_H