/**
* @file IioCfgUpdateDxeLightningRidgeEXECB1.h
*
* @brief IioCfgUpdateDxeLightningRidgeEXECB1 - UEFI DXE driver for registering
* IIO (Integrated IO) configuration data for the LightningRidgeEXECB1
* platform via the UBA (Unified Board Architecture) framework.
*
* MODULE TYPE: DXE Driver
* UEFI PHASE: DXE (Driver Execution Environment)
*
* PURPOSE:
* This driver is part of Lenovo's UBA (Unified Board Architecture) framework.
* It performs the following at entry:
* 1. Initializes UEFI global variables (gImageHandle, gST, gBS, gRT)
* via the UefiBootServicesTableLib and UefiRuntimeServicesTableLib.
* 2. Locates the HOB (Hand-Off Block) list from the UEFI System Table's
* configuration table array by matching the EFI_HOB_LIST_GUID.
* 3. Locates a UBA board-type protocol using gBS->LocateProtocol()
* (same protocol GUID E03E0D46-... used by RomLayoutDxe and other
* UBA platform modules).
* 4. Registers up to 4 IIO configuration protocol instances by calling
* the board-type protocol's registration function, passing a
* UBA_IIO_CFG_UPDATE_PROTOCOL structure (signature "PIIO") and a
* board-config GUID for each IIO (CPU socket) instance.
* 5. Provides debug output via the DebugLib protocol accessed through
* gBS (RaiseTPL/RestoreTPL for critical sections).
*
* DEPENDENCIES (Protocols consumed):
* - UBA Board-Type Protocol (GUID: e03e0d46-5263-4845-b0a4-58d57b3177e2)
* Same protocol used by RomLayoutDxe, SlotDataUpdateDxe*, etc.
* Located via gBS->LocateProtocol(). Provides a registration function
* at interface offset 0x10.
* - EFI_HOB_LIST_GUID (7739f24c-93d7-11d4-9a3a-0090273fc14d)
* Used to locate the HOB list from the system configuration table.
* - UEFI Debug Library Protocol (implicit via gBS)
*
* DEPENDENCIES (Protocols produced):
* - UBA IIO Config Update Protocol (GUIDs vary per IIO instance):
* * 6FE6C559-4F35-4111-98E1-332A251512F3
* * 0F722F2A-650F-448A-ABB7-04EECD75BB30
* * EBD11A00-8C5C-4F71-BB9E-5394032B01F4
* * 123BD082-3201-465C-B139-0CB8C77208F8
* These represent IIO configuration instances for up to 4 CPU sockets
* on the LightningRidgeEXECB1 platform.
*
* HARDWARE ACCESS:
* - CMOS ports 0x70/0x71: Read debug level setting mask from CMOS register 0x4B
* - MMIO 0xFDAF0490: On boards where CMOS byte is 0, reads a board config
* register to determine board type.
*
* LIBRARY DEPENDENCIES:
* - UefiBootServicesTableLib (gImageHandle, gST, gBS)
* - UefiRuntimeServicesTableLib (gRT)
* - DxeHobLib (HOB list parsing)
* - BaseLib (unaligned read: ReadUnaligned64)
* - DebugLib (DEBUG macro via CmosDebugLevelProvider)
*
* @note This module is specific to the LightningRidgeEXECB1 platform type.
* Similar modules exist for other platforms (e.g., LightningRidgeEXECB2,
* LightningRidgeEXRP, NeonCityFPGA) with different IIO config tables.
*/
#ifndef _IIO_CFG_UPDATE_DXE_LIGHTNINGRIDGE_EXECB1_H_
#define _IIO_CFG_UPDATE_DXE_LIGHTNINGRIDGE_EXECB1_H_
#include "../uefi_headers/Uefi.h"
// ============================================================================
// GUID Definitions
// ============================================================================
///
/// EFI_HOB_LIST_GUID - GUID used to locate the HOB list in the system
/// configuration table.
/// {7739F24C-93D7-11D4-9A3A-0090273FC14D}
///
#define EFI_HOB_LIST_GUID \
{ 0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
///
/// UBA_BOARD_TYPE_PROTOCOL_GUID
/// Protocol GUID used with gBS->LocateProtocol() to obtain the UBA board-type
/// protocol interface. This is the same protocol GUID used across all UBA
/// platform modules (RomLayoutDxe, SlotDataUpdateDxe*, etc.).
/// The protocol's interface has a function at offset 0x10 that registers
/// platform-specific configuration data.
/// {E03E0D46-5263-4845-B0A4-58D57B3177E2}
///
#define UBA_BOARD_TYPE_PROTOCOL_GUID \
{ 0xE03E0D46, 0x5263, 0x4845, { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }
///
/// UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_0
/// IIO configuration protocol for CPU socket 0 on LightningRidgeEXECB1.
/// {6FE6C559-4F35-4111-98E1-332A251512F3}
///
#define UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_0 \
{ 0x6FE6C559, 0x4F35, 0x4111, { 0x98, 0xE1, 0x33, 0x2A, 0x25, 0x15, 0x12, 0xF3 } }
///
/// UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_1
/// IIO configuration protocol for CPU socket 1 on LightningRidgeEXECB1.
/// {0F722F2A-650F-448A-ABB7-04EECD75BB30}
///
#define UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_1 \
{ 0x0F722F2A, 0x650F, 0x448A, { 0xAB, 0xB7, 0x04, 0xEE, 0xCD, 0x75, 0xBB, 0x30 } }
///
/// UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_2
/// IIO configuration protocol for CPU socket 2 on LightningRidgeEXECB1.
/// {EBD11A00-8C5C-4F71-BB9E-5394032B01F4}
///
#define UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_2 \
{ 0xEBD11A00, 0x8C5C, 0x4F71, { 0xBB, 0x9E, 0x53, 0x94, 0x03, 0x2B, 0x01, 0xF4 } }
///
/// UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_3
/// IIO configuration protocol for CPU socket 3 on LightningRidgeEXECB1.
/// {123BD082-3201-465C-B139-0CB8C77208F8}
///
#define UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_3 \
{ 0x123BD082, 0x3201, 0x465C, { 0xB1, 0x39, 0x0C, 0xB8, 0xC7, 0x72, 0x08, 0xF8 } }
///
/// UBA_DEBUG_PROTOCOL_GUID
/// Protocol GUID for the UBA Debug Library protocol, cached by GetDebugProtocol().
/// This protocol provides debug output and assertion handling.
/// {36232936-0E76-31C8-A13A-3AF2FC1C3932}
///
#define UBA_DEBUG_PROTOCOL_GUID \
{ 0x36232936, 0x0E76, 0x31C8, { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }
// ============================================================================
// Structure Definitions
// ============================================================================
///
/// UBA_IIO_CFG_UPDATE_PROTOCOL
/// Structure passed to the UBA board-type protocol to register IIO
/// configuration data for a specific CPU socket.
///
/// The signature is "PIIO" (little-endian: 'P','I','I','O'), which encodes
/// "OIIP" in memory, representing "IIO Protocol".
///
typedef struct {
///
/// Signature = "PIIO" (0x4F494950 in little-endian).
///
UINT32 Signature;
///
/// Board ID value. On LightningRidgeEXECB1, this is 0x0D60.
///
UINT16 BoardId;
///
/// Padding/Reserved.
///
UINT16 Reserved0;
///
/// Slot number (CPU socket index). This is 0x3C (60) on the
/// LightningRidgeEXECB1 platform.
///
UINT64 SlotNumber;
///
/// Size of the IIO configuration table in bytes. Value = 0x50C (1292).
///
UINT64 IioCfgTableSize;
///
/// Pointer (relative offset from image base) to the IIO configuration table.
/// On LightningRidgeEXECB1, this points to offset 0xC60 in the image.
///
UINT64 IioCfgTable;
///
/// Reserved padding field. Value = 0xFC (252).
///
UINT64 Reserved1;
} UBA_IIO_CFG_UPDATE_PROTOCOL;
///
/// UBA_IIO_CFG_UPDATE_TABLE_ENTRY
/// An entry in the IIO configuration table at IioCfgTable.
/// Each entry is 12 bytes and encodes configuration for a specific IIO
/// register or port on a CPU socket.
///
typedef struct {
///
/// Byte 0: Configuration type/register index.
///
UINT8 Type;
///
/// Byte 1: Sub-type or function selector.
///
UINT8 SubType;
///
/// Bytes 2-3: Reserved/padding (typically 0xFFFF = unchecked).
///
UINT16 Reserved0;
///
/// Bytes 4-7: Reserved/padding (typically 0xFFFF0000...).
///
UINT32 Reserved1;
///
/// Byte 8: Target value or device selector.
///
UINT8 Value;
///
/// Byte 9: Port/address.
///
UINT8 Port;
///
/// Bytes 10-11: Reserved/padding.
///
UINT16 Reserved2;
} UBA_IIO_CFG_UPDATE_TABLE_ENTRY;
///
/// UBA_IIO_CFG_UPDATE_TABLE_ENTRY_SIZE
/// Size of each entry in the IIO configuration table (12 bytes).
///
#define UBA_IIO_CFG_UPDATE_TABLE_ENTRY_SIZE 12
// ============================================================================
// Constants
// ============================================================================
///
/// IIO protocol signature ("PIIO" in little-endian).
///
#define UBA_IIO_CFG_UPDATE_SIGNATURE SIGNATURE_32('P', 'I', 'I', 'O')
///
/// Board ID value for LightningRidgeEXECB1.
///
#define LIGHTNINGRIDGE_EXECB1_BOARD_ID 0x0D60
///
/// Slot number on this platform.
///
#define LIGHTNINGRIDGE_EXECB1_SLOT_NUMBER 0x3C
///
/// IIO configuration table size (1292 bytes = 0x50C).
///
#define LIGHTNINGRIDGE_EXECB1_IIO_CFG_SIZE 0x50C
///
/// Number of IIO configuration protocols registered (4 sockets max).
///
#define IIO_CFG_UPDATE_PROTOCOL_COUNT 4
///
/// CMOS debug level register. Port 0x70 selects the CMOS register;
/// port 0x71 reads/writes the value.
/// Register 0x4B is used for board type / debug level control.
///
#define CMOS_DEBUG_LEVEL_REGISTER 0x4B
///
/// CMOS index port
///
#define RTC_INDEX_PORT 0x70
///
/// CMOS data port
///
#define RTC_DATA_PORT 0x71
///
/// Board configuration MMIO register address (used for debug level fallback
/// when CMOS byte is 0).
///
#define BOARD_CONFIG_MMIO_ADDR 0xFDAF0490ULL
///
/// Debug message severity mask. Used with the DebugLib protocol.
///
#define DEBUG_INFO 0x80000000
///
/// Board type CMOS byte value indicating "read from MMIO".
///
#define BOARD_TYPE_CMOS_NEEDS_MMIO 0
///
/// Board type threshold: values 1, 2, 3 are "standard" board types.
///
#define BOARD_TYPE_STANDARD_MAX 3
///
/// Mask for board type extraction from MMIO register.
///
#define BOARD_TYPE_MMIO_MASK 2
///
/// Flag bit for MMIO-based board type.
///
#define BOARD_TYPE_MMIO_FLAG_BIT BIT0
// ============================================================================
// Global Variable Declarations
// ============================================================================
//
// UEFI Boot Services Table pointer (cached by UefiBootServicesTableLib).
//
extern EFI_SYSTEM_TABLE *gST;
extern EFI_BOOT_SERVICES *gBS;
extern EFI_RUNTIME_SERVICES *gRT;
extern EFI_HANDLE gImageHandle;
///
/// Pointer to the HOB list, obtained from the system configuration table
/// by searching for the EFI_HOB_LIST_GUID entry.
///
extern VOID *gHobList;
///
/// Cached debug protocol interface obtained by GetDebugProtocol().
///
extern VOID *gDebugProtocol;
// ============================================================================
// Function Declarations
// ============================================================================
/**
* Module entry point for IioCfgUpdateDxeLightningRidgeEXECB1.
*
* Initializes UEFI global variables (gImageHandle, gST, gBS, gRT), locates the
* HOB list via GetHobList(), prints a debug banner via DebugPrint(), locates the
* UBA board-type protocol, and registers up to 4 IIO configuration protocol
* instances by calling the protocol's registration function.
*
* @param[in] ImageHandle The firmware-allocated handle for this driver image.
* @param[in] SystemTable A pointer to the EFI System Table.
*
* @return EFI_SUCCESS At least one IIO configuration protocol was registered.
* @return Other The board-type protocol could not be located.
*/
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
* Registers all IIO configuration protocol instances for this platform.
*
* Locates the UBA board-type protocol, then registers up to 4 IIO configuration
* protocol instances (one per CPU socket) by calling the protocol's registration
* function. Each registration call passes a different board-config GUID and the
* same UBA_IIO_CFG_UPDATE_PROTOCOL structure (48 bytes).
*
* @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
);
/**
* Resolves and caches the UBA DebugLib protocol interface.
*
* Raises the task priority level to TPL_HIGH_LEVEL, then calls
* gBS->LocateProtocol() with the UBA_DEBUG_PROTOCOL_GUID to obtain the
* DebugLib protocol interface. Results are cached in the global variable
* gDebugProtocol to avoid repeated Lookups.
*
* @return Pointer to the UBA DebugLib protocol interface.
* Returns 0 if the platform only has 1 CPU package (HOB allocation
* size <= 0x10) or if the protocol cannot be located.
*/
VOID *
GetDebugProtocol (
VOID
);
/**
* Debug print function (wraps the UEFI DebugLib protocol).
*
* Resolves the DebugLib protocol interface via GetDebugProtocol(), then
* reads the debug level from CMOS register 0x4B to determine if the
* requested severity mask is enabled. If so, calls the DebugLib protocol's
* output function.
*
* @param[in] ErrorLevel The debug error level mask (e.g., 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,
...
);
/**
* ASSERT assertion failure handler.
*
* Called when a runtime assertion fails. Resolves the DebugLib protocol
* via GetDebugProtocol() and calls its assertion failure handler.
*
* @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
);
/**
* 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.
*
* Results are cached in the global variable gHobList.
*
* @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
);
/**
* Compares a GUID against the EFI_HOB_LIST_GUID by comparing its first 8 bytes
* and second 8 bytes independently.
*
* Uses ReadUnaligned64() to perform the comparison.
*
* @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
);
/**
* Returns the UEFI status code for "Not Found".
*
* This is a trivial leaf function that returns 0x800000000000000E (EFI_NOT_FOUND).
*
* @return EFI_NOT_FOUND (0x800000000000000E).
*/
EFI_STATUS
ReturnNotFound (
VOID
);
/**
* Reads an unaligned 64-bit value from memory.
*
* Wraps the BaseLib ReadUnaligned64() function with a NULL pointer check.
*
* @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
);
// ============================================================================
// UBA Board-Type Protocol Interface
// ============================================================================
///
/// UBA_BOARD_TYPE_PROTOCOL
///
/// The protocol interface obtained via gBS->LocateProtocol() using the GUID
/// UBA_BOARD_TYPE_PROTOCOL_GUID.
///
/// This protocol is used to register platform-specific configuration data
/// (IIO config, setup config, slot data, SMBIOS data, etc.). The registration
/// function is at offset 0x10 within the interface structure.
///
typedef struct {
///
/// Unknown fields at offsets 0x00-0x0F (may contain protocol revision,
/// header, or other methods).
///
UINT64 Reserved0;
UINT64 Reserved1;
///
/// Function at offset 0x10. Registers a platform-specific configuration
/// protocol instance.
///
/// @param[in] This Pointer to the UBA board-type protocol interface.
/// @param[in] ProtocolGuid GUID of the protocol to register
/// (e.g., UBA_IIO_CFG_UPDATE_PROTOCOL_GUID_x).
/// @param[in] ConfigData Pointer to the UBA_IIO_CFG_UPDATE_PROTOCOL structure.
/// @param[in] ConfigDataSize Size of the configuration data structure in bytes.
///
/// @return EFI_STATUS.
///
EFI_STATUS
(EFIAPI *RegisterConfig) (
IN VOID *This,
IN EFI_GUID *ProtocolGuid,
IN UBA_IIO_CFG_UPDATE_PROTOCOL *ConfigData,
IN UINT64 ConfigDataSize
);
} UBA_BOARD_TYPE_PROTOCOL;
#endif /* _IIO_CFG_UPDATE_DXE_LIGHTNINGRIDGE_EXECB1_H_ */