/**
* @file SlotDataUpdateDxeLightningRidgeEXECB1.h
*
* @brief UEFI DXE driver header for LightningRidge EXEC B1 slot data update.
*
* This driver is part of the AMI UBA (Universal BIOS Architecture) framework.
* It locates the UBA_CONFIG protocol specific to the LightningRidge EXEC B1
* platform and reads PSLT (Platform Slot Table) configuration data via the
* protocol's GetData interface. The data defines PCIe slot layout for the
* platform and is consumed by slot initialization and SMBIOS slot type
* reporting subsystems.
*
* Build source path: PurleyRpPkg/Uba/UbaMain/Dxe/TypeLightningRidgeEXECB1/
* SlotDataUpdateDxe/SlotDataUpdateDxe/
* PDB: SlotDataUpdateDxeLightningRidgeEXECB1.pdb
* Build: VS2015, DEBUG, X64
*/
#ifndef SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B1_H
#define SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B1_H
#include "../uefi_headers/Uefi.h"
// =============================================================================
// Platform Constants
// =============================================================================
/** CMOS I/O port for selecting CMOS register index. */
#define CMOS_INDEX_PORT 0x70
/** CMOS I/O port for reading/writing CMOS register data. */
#define CMOS_DATA_PORT 0x71
/** CMOS register index for platform type / debug verbosity. */
#define CMOS_PLATFORM_TYPE_REG 0x4B
/** MMIO address for hardware platform strap in PCH. */
#define PLATFORM_STRAP_MMIO_ADDR 0xFDAF0490
// =============================================================================
// Debug Level Masks (UEFI standard)
// =============================================================================
/** Debug error severity. Always enabled by this module's mask logic. */
#define DEBUG_ERROR ((UINT64)0x8000000000000001)
/** Debug info severity. */
#define DEBUG_INFO_MASK ((UINT64)0x80000004)
/** Debug verbose severity. */
#define DEBUG_VERBOSE_MASK ((UINT64)0x80000006)
// =============================================================================
// Function Pointer Type Declarations for UBA Protocol vtable
// =============================================================================
/**
* DebugPrint function type as implemented by the UBA protocol (vtable +0x00).
*
* @param[in] Severity Debug level mask.
* @param[in] Format Format string.
* @param[in] VaList Pointer to variable argument list (UINT64*).
*/
typedef
VOID
(EFIAPI *DEBUG_PRINT_FUNC)(
UINT64 Severity,
CHAR8 *Format,
UINT64 *VaList
);
/**
* DebugAssert function type as implemented by the UBA protocol (vtable +0x08).
*
* @param[in] FileName Source file name.
* @param[in] LineNumber Line number.
* @param[in] Expression Assertion expression.
*/
typedef
VOID
(EFIAPI *DEBUG_ASSERT_FUNC)(
CHAR8 *FileName,
UINTN LineNumber,
CHAR8 *Expression
);
/**
* GetData function type as implemented by the UBA protocol (vtable +0x10).
*
* @param[in] This The UBA protocol interface.
* @param[in] Guid GUID identifying the data to retrieve.
* @param[out] Data Output buffer.
* @param[in] DataSize Size of the output buffer.
* @return EFI_STATUS EFI_SUCCESS on success, error code otherwise.
*/
typedef
EFI_STATUS
(EFIAPI *UBA_GET_DATA_FUNC)(
VOID *This,
EFI_GUID *Guid,
VOID *Data,
UINTN DataSize
);
// =============================================================================
// GUID Definitions
// =============================================================================
/**
* UBA Debug Protocol GUID for LightningRidge EXEC B1.
* GUID: 36232936-0E76-31C8-A13A-3AF2FC1C3932
*
* Located by UbaGetProtocolInterface(). Provides DebugPrint (+0x00) and
* DebugAssert (+0x08) services. This is the debug channel portion of the
* UBA framework and is separate from the UBA Config protocol that provides
* GetData.
*/
#define UBA_DEBUG_PROTOCOL_GUID \
{ 0x36232936, 0x0E76, 0x31C8, \
{ 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }
/** Pointer to UBA_DEBUG_PROTOCOL_GUID as EFI_GUID */
extern EFI_GUID gUbaDebugProtocolGuid;
/**
* UBA Config Protocol GUID for LightningRidge EXEC B1.
* GUID: E03E0D46-5263-4845-B0A4-58D57B3177E2
*
* Located directly in _ModuleEntryPoint via gBS->LocateProtocol().
* Provides GetData (+0x10) for reading PSLT configuration entries.
* This protocol is separate from the debug protocol and represents
* the platform-specific UBA configuration data store.
*/
#define UBA_CONFIG_PROTOCOL_GUID \
{ 0xE03E0D46, 0x5263, 0x4845, \
{ 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }
/** Pointer to UBA_CONFIG_PROTOCOL_GUID as EFI_GUID */
extern EFI_GUID gUbaConfigProtocolGuid;
/**
* UBA Slot Data PSLT Entry 1 GUID.
*
* GUID: B93613E1-48F0-4B32-B3A8-4FEDFC7C1365
*
* Used with UbaProtocol->GetData to retrieve the primary PSLT (Platform Slot
* Table) structure containing slot count and slot-specific data.
* Output buffer at mSlotDataBuffer1 (0xBB0), size 32 bytes.
*/
#define UBA_SLOT_DATA_PSLT1_GUID \
{ 0xB93613E1, 0x48F0, 0x4B32, \
{ 0xB3, 0xA8, 0x4F, 0xED, 0xFC, 0x7C, 0x13, 0x65 } }
extern EFI_GUID gUbaSlotDataPsl1Guid;
/**
* UBA Slot Config PSLT Entry 2 GUID.
*
* GUID: 226763AE-972C-4E3C-80D1-73B25E8CBBA3
*
* Used with UbaProtocol->GetData to retrieve the secondary slot configuration
* structure. Output buffer at mSlotDataBuffer2 (0xBE0), size 40 bytes.
* Contains PSLT header plus 8 bytes of extended config data.
*/
#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.
*/
#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. The driver reads PSLT
* entries from the UBA protocol using GetData with specific GUIDs.
*
* Template instances:
* - mSlotDataBuffer1 (0xBB0): GetData writes 32 bytes (PSLT_HEADER)
* - mSlotDataBuffer2 (0xBE0): GetData writes 40 bytes (SLOT_CONFIG)
*
* At runtime, the UBA protocol fills in these structures with platform-
* specific slot configuration data for the LightningRidge EXEC B1 platform.
*/
#pragma pack(push, 1)
typedef struct {
UINT32 Signature; ///< "PSLT" (0x544C5350) -- Platform Slot Table signature
UINT32 Version; ///< PSLT format version (1 for this generation)
UINT64 Length; ///< Total length of PSLT data block (3024 = 0xBD0)
UINT64 StructSize; ///< Size of each per-slot structure (1200 = 0x4B0)
UINT64 NumberOfSlots; ///< Number of PCIe slots defined for this platform (1)
} PSLT_HEADER;
/**
* SLOT_CONFIG - Extended slot configuration structure (40 bytes).
*
* Used for the second GetData call. Contains a PSLT_HEADER followed by
* 8 bytes of platform-specific extended configuration (initialized to
* 0x04B4 in the template, which equals StructSize + 4).
*/
typedef struct {
PSLT_HEADER Header; ///< PSLT header (32 bytes)
UINT64 ConfigData; ///< Extended slot configuration data (8 bytes)
} SLOT_CONFIG;
#pragma pack(pop)
/** Compile-time assertion macro for struct size validation. */
#define ASSERT_STRUCT_SIZE(type, expected) \
typedef char ASSERT_##type##_SIZE[(sizeof(type) == (expected)) ? 1 : -1]
/** Verify PSLT_HEADER is exactly 32 bytes. */
ASSERT_STRUCT_SIZE(PSLT_HEADER, 32);
/** Verify SLOT_CONFIG is exactly 40 bytes. */
ASSERT_STRUCT_SIZE(SLOT_CONFIG, 40);
// =============================================================================
// UBA Protocol Interface Structure
// =============================================================================
/**
* UBA Debug Protocol interface structure.
*
* Located by UbaGetProtocolInterface() with GUID
* {36232936-0E76-31C8-A13A-3AF2FC1C3932} (at 0xB60).
*
* Provides DebugPrint and DebugAssert only. The GetData slot (+0x10)
* may be a stub or null in this protocol instance.
*/
typedef struct {
DEBUG_PRINT_FUNC DebugPrint; ///< +0x00: DebugPrint function
DEBUG_ASSERT_FUNC DebugAssert; ///< +0x08: DebugAssert function
VOID *Reserved3; ///< +0x10: Reserved/GetData (unused)
} UBA_DEBUG_PROTOCOL_INTERFACE;
/**
* UBA Config Protocol interface structure.
*
* Located directly in _ModuleEntryPoint with GUID
* {E03E0D46-5263-4845-B0A4-58D57B3177E2} (at 0xB70).
*
* Provides GetData at +0x10 for reading PSLT configuration entries.
* The +0x00 and +0x08 slots may be reserved or different from the
* debug protocol.
*/
typedef struct {
VOID *Reserved1; ///< +0x00: Possibly DebugPrint (unused)
VOID *Reserved2; ///< +0x08: Possibly DebugAssert (unused)
UBA_GET_DATA_FUNC GetData; ///< +0x10: GetData for PSLT reads
} UBA_CONFIG_PROTOCOL_INTERFACE;
// =============================================================================
// Global Variables (defined in .c)
// =============================================================================
/** Saved ImageHandle from entry point parameter. Address: 0xC18. */
extern EFI_HANDLE gImageHandle;
/** Saved SystemTable pointer from entry point parameter. Address: 0xC08. */
extern EFI_SYSTEM_TABLE *gSystemTable;
/** Saved BootServices pointer (SystemTable->BootServices). Address: 0xC10. */
extern EFI_BOOT_SERVICES *gBootServices;
/** Saved RuntimeServices pointer (SystemTable->RuntimeServices). Address: 0xC20. */
extern EFI_RUNTIME_SERVICES *gRuntimeServices;
// =============================================================================
// Internal Module State (STATIC in .c, listed here for documentation only)
// =============================================================================
/**
* Cached UBA debug protocol interface pointer (mUbaDebugProtocol). Address: 0xC28.
* Lazily initialized by UbaGetProtocolInterface() using GUID at 0xB60.
* Provides DebugPrint and DebugAssert. NULL initially.
*/
extern UBA_DEBUG_PROTOCOL_INTERFACE *mUbaDebugProtocol;
/**
* Cached HOB list pointer from config table (mHobList). Address: 0xC30.
* Initialized by GetHobList(). NULL initially.
*/
extern VOID *mHobList;
/**
* Cached platform type from CMOS[0x4B] or hardware strap (mPlatformType).
* Address: 0xC38. Initial value: 0.
*/
extern UINT8 mPlatformType;
/**
* PSLT buffer 1 -- slot data output buffer (mSlotDataBuffer1).
* Address: 0xBB0. 32 bytes. Template filled by GetData.
*/
extern PSLT_HEADER mSlotDataBuffer1;
/**
* PSLT buffer 2 -- slot config output buffer (mSlotDataBuffer2).
* Address: 0xBE0. 40 bytes. Template filled by GetData.
*/
extern SLOT_CONFIG mSlotDataBuffer2;
// =============================================================================
// Function Declarations
// =============================================================================
/**
* UEFI DXE driver entry point.
*
* Called by the DXE Core during driver dispatch. Performs:
* 1. Caches ImageHandle, SystemTable, BootServices, RuntimeServices globals.
* 2. Initializes HOB list from config table.
* 3. Locates the UBA protocol via LocateProtocol.
* 4. Reads PSLT entry 1 (slot data) and entry 2 (slot config) via GetData.
*
* @param[in] ImageHandle The firmware-allocated handle for this image.
* @param[in] SystemTable A pointer to the EFI System Table.
* @return EFI_STATUS EFI_SUCCESS, or EFI_NOT_FOUND from LocateProtocol,
* or error from GetData.
*/
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 B1. Used by the UBA framework
* for slot enumeration and SMBIOS topology reporting.
*
* @return UINT8 Always 2 (number of PCIe slots).
*/
UINT8
EFIAPI
GetSlotCount (
VOID
);
/**
* Identity pass-through for slot data.
*
* Returns DefaultData unchanged. Slot data on EXEC B1 is populated by
* UbaProtocol->GetData directly; no callback customization is needed.
*
* @param[in] Slot Slot index (unused).
* @param[in] DefaultData Pointer to default slot data.
* @return VOID* The unmodified DefaultData pointer.
*/
VOID *
EFIAPI
GetSlotData (
IN UINTN Slot,
IN VOID *DefaultData
);
/**
* Lazily resolves and caches the UBA DEBUG protocol interface.
*
* TPL-safe LocateProtocol wrapper. Uses the debug protocol GUID at 0xB60
* ({36232936-0E76-31C8-A13A-3AF2FC1C3932}). Raises to TPL_HIGH_LEVEL (31),
* restores to verify current TPL <= TPL_NOTIFY (0x10), then calls
* gBS->LocateProtocol(...). Provides DebugPrint and DebugAssert.
*
* NOTE: This 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-aware debug print with CMOS platform-type filtering.
*
* Reads CMOS register 0x4B via I/O ports 0x70/0x71 to determine verbosity:
* - <= 3: Direct verbosity level (0=DE, 1=DE|DI, 2+=DE|DV)
* - > 3: Platform type. If cached type is 0, derives from hardware strap
* at MMIO 0xFDAF0490: type = (strap & 2) | 1 (always >= 1)
* - All derived types >= 1 produce DE|DV mask (0x80000006).
*
* If the resulting mask matches the caller's severity, the message is
* forwarded to the protocol's DebugPrint function.
*
* @param[in] DebugLevel Debug message severity mask.
* @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-aware ASSERT failure handler.
*
* Locates the UBA protocol and calls DebugAssert (+0x08) with the file
* name, line number, and assertion expression. Silently returns if the
* UBA protocol is unavailable.
*
* @param[in] FileName Source file where assertion failed.
* @param[in] LineNumber Line number of failed assertion.
* @param[in] Expression Assertion expression string.
*/
VOID
EFIAPI
UbaDebugAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Expression
);
/**
* Locates and caches the HOB list from SystemTable->ConfigurationTable.
*
* Scans for gEfiDxeServicesTableGuid ({7739F24C-93D7-11D4-9A3A-0090273FC14D})
* using IsHobGuidMatch (64-bit halves comparison).
* If not found, triggers debug assert with EFI_NOT_FOUND.
*
* @return VOID* Pointer to the HOB list, or NULL.
*/
VOID *
EFIAPI
GetHobList (
VOID
);
/**
* Compares two EFI_GUID values via unaligned 64-bit reads.
*
* Reads both halves (bytes 0-7 and 8-15) of each GUID using
* ReadUnaligned64 and compares them. This is an unaligned-safe
* comparison following the standard EDK2 pattern.
*
* @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 assertion.
*
* Asserts via UbaDebugAssert if Buffer is NULL, then performs a direct
* 64-bit read. On x64 the CPU natively handles unaligned accesses.
*
* @param[in] Buffer Pointer to UINT64 (must not be NULL).
* @return UINT64 The value at Buffer.
*/
UINT64
EFIAPI
ReadUnaligned64 (
IN CONST UINT64 *Buffer
);
#endif // SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B1_H