/**
* @file StaticSkuDataDxeNeonCityFPGA.h
*
* @brief Header for StaticSkuDataDxeNeonCityFPGA - UEFI DXE driver that
* installs platform-specific SKU configuration data (UMPT, PIRQ, ACPF)
* into ACPI configuration tables for the NeonCity FPGA platform.
*
* This driver is part of the Lenovo UBA (Universal BIOS Architecture).
* Build path: e:\hs\Build\HR6N0XMLK\DEBUG_VS2015\X64\PurleyRpPkg\Uba\UbaMain\Dxe\TypeNeonCityFPGA\StaticSkuDataDxe\DEBUG\StaticSkuDataDxeNeonCityFPGA.pdb
*
* The driver reads the platform type from RTC CMOS register 0x4B,
* locates a platform-specific ACPI configuration protocol via GUID
* {E03E0D46-5263-4845-B0A4-58D57B3177E2}, and installs three
* configuration tables:
* - UMPT (Ubox/Memory/Platform topology table)
* - PIRQ (PCI IRQ routing table)
* - ACPF (ACPI Platform SKU configuration data)
*/
#ifndef STATIC_SKU_DATA_DXE_NEON_CITY_FPGA_H
#define STATIC_SKU_DATA_DXE_NEON_CITY_FPGA_H
#include "../uefi_headers/Uefi.h"
/*============================================================================
* GUID Definitions
*============================================================================*/
///
/// Protocol GUID used in gBS->LocateProtocol() to obtain the ACPI
/// configuration interface at offset 0x10.
/// This is a platform-specific protocol (likely Lenovo UBA or custom ACPI
/// table protocol), NOT the standard EFI_ACPI_TABLE_PROTOCOL.
///
#define STATIC_SKU_DATA_PROTOCOL_GUID \
{ 0xE03E0D46, 0x5263, 0x4845, { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }
///
/// GUIDs used as ACPI table keys for InstallConfigurationTable:
///
/// 1. UMPT table -- installed with 24 bytes of data
/// Key GUID: {0FF8A1CF-A0AB-4AC0-BFC9-34A78F68DD8A}
/// Data GUID: (same GUID used for both key and data in this call)
///
#define UMPT_TABLE_GUID \
{ 0x0FF8A1CF, 0xA0AB, 0x4AC0, { 0xBF, 0xC9, 0x34, 0xA7, 0x8F, 0x68, 0xDD, 0x8A } }
///
/// 2. PIRQ table -- installed with 16 bytes of data
/// Key GUID: {4C1F48A5-C976-4D90-9F03-8E9B1C327FCF}
/// Data GUID: PIRQ_VAR_GUID (tag "PIRQ" in the data)
///
#define PIRQ_TABLE_GUID \
{ 0x4C1F48A5, 0xC976, 0x4D90, { 0x9F, 0x03, 0x8E, 0x9B, 0x1C, 0x32, 0x7F, 0xCF } }
///
/// 3. ACPF table -- installed with 16 bytes of data
/// Key GUID: {81129EF8-391D-4F63-AE99-58517EC077E3}
/// Data GUID: ACPF_VAR_GUID (tag "ACPF" in the data)
///
#define ACPF_TABLE_GUID \
{ 0x81129EF8, 0x391D, 0x4F63, { 0xAE, 0x99, 0x58, 0x51, 0x7E, 0xC0, 0x77, 0xE3 } }
///
/// HOB list GUID (gEfiDxeServicesTableGuid is the standard UEFI name,
/// but this is actually the HOB list pointer GUID)
/// {7739F24C-93D7-11D4-9A3A-0090273FC14D}
///
#define HOB_LIST_GUID \
{ 0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
///
/// SKU data identifier GUID at the start of the .data section
/// {36232936-0E76-31C8-A13A-3AF2FC1C3932}
///
#define SKU_DATA_IDENTIFIER_GUID \
{ 0x36232936, 0x0E76, 0x31C8, { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }
/*============================================================================
* Data Structure Definitions
*============================================================================*/
///
/// Header for each configuration variable block installed into ACPI tables.
/// Each variable block has a 4-byte ASCII tag, a version field, and
/// a pointer to the actual data.
///
#pragma pack(push, 1)
typedef struct {
UINT32 Signature; ///< 4-byte ASCII tag: "UMPT", "PIRQ", or "ACPF"
UINT32 Version; ///< Version number (always 1 in this driver)
UINT64 DataPointer; ///< Absolute address of the actual configuration data
} SKU_VAR_HEADER;
#pragma pack(pop)
///
/// UMPT header has an extended format (24 bytes total):
/// - 8 bytes SKU_VAR_HEADER (Sig + Ver + DataPtr)
/// - 8 bytes next data pointer (points to PIRQ data at 0x90B8)
/// - 8 bytes: table GUID suffix
///
#pragma pack(push, 1)
typedef struct {
SKU_VAR_HEADER Header; ///< "UMPT", version=1, data_ptr=0x9040
UINT64 NextPtr; ///< Pointer to next var block (0x9020 -> PIRQ data region)
UINT64 TableGUIDLow; ///< Low 8 bytes of PIRQ_TABLE_GUID Data2|Data1
} UMPT_VAR_BLOCK;
#pragma pack(pop)
///
/// UMPT configuration data entry (at 0x9020).
/// Each entry pairs a memory/address value with a count.
///
#pragma pack(push, 1)
typedef struct {
UINT64 BaseAddress; ///< Memory base address or resource base
UINT32 Count; ///< Count of items or size in bytes
UINT32 Reserved; ///< Reserved / padding
} UMPT_DATA_ENTRY;
#pragma pack(pop)
///
/// PIRQ configuration data entry (at 0x90F0+).
/// Describes IOAPIC and GSI routing.
///
#pragma pack(push, 1)
typedef struct {
UINT64 IoApicId; ///< IOAPIC identifier
UINT64 GsiBase; ///< Global System Interrupt base
UINT64 OverrideFlags;///< Interrupt source override flags
} PIRQ_DATA_ENTRY;
#pragma pack(pop)
///
/// PIRQ header (at 0x90B8):
/// Each entry contains a pointer + count for data arrays.
///
#pragma pack(push, 1)
typedef struct {
UINT64 DataPointer; ///< Pointer to PIRQ entry data
UINT32 Count; ///< Number of entries
UINT32 Reserved; ///< Reserved
} PIRQ_DATA_HEADER;
#pragma pack(pop)
///
/// Main SKU configuration table entry (at 0x40E0+).
/// There are 632 entries, each 0x20 (32) bytes.
///
#pragma pack(push, 1)
typedef struct {
UINT64 StringOffset; ///< Absolute address of the identifying string in .rdata
///< e.g. 0x7BC = "PSYS", 0x7C8 = "_SB_.CCT0"
UINT32 GroupId; ///< Group identifier:
///< 0x00005B80 - CCT/CFH/PSYS entries
///< 0x00000008 - NVDR entries
///< 0x00000011 - FIX8/FIXA entries (PCI root bridge resources)
UINT32 RdataStringOffset; ///< Offset in .rdata section of the ACPI path string
///< e.g. 0x0954 = "_SB_.NVDR.N000.FXBS" (for PSYS root)
///< For CCT/CFH entries, this is a secondary reference
UINT32 EntryType; ///< Entry type:
///< 0x0000000C - Group root / namespace root
///< 0x0000000E - Child entry with ACPI path
///< 0x0000000A - NVDR sub-function descriptor
///< 0x00000087/0x88/0x8A - PCI resource entries (FIX8/FIXA)
UINT32 Reserved; ///< Reserved field
CHAR8 Name[8]; ///< 8-byte entry name (e.g. "FIX0", "FIXX\1", "FIXV\2", etc.)
///< Bytes 4-7 encode sub-index and flags
} SKU_CONFIG_ENTRY;
#pragma pack(pop)
/*============================================================================
* Function Declarations
*============================================================================*/
/**
* @brief UEFI DXE driver entry point.
*
* Standard UEFI entry point. Called by DxeCore during driver dispatch.
* Caches ImageHandle, SystemTable, BootServices, RuntimeServices.
* Locates the HOB list, then queries for a platform-specific ACPI
* configuration protocol. Installs three configuration tables:
* UMPT (Ubox topology), PIRQ (PCI IRQ routing), and ACPF (SKU data).
*
* @param[in] ImageHandle The firmware-allocated handle for this driver image.
* @param[in] SystemTable Pointer to the UEFI system table.
* @return EFI_SUCCESS The driver initialized successfully.
* @return Other Error from LocateProtocol or InstallConfigurationTable.
*/
EFI_STATUS
EFIAPI
StaticSkuDataDxeEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
* @brief Locate and cache the HOB list pointer.
*
* Searches SystemTable->ConfigurationTable for the HOB list GUID
* ({7739F24C-93D7-11D4-9A3A-0090273FC14D}). The HOB list is required
* for locating DXE services during initialization.
*
* @param[in] ImageHandle Unused in this context (passed from entry point).
* @return Pointer to the first HOB in the HOB list, or NULL if not found.
*/
VOID *
GetHobList (
IN EFI_HANDLE ImageHandle
);
/**
* @brief Compare two 64-bit values (used for GUID comparison).
*
* Reads a UINT64 from the given address and compares it against
* a reference value. Used by GetHobList to match GUIDs in the
* configuration table.
*
* @param[in] Reference Address of reference GUID (e.g. &unk_4080 = HOB_LIST_GUID).
* @param[in] Target Address of configuration table entry to compare.
* @return TRUE if the two 64-bit values match.
* @return FALSE if they differ.
*/
BOOLEAN
IsHobGuidMatch (
IN UINT64 *Reference,
IN UINT64 *Target
);
/**
* @brief Unaligned 64-bit read with NULL-check assertion.
*
* Wrapper for BaseLib ReadUnaligned64. Asserts if Buffer is NULL.
*
* @param[in] Buffer Pointer to read from (may be unaligned).
* @return The 64-bit value at Buffer.
*/
UINT64
ReadUnaligned64 (
IN CONST VOID *Buffer
);
/**
* @brief Platform-specific debug/output function.
*
* Reads the platform type from RTC CMOS register 0x4B. Based on the
* platform type value, routes debug output through the platform protocol.
*
* @param[in] DebugLevel Debug level / routing selector (0x80000000 for error).
* @param[in] FormatString printf-style format string.
* @param[in] ... Variable arguments for format string.
* @return TRUE if the message was routed.
*/
BOOLEAN
PlatformDebugPrint (
IN UINT64 DebugLevel,
IN CONST CHAR8 *FormatString,
...
);
/**
* @brief Lazy-initialized platform protocol interface getter.
*
* On first call, allocates a test pool buffer of 31 bytes to verify
* that gBS->AllocatePool is functional (checks for pool <= 0x10 as
* a guard). Then locates the platform protocol via gBS->LocateProtocol.
* The result is cached globally.
*
* @return Pointer to the platform protocol interface, or NULL on failure.
*/
VOID *
GetPlatformProtocol (
VOID
);
/**
* @brief Assert handler for debug builds.
*
* Forwards assertion information to the platform protocol's
* assert function (function offset 0x08 in the protocol interface).
*
* @param[in] FileName Source file name string.
* @param[in] LineNumber Line number in source file.
* @param[in] AssertString Assertion expression string.
*/
VOID
PlatformAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *AssertString
);
/*============================================================================
* Global Variable Declarations
*============================================================================*/
///
/// Cached EFI_HANDLE from the entry point.
///
extern EFI_HANDLE gImageHandle;
///
/// Cached EFI_SYSTEM_TABLE pointer.
///
extern EFI_SYSTEM_TABLE *gSystemTable;
///
/// Cached EFI_BOOT_SERVICES pointer (offset 0x60 from SystemTable).
///
extern EFI_BOOT_SERVICES *gBootServices;
///
/// Cached EFI_RUNTIME_SERVICES pointer (offset 0x58 from SystemTable).
///
extern EFI_RUNTIME_SERVICES *gRuntimeServices;
///
/// Cached platform protocol interface pointer (lazy initialized).
///
extern VOID *gPlatformProtocol;
///
/// Cached HOB list pointer (lazy initialized).
///
extern VOID *gHobList;
/*============================================================================
* Platform Protocol Interface Layout (Inferred)
*
* This protocol is obtained via LocateProtocol with GUID
* {E03E0D46-5263-4845-B0A4-58D57B3177E2}.
*
* Offset 0x00: Reserved / Version
* Offset 0x08: Assert (function 1) - VOID (*)(CHAR8 *File, UINTN Line, CHAR8 *Msg)
* Offset 0x10: InstallConfigurationTable (function 2) - EFI_STATUS (*)(GUID *Key, VOID *Data, UINTN Size)
*============================================================================*/
#endif /* STATIC_SKU_DATA_DXE_NEON_CITY_FPGA_H */