/**
* @file OpromUpdateDxeLightningRidgeEXECB2.h
* @brief UBA OpromUpdate DXE driver for LightningRidge (C621/C622) EXEC B2 board.
*
* This is an Intel UBA (Unified BIOS Architecture) OpromUpdate-type driver that
* registers board-specific PCIe slot configuration callbacks for the LightningRidge
* PCH (Lewisburg/C620 series) EXEC B2 board variant.
*
* The driver registers callbacks via UbaConfigProtocol to provide:
* 1. PCIe slot populated-function detection (by reading PCI Express Capability registers)
* 2. Board-specific PCIe slot/port mapping data
* 3. Two PCIe slot NVRAM configuration tables (slot-to-BDF mapping)
*
* Key GUID definitions:
* gEfiPciIoProtocolGuid - EFI_PCI_IO_PROTOCOL (2f707ebb-4a1a-11d4-...)
* gUbaDebugProtocolGuid - UBA debug protocol (36232936-0e76-31c8-...)
* gUbaConfigProtocolGuid - UBA config protocol (e03e0d46-5263-4845-...)
* gOpromUpdateBoardGuid - Board registration GUID (371bd79c-de79-4c5f-...)
* gEfiGuidedSectionExtractionProtocolGuid - (7739f24c-93d7-11d4-...)
*/
#ifndef OPROM_UPDATE_DXE_LIGHTNINGRIDGE_EXEC_B2_H_
#define OPROM_UPDATE_DXE_LIGHTNINGRIDGE_EXEC_B2_H_
#include "../uefi_headers/Uefi.h"
//=============================================================================
// GUID Definitions
//=============================================================================
///
/// {2f707ebb-4a1a-11d4-9a38-0090273fc14d}
/// Standard UEFI PCI I/O Protocol GUID. Used to read PCI config space
/// for slot-population detection.
///
#define EFI_PCI_IO_PROTOCOL_GUID \
{ 0x2f707ebb, 0x4a1a, 0x11d4, { 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
///
/// {36232936-0e76-31c8-a13a-3af2fc1c3932}
/// UBA Debug Protocol GUID (used for debug message output).
/// The debug protocol interface has a Report function at offset +8
/// and a ReportAssert function at offset +0 (assert handler).
///
#define UBA_DEBUG_PROTOCOL_GUID \
{ 0x36232936, 0x0e76, 0x31c8, { 0xa1, 0x3a, 0x3a, 0xf2, 0xfc, 0x1c, 0x39, 0x32 } }
///
/// {e03e0d46-5263-4845-b0a4-58d57b3177e2}
/// UBA Config Protocol GUID. This is the main protocol interface used
/// to register board-specific configuration data and callbacks.
///
#define UBA_CONFIG_PROTOCOL_GUID \
{ 0xe03e0d46, 0x5263, 0x4845, { 0xb0, 0xa4, 0x58, 0xd5, 0x7b, 0x31, 0x77, 0xe2 } }
///
/// {371bd79c-de79-4c5f-aa2b-bc9ebefa988f}
/// OpromUpdate LightningRidge EXEC B2 Board GUID.
/// Used as registration key when registering the PBDS callback table
/// with the UBA Config Protocol.
///
#define OPROM_UPDATE_BOARD_GUID \
{ 0x371bd79c, 0xde79, 0x4c5f, { 0xaa, 0x2b, 0xbc, 0x9e, 0xbe, 0xfa, 0x98, 0x8f } }
///
/// {7739f24c-93d7-11d4-9a3a-0090273fc14d}
/// EFI Guided Section Extraction Protocol GUID.
/// Stored at 0xD10 but not used in this driver (may be used by UBA framework).
///
#define EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID \
{ 0x7739f24c, 0x93d7, 0x11d4, { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
//=============================================================================
// Type Definitions
//=============================================================================
///
/// PBDS_CONFIG_SIGNATURE
/// Signature string for the board config callback table.
/// "PBDS" = Platform Board Data Structure (Intel UBA naming convention).
///
#define PBDS_CONFIG_SIGNATURE SIGNATURE_32('P', 'B', 'D', 'S')
///
/// Maximum number of PCIe root ports / slot entries in the BDF lookup table.
///
#define MAX_PCIE_ROOT_PORTS 8
///
/// Maximum number of slots in the first slot config table (returned by GetSlotConfig1).
///
#define MAX_SLOT_CONFIG1_ENTRIES 6
///
/// Maximum number of slots in the second slot config table (returned by GetSlotConfig2).
///
#define MAX_SLOT_CONFIG2_ENTRIES 10
///
/// Structure of one entry in the PCIe root port BDF lookup table at 0xED1.
/// Each entry encodes:
/// @v8 Register offset within the root port's config space
/// @v9 [2:0] = Function number, [7:3] = Device number
/// @v10 Bus number
///
/// When combined into a 32-bit value:
/// bits [7:0] = Register offset
/// bits [15:8] = (v9 & 7) = Function
/// bits [20:16] = (v9 >> 3) = Device
/// bits [31:24] = v10 = Bus
///
typedef struct {
UINT8 RegisterOffset; ///< Config space register offset base
UINT8 DevFunc; ///< [2:0]=Function, [7:3]=Device
UINT8 Bus; ///< PCI bus number
UINT8 Reserved; ///< Padding to 4-byte aligned entry
} PCIE_ROOT_PORT_BDF_ENTRY;
///
/// The PCIe Root Port BDF lookup table.
/// Contains 8 entries mapping root port indices to PCI bus:device:function.
///
typedef struct {
PCIE_ROOT_PORT_BDF_ENTRY Entries[MAX_PCIE_ROOT_PORTS];
} PCIE_ROOT_PORT_BDF_TABLE;
///
/// Board callback function table ("PBDS" format).
/// This structure is registered with the UBA Config Protocol.
///
typedef struct {
UINT32 Signature; ///< "PBDS" signature
UINT32 Version; ///< Structure version (currently 1)
UINT64 BoardCallbacks[4]; ///< Relocatable RVAs to callback functions:
///< 0: IsFunctionInPopulatedSlot
///< 1: GetBoardInfo
///< 2: GetSlotConfig1
///< 3: GetSlotConfig2
} PBDS_BOARD_CONFIG;
///
/// PCIe Slot NVRAM configuration entry structure.
/// Format used in the slot config tables at 0xD60 and 0xE60.
///
typedef struct {
UINT32 SlotInfo; ///< Slot identification / port register
UINT32 Flags; ///< Slot capability flags
UINT32 PciAddress; ///< PCI address: [31:24]=Bus, [23:16]=Reserved, [15:11]=Device, [10:8]=Func
} PCIE_SLOT_CONFIG_ENTRY;
///
/// UEFI System Table global (cached pointer).
///
extern EFI_SYSTEM_TABLE *gST;
extern EFI_BOOT_SERVICES *gBS;
extern EFI_HANDLE gImageHandle;
//=============================================================================
// Global Variable Declarations
//=============================================================================
///
/// @var gSystemTable
/// Pointer to the UEFI System Table (cached at module entry).
///
extern EFI_SYSTEM_TABLE *gSystemTable;
///
/// @var gBootServices
/// Pointer to the UEFI Boot Services Table (cached at module entry).
///
extern EFI_BOOT_SERVICES *gBootServices;
///
/// @var gRuntimeServices
/// Pointer to the UEFI Runtime Services Table (cached at module entry).
///
extern EFI_RUNTIME_SERVICES *gRuntimeServices;
///
/// @var gDebugProtocol
/// Cached pointer to the UBA Debug Protocol interface.
/// Lazily initialized by LocateDebugProtocol().
/// NULL if protocol is not found or initialization fails.
///
extern VOID *gDebugProtocol;
///
/// @var gHobList
/// Cached pointer to the HOB (Hand-Off Block) list.
/// Populated by GetHobList() from the SystemTable's configuration table.
///
extern VOID *gHobList;
///
/// @var gDebugFlags
/// Debug output control flags (used by DebugPrint).
///
extern UINTN gDebugFlags;
//=============================================================================
// Function Declarations
//=============================================================================
/**
* UEFI Driver Entry Point.
*
* Initializes UEFI globals, locates the HOB list, and registers the
* LightningRidge EXEC B2 board-specific callback table with the
* UBA Config Protocol.
*
* The registration includes four callbacks:
* - IsFunctionInPopulatedSlot() - detects populated PCIe slots
* - GetBoardInfo() - returns board identification data
* - GetSlotConfig1() - returns first PCIe slot config table
* - GetSlotConfig2() - returns second PCIe slot config table
*
* Registration GUID: OPROM_UPDATE_BOARD_GUID (371bd79c-...)
* Protocol: gUbaConfigProtocolGuid (e03e0d46-...)
* Registration data: PBDS_BOARD_CONFIG with Signature="PBDS", Version=1
*
* @param[in] ImageHandle UEFI image handle
* @param[in] SystemTable UEFI system table
* @return EFI_STATUS EFI_SUCCESS if registered, error otherwise
*/
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
IN EFI_IMAGE_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
* Checks if a PCI function belongs to a populated PCIe slot.
*
* Iterates through 8 PCIe root port table entries. For each root port
* where the corresponding bit in @p SlotBitmask is clear (slot is
* populated), reads the root port's PCIe Device Capabilities registers
* at config offsets (BDF_Base | 0x19) and (BDF_Base | 0x1A) to determine
* the supported function number range.
*
* The root port BDF entries are in a lookup table that encodes
* Bus/Device/Function for each of the 8 possible root ports.
*
* Access to PCI config space uses EFI_PCI_IO_PROTOCOL.Pci.Read
* through the protocol located via LocateProtocol.
* @param[in] FuncNum The PCI function number to check
* @param[in] SlotBitmask 8-bit bitmask: bit n=0 means slot n is populated and should
* be checked; bit n=1 means slot n is unpopulated (skip)
* @retval TRUE The function belongs to at least one populated slot
* @retval FALSE The function does NOT belong to any populated slot
*/
BOOLEAN
EFIAPI
IsFunctionInPopulatedSlot (
IN UINT64 FuncNum,
IN UINT32 SlotBitmask
);
/**
* Returns the board-specific PCIe structure pointer.
*
* LightningRidge EXEC B2 does not have additional board info;
* returns a pointer to an empty/zeroed structure.
*
* @param[out] BoardInfo Pointer to set to the board info structure
* @return EFI_SUCCESS Always returns EFI_SUCCESS
*/
EFI_STATUS
EFIAPI
GetBoardInfo (
OUT VOID **BoardInfo
);
/**
* Returns the first PCIe slot configuration table.
*
* The table at memory offset 0xD60 contains @ 6 entries describing
* PCIe slot-to-BDF mappings for the board.
* @param[out] SlotConfig Pointer to set to the slot configuration table
* @param[out] EntryCount Set to 6 (number of entries in the table)
* @return EFI_SUCCESS Always returns EFI_SUCCESS
*/
EFI_STATUS
EFIAPI
GetSlotConfig1 (
OUT VOID **SlotConfig,
OUT UINTN *EntryCount
);
/**
* Returns the second PCIe slot configuration table.
*
* The table at memory offset 0xE60 contains 10 entries describing
* additional PCIe slot-to-BDF mappings for the board.
*
* @param[out] SlotConfig Pointer to set to the slot configuration table
* @param[out] EntryCount Set to 10 (number of entries in the table)
* @return EFI_SUCCESS Always returns EFI_SUCCESS
*/
EFI_STATUS
EFIAPI
GetSlotConfig2 (
OUT VOID **SlotConfig,
OUT UINTN *EntryCount
);
/**
* Debug callback invoked when UBA sets a PCIe slot number.
*
* LightningRidge EXEC B2 does not override PCIe slot numbers
* (returns 0, indicating use the hardware default).
*
* @param[out] SlotNumber Set to 0 (no override)
* @return EFI_SUCCESS Always returns EFI_SUCCESS
*/
EFI_STATUS
EFIAPI
SetPcieSlotNumber (
OUT UINT8 *SlotNumber
);
//
// Internal library functions
//
/**
* Lazily locates and caches the UBA Debug Protocol.
*
* Allocates a page of BootServicesData memory (for the protocol
* interface buffer), checks if TPL was <= TPL_NOTIFY (0x10),
* then calls LocateProtocol(gUbaDebugProtocolGuid, NULL, &gDebugProtocol).
*
* Cached in @p gDebugProtocol (at 0xF50).
*
* @return Pointer to UBA Debug Protocol interface, or NULL on failure
*/
VOID *
LocateDebugProtocol (
VOID
);
/**
* Outputs a debug message via the UBA Debug Protocol.
*
* If the debug protocol is available, calls its Report function
* (at interface+8) with the given severity, format string, and args.
*
* Also performs a CMOS check: reads CMOS index 0x4B (via I/O ports 0x70/0x71)
* to determine debug verbosity level. Only prints if the requested
* severity level matches the CMOS-configured bitmask.
*
* @param[in] ErrorLevel Debug severity level
* @param[in] Format Printf-style format string
* @param[in] ... Variable arguments for format string
*
* @return Non-zero if message was printed, 0 if suppressed or protocol unavailable
*/
UINT8
EFIAPI
DebugPrint (
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
...
);
/**
* Reports an assertion failure via the UBA Debug Protocol.
*
* If the debug protocol is available, forwards the assert
* to the protocol's ReportAssert function (at interface+0).
*
* @param[in] FileName Source file name where assertion failed
* @param[in] LineNumber Line number of the failed assertion
* @param[in] Description Assert condition description string
*
* @retval 0 Assert handled (by protocol)
* @retval negative Protocol not available
*/
EFI_STATUS
EFIAPI
ReportAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
);
/**
* Locates and caches the HOB (Hand-Off Block) list.
*
* Iterates through the SystemTable's configuration table entries
* looking for one with the HOB list GUID (gHobListGuid).
* If found, caches the HOB list pointer in @p gHobList.
* Uses CompareGuid() for GUID matching.
*
* @return Pointer to HOB list, or NULL if not found
*/
VOID *
GetHobList (
VOID
);
/**
* Compares two GUIDs for equality.
*
* Simple byte-by-byte comparison of two 16-byte GUIDs.
* Used by GetHobList() to match GUID entries in the
* configuration table.
*
* @param[in] Guid1 First GUID to compare
* @param[in] Guid2 Second GUID to compare
* @retval TRUE GUIDs are equal
* @retval FALSE GUIDs differ
*/
BOOLEAN
EFIAPI
CompareGuid (
IN EFI_GUID *Guid1,
IN EFI_GUID *Guid2
);
/**
* Reads a 64-bit value from an unaligned memory address.
*
* If the address is NULL, triggers an assertion.
*
* @param[in] Buffer Memory address to read from
* @return UINT64 The value read from the address
*/
UINT64
EFIAPI
ReadUnaligned64 (
IN CONST VOID *Buffer
);
#endif // OPRON_UPDATE_DXE_LIGHTNINGRIDGE_EXEC_B2_H_