/** @file
OpromUpdateDxeNeonCityFPGA - UEFI DXE driver header.
Unified Board Architecture (UBA) driver for the NeonCityFPGA platform.
Provides Option ROM (OpROM) update configuration by registering PCIe slot
data with the UBA board protocol. The driver identifies the ROM layout,
locates the HOB list from the system configuration table, resolves the
UBA board-type protocol, and registers slot configuration function callbacks.
Copyright (c) Lenovo. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef OPCROM_UPDATE_DXE_NEON_CITY_FPGA_H_
#define OPCROM_UPDATE_DXE_NEON_CITY_FPGA_H_
#include "../uefi_headers/Uefi.h"
///
/// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL GUID
/// {BB7E702F-1A4A-11D4-9A38-0090273FC14D}
///
#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \
{ 0x2F707EBB, 0x4A1A, 0x11D4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
///
/// DebugLib Protocol GUID (EDK2 DebugLib protocol)
/// {36232936-0E76-31C8-A13A-3AF2FC1C3932}
///
#define DEBUG_LIB_PROTOCOL_GUID \
{ 0x36232936, 0x0E76, 0x31C8, { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }
///
/// UBA NeonCityFPGA Board-Type Protocol GUID
/// {E03E0D46-5263-4845-B0A4-58D57B3177E2}
///
#define UBA_NEONCITY_FPGA_BOARD_TYPE_PROTOCOL_GUID \
{ 0xE03E0D46, 0x5263, 0x4845, { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }
///
/// EFI_HOB_LIST_GUID
/// {7739F24C-93D7-11D4-9A3A-0090273FC14D}
///
#define EFI_HOB_LIST_GUID \
{ 0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
///
/// OpROM update configuration GUID for NeonCityFPGA
/// {371BD79C-DE79-4C5F-AA2B-BC9EBEFA988F}
///
#define OPCROM_UPDATE_CONFIG_GUID \
{ 0x9CD71B37, 0x79DE, 0x4C5F, { 0xAA, 0x2B, 0xBC, 0x9E, 0xBE, 0xFA, 0x98, 0x8F } }
///
/// CMOS RTC I/O ports
///
#define RTC_INDEX_PORT 0x70
#define RTC_DATA_PORT 0x71
#define RTC_INDEX_DEBUG_LEVEL 0x4B
///
/// Debug level / error severity mask
/// Used with DebugPrint to control output verbosity
///
#define DEBUG_ERROR_MASK 0x80000000
///
/// Maximum number of PCIe slots (PCI bus/device/function combinations)
/// tested by the slot checker callback
///
#define PCIE_SLOT_CHECK_BIT_COUNT 8
///
/// Number of entries in the first slot configuration table (at 0xD40)
///
#define PCIE_SLOT_TABLE_1_COUNT 6
///
/// Number of entries in the second slot configuration table (at 0xE40)
///
#define PCIE_SLOT_TABLE_2_COUNT 10
///
/// Size of each slot table entry: 40 bytes (0x28)
///
#define PCIE_SLOT_TABLE_ENTRY_SIZE 40
///
/// UBA OpROM Update Configuration Table signature ("PBDS")
///
#define UBA_OPROM_UPDATE_CONFIG_SIGNATURE 0x53444250 ///< "PBDS" in little-endian
///
/// Size of the UBA OpROM Update configuration table passed to RegisterOpromUpdate
/// 4 (Signature) + 4 (Version) + 5 * 8 (Function pointers) = 48
///
#define UBA_OPROM_UPDATE_CONFIG_SIZE 48
///
/// UBA OpROM Update Configuration Table structure
/// This structure is packed into .rdata at offset 0xEB8.
/// It contains function callback pointers registered with the UBA protocol.
///
#pragma pack(push, 1)
typedef struct {
///
/// Signature "PBDS" (0x53444250)
///
UINT32 Signature;
///
/// Version (1)
///
UINT32 Version;
///
/// Function pointer 0: PcieSlotChecker
/// Checks whether a given PCIe bus/dev/func corresponds to a configured slot.
/// Signature: BOOLEAN (EFIAPI *)(UINT64 PcieAddress, UINT32 SlotBitmap)
///
UINT64 PcieSlotChecker;
///
/// Function pointer 1: GetPcieSlotProtocol
/// Returns a pointer to a slot configuration protocol/structure.
/// Signature: UINT64 (EFIAPI *)(VOID **Protocol)
///
UINT64 GetPcieSlotProtocol;
///
/// Function pointer 2: GetPcieSlotTable1
/// Returns the first PCIe slot configuration table (6 entries at 0xD40).
/// Signature: UINT64 (EFIAPI *)(VOID **Table, UINTN *Count)
///
UINT64 GetPcieSlotTable1;
///
/// Function pointer 3: GetPcieSlotTable2
/// Returns the second PCIe slot configuration table (10 entries at 0xE40).
/// Signature: UINT64 (EFIAPI *)(VOID **Table, UINTN *Count)
///
UINT64 GetPcieSlotTable2;
///
/// Function pointer 4: SetPcieSlotNumberCallback
/// Sets the PCIe slot number for a given slot.
/// Signature: UINT64 (EFIAPI *)(UINT8 *SlotNumber)
///
UINT64 SetPcieSlotNumberCallback;
} UBA_OPROM_UPDATE_CONFIG;
#pragma pack(pop)
///
/// UBA NeonCityFPGA Board Protocol Interface Structure
/// Located dynamically via gBS->LocateProtocol().
///
#pragma pack(push, 1)
typedef struct {
///
/// Offset 0x00: Unknown field (revision/flags)
///
UINT64 Revision;
///
/// Offset 0x08: Unknown field (reserved)
///
UINT64 Reserved;
///
/// Offset 0x10: RegisterOpromUpdate function
/// Registers OpROM update configuration callbacks with the UBA board protocol.
///
/// EFI_STATUS (EFIAPI *RegisterOpromUpdate)(
/// IN UBA_NEONCITY_BOARD_PROTOCOL *This,
/// IN EFI_GUID *ConfigGuid, ///< GUID identifying the config
/// IN UBA_OPROM_UPDATE_CONFIG *ConfigData, ///< Function callback table
/// IN UINTN ConfigDataSize ///< Size of config data (48)
/// );
///
UINT64 RegisterOpromUpdate;
} UBA_NEONCITY_BOARD_PROTOCOL;
#pragma pack(pop)
///
/// Debug Library Protocol Interface Structure
///
#pragma pack(push, 1)
typedef struct {
///
/// Offset 0x00: DebugPrint function
///
UINT64 DebugPrint;
///
/// Offset 0x08: DebugAssert function
///
UINT64 DebugAssert;
} DEBUG_LIB_PROTOCOL;
#pragma pack(pop)
///
/// PCIe slot bit configuration entry (4 bytes each, 8 entries at 0xEF1)
/// Used by PcieSlotChecker to determine which PCIe addresses correspond
/// to physical slots on the NeonCityFPGA platform.
///
#pragma pack(push, 1)
typedef struct {
UINT8 Bus; ///< PCI bus number
UINT8 Device; ///< PCI device number
UINT8 Function; ///< PCI function number
UINT8 SlotBit; ///< Slot bit position in the bitmap
} PCIE_SLOT_BIT_CONFIG;
#pragma pack(pop)
///
/// PCIe slot table entry structure (40 bytes each)
/// Defines a single PCIe slot configuration.
///
#pragma pack(push, 1)
typedef struct {
UINT32 Flags; ///< +0x00: Slot flags/enable bits
UINT32 VendorDeviceId; ///< +0x04: Vendor/device ID encoding (0x00020001 style)
UINT32 VendorDeviceIdHi; ///< +0x08: High part of PCI vendor/device ID (e.g., 0x15288086 = Intel 0x8086 0x1528)
UINT32 BusDeviceFunction; ///< +0x0C: BDF encoding (e.g., 0x48010802)
UINT32 SegmentBus; ///< +0x10: PCI segment group number / bus
UINT32 SegmentBusHi; ///< +0x14: High part of segment/bus
UINT32 Reserved1; ///< +0x18
UINT32 Reserved2; ///< +0x1C
UINT32 Reserved3; ///< +0x20
UINT32 Reserved4; ///< +0x24
} PCIE_SLOT_TABLE_ENTRY;
///
/// System Configuration Table Entry Format
/// Used to scan SystemTable->ConfigurationTable[] for EFI_HOB_LIST_GUID
///
#pragma pack(push, 1)
typedef struct {
EFI_GUID VendorGuid; ///< +0x00: 16-byte GUID
VOID *VendorTable; ///< +0x10: 8-byte pointer
} CONFIG_TABLE_ENTRY; ///< Total: 0x18 (24 bytes)
#pragma pack(pop)
///
/// Global variables
///
extern EFI_HANDLE gImageHandle; ///< @ 0xF20: Driver image handle
extern EFI_SYSTEM_TABLE *gST; ///< @ 0xF10: System table pointer
extern EFI_BOOT_SERVICES *gBS; ///< @ 0xF18: Boot services pointer
extern EFI_RUNTIME_SERVICES *gRT; ///< @ 0xF28: Runtime services pointer
extern VOID *gDebugProtocol; ///< @ 0xF30: Cached DebugLib protocol
extern VOID *gHobList; ///< @ 0xF38: Cached HOB list pointer
#endif // OPCROM_UPDATE_DXE_NEON_CITY_FPGA_H_