/**
* @file RomLayoutDxe.h
*
* @brief RomLayoutDxe - UEFI DXE driver for locating ROM layout via HOB and
* registering a UBA (Unified Board Architecture) setup configuration
* protocol for the NeonCityFPGA platform.
*
* 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. Locates the HOB (Hand-Off Block) list from the UEFI System Table's
* configuration table array by matching the EFI_HOB_LIST_GUID.
* 2. Locates a UBA board-type protocol (specific to NeonCityFPGA) using
* gBS->LocateProtocol().
* 3. Installs a new protocol interface (with GUID cd1f9574-dd03-4196-96ad-4965146f9665)
* via a function on the located UBA protocol interface, passing a
* UBA_SETUP_CONFIG_DATA structure (signature "PSET", version 1, 0x48c bytes).
* 4. Provides debug output via the UEFI DebugLib protocol accessed through
* the UEFI Boot Services table (gBS).
*
* DEPENDENCIES (Protocols consumed):
* - UBA NeonCityFPGA Board-Type Protocol (GUID: e03e0d46-5263-4845-b0a4-58d57b3177e2)
* This protocol is located to register the setup configuration.
* - 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 NeonCityFPGA Setup Config Protocol
* (GUID: cd1f9574-dd03-4196-96ad-4965146f9665)
* Registered with a UBA_SETUP_CONFIG_DATA interface.
*
* HARDWARE ACCESS:
* - CMOS ports 0x70/0x71: Read debug level setting mask from CMOS register 0x4B
* - MMIO 0xFDAF0490: On some platforms, reads a board configuration register
* to determine debug verbosity level.
*
* 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 index 0000 in the BIOS FFS - it is one of the first
* DXE drivers dispatched.
*/
#ifndef _ROM_LAYOUT_DXE_H_
#define _ROM_LAYOUT_DXE_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_NEONCITYFPGA_BOARD_TYPE_PROTOCOL_GUID
/// Protocol GUID used with gBS->LocateProtocol() to obtain the UBA board-type
/// protocol interface for the NeonCityFPGA platform.
/// This protocol's interface has a function at offset 0x10 (16) that registers
/// the setup configuration data.
/// {E03E0D46-5263-4845-B0A4-58D57B3177E2}
///
#define UBA_NEONCITYFPGA_BOARD_TYPE_PROTOCOL_GUID \
{ 0xE03E0D46, 0x5263, 0x4845, { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }
///
/// UBA_NEONCITYFPGA_SETUP_CONFIG_PROTOCOL_GUID
/// Protocol GUID that is registered by this driver during its entry point.
/// This protocol is installed via the board-type protocol's registration
/// function and represents the setup configuration for NeonCityFPGA.
/// {CD1F9574-DD03-4196-96AD-4965146F9665}
///
#define UBA_NEONCITYFPGA_SETUP_CONFIG_PROTOCOL_GUID \
{ 0xCD1F9574, 0xDD03, 0x4196, { 0x96, 0xAD, 0x49, 0x65, 0x14, 0x6F, 0x96, 0x65 } }
// ============================================================================
// Structure Definitions
// ===========================================================================/
///
/// UBA_SETUP_CONFIG_DATA
/// Structure passed to the UBA board-type protocol to register the setup
/// configuration data for the NeonCityFPGA platform.
///
/// The signature is "PSET" (little-endian: 'P','S','E','T'), which is "SETP"
/// in big-endian -- an encoding of "SETUP" with the last character dropped.
///
typedef struct {
///
/// Signature = "PSET" (0x54455350 in little-endian).
///
UINT32 Signature;
///
/// Version of this structure. Currently = 1.
///
UINT32 Version;
///
/// Total size of the setup configuration data blob. Size = 0x48c (1164) bytes.
///
UINT64 Size;
///
/// Additional size field (duplicate of Size for alignment/padding).
///
UINT64 SizeDuplicate;
} UBA_SETUP_CONFIG_DATA;
///
/// UBA_SETUP_CONFIG_FIXED_SIZE
/// The fixed size of the configuration data associated with this module.
///
#define UBA_SETUP_CONFIG_FIXED_SIZE 0x48c
///
/// UBA_SETUP_CONFIG_VERSION
/// Current version of the UBA setup config structure.
///
#define UBA_SETUP_CONFIG_VERSION 0x1
///
/// CMOS debug level register. Port 0x70 selects the CMOS register;
/// port 0x71 reads/writes the value.
/// Register 0x4B is used for 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).
///
#define BOARD_CONFIG_MMIO_ADDR 0xFDAF0490ULL
///
/// Debug message severity mask. Used with the DebugLib protocol.
///
#define DEBUG_INFO 0x80000000
// ============================================================================
// 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;
// ============================================================================
// Function Declarations
// ===========================================================================/
/**
* Module entry point for RomLayoutDxe.
*
* Initializes UEFI global variables (gImageHandle, gST, gBS, gRT), locates the
* HOB list via sub_5E0(), prints a debug banner via sub_518(), locates the UBA
* NeonCityFPGA board-type protocol, and registers the setup configuration data
* 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 The protocol was successfully registered.
* @return Other The protocol could not be located or registered.
*/
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
* 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 qword_BC0 (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
);
/**
* Debug print function (wraps the UEFI DebugLib protocol).
*
* Resolves the DebugLib protocol interface via the UEFI Boot Services table
* and calls its output function if the debug level determined by CMOS register
* 0x4B matches the requested severity mask.
*
* @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
* 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
);
/**
* 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_NEONCITYFPGA_BOARD_TYPE_PROTOCOL
///
/// The protocol interface obtained via gBS->LocateProtocol() using the GUID
/// UBA_NEONCITYFPGA_BOARD_TYPE_PROTOCOL_GUID.
///
/// This protocol is used to register platform-specific setup configuration
/// data. 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 the setup configuration data.
///
/// @param[in] This Pointer to the UBA board-type protocol interface.
/// @param[in] ProtocolGuid GUID of the protocol to register
/// (UBA_NEONCITYFPGA_SETUP_CONFIG_PROTOCOL_GUID).
/// @param[in] ConfigData Pointer to the UBA_SETUP_CONFIG_DATA structure.
/// @param[in] ConfigDataSize Size of the configuration data structure in bytes.
///
/// @return EFI_STATUS.
///
EFI_STATUS
(EFIAPI *RegisterSetupConfig) (
IN VOID *This,
IN EFI_GUID *ProtocolGuid,
IN UBA_SETUP_CONFIG_DATA *ConfigData,
IN UINT64 ConfigDataSize
);
} UBA_NEONCITYFPGA_BOARD_TYPE_PROTOCOL;
#endif /* _ROM_LAYOUT_DXE_H_ */