/**
* @file UsbOcUpdateDxeNeonCityFPGA.h
*
* @brief UsbOcUpdateDxeNeonCityFPGA - UEFI DXE driver for configuring USB
* over-current (OC) protection settings for the NeonCityFPGA platform.
*
* MODULE TYPE: DXE Driver (Index 0010 in BIOS FFS)
* UEFI PHASE: DXE (Driver Execution Environment)
*
* PURPOSE:
* This driver is part of Lenovo's UBA (Unified Board Architecture) framework.
* It configures USB over-current (OC) protection for the NeonCityFPGA platform
* by:
* 1. Locating the HOB (Hand-Off Block) list from the system configuration table
* via the EFI_HOB_LIST_GUID.
* 2. Printing a debug banner identifying the platform type.
* 3. Locating the UBA board-type protocol via gBS->LocateProtocol().
* 4. Registering USB OC port-to-OC-pin mapping tables via the protocol's
* registration function (at offset 0x10 in the protocol interface).
*
* The USB OC mapping tables define which over-current sense pin corresponds to
* each physical USB port on the motherboard. Two tables are provided:
* - Table 1 (front panel / internal USB ports): 16 UINT32 entries
* - Table 2 (rear panel / backplane USB ports): 16+ UINT32 entries
*
* DEPENDENCIES (Protocols consumed):
* - UBA NeonCityFPGA Board-Type Protocol (GUID: e03e0d46-5263-4845-b0a4-58d57b3177e2)
* Located via gBS->LocateProtocol() to register USB OC config.
* - EFI_HOB_LIST_GUID (7739f24c-93d7-11d4-9a3a-0090273fc14d)
* Used to locate the HOB list from the system configuration table.
* - UEFI Debug Library Protocol (dynamically located for debug output)
*
* DEPENDENCIES (Protocols produced):
* - UBA NeonCityFPGA USB OC Config Protocol
* (GUID: 2638009e-3850-4e4b-b05d-042a32dbb9d1)
* Registered with a "PUSB"-signed UBA_USBOC_CONFIG_DATA interface.
*
* HARDWARE ACCESS:
* - CMOS RTC ports 0x70/0x71: Read debug level setting from CMOS register 0x4B
* - MMIO 0xFDAF0490: Board configuration register (fallback debug level source)
*
* LIBRARY DEPENDENCIES (inlined):
* - UefiBootServicesTableLib (gImageHandle, gST, gBS)
* - UefiRuntimeServicesTableLib (gRT)
* - DxeHobLib (HOB list parsing)
* - BaseLib (unaligned read via ReadUnaligned64)
* - DebugLib (debug output via dynamically-located protocol)
*/
#ifndef _USB_OC_UPDATE_DXE_NEON_CITY_FPGA_H_
#define _USB_OC_UPDATE_DXE_NEON_CITY_FPGA_H_
#include "../uefi_headers/Uefi.h"
// ============================================================================
// GUID Definitions
// ===========================================================================/
///
/// 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:
/// - DebugAssert function at offset +0x08
/// - RegisterUsbOcConfig function at offset +0x10
/// {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_USBOC_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 USB over-current configuration mappings.
/// {2638009E-3850-4E4B-B05D-042A32DBB9D1}
///
#define UBA_NEONCITYFPGA_USBOC_CONFIG_PROTOCOL_GUID \
{ 0x2638009E, 0x3850, 0x4E4B, { 0xB0, 0x5D, 0x04, 0x2A, 0x32, 0xDB, 0xB9, 0xD1 } }
///
/// 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 } }
// ============================================================================
// Structure Definitions
// ===========================================================================/
///
/// UBA_USBOC_CONFIG_DATA
/// Structure registered via the UBA board-type protocol to describe the USB
/// over-current configuration for the NeonCityFPGA platform.
///
/// The signature is "PUSB" (big-endian "BSUP"), representing "USB Port" in
/// reverse, analogous to the "PSET" ("SETP" / "SETUP") signature used by
/// the RomLayoutDxe / SetupConfigUpdateDxe modules.
///
typedef struct {
///
/// Signature = "PUSB" (0x42535550 in little-endian).
///
UINT32 Signature;
///
/// Version of this structure. Currently = 2.
///
UINT32 Version;
///
/// Total size of the USB OC configuration data blob (includes port mapping
/// tables). Size = 0x48c (1164) bytes.
///
UINT64 Size;
///
/// USB OC Port Mapping Table 1: Maps USB port index (0-15) to over-current
/// sense pin number. Each entry is a UINT32 OC pin number.
/// 16 entries, 64 bytes total. Starts immediately after the header.
///
/// Table 1: Front panel / internal USB port OC assignments:
/// Port 0 -> OC 0 (root/always-on port)
/// Port 1 -> OC 1 (internal USB 2.0 header)
/// Port 2 -> OC 1 (internal USB 2.0 header, shared OC)
/// Port 3 -> OC 2
/// Port 4 -> OC 3
/// Port 5 -> OC 3 (shared with port 4)
/// Port 6 -> OC 7
/// Port 7 -> OC 7 (shared with port 6)
/// Port 8 -> OC 6
/// Port 9 -> OC 4
/// Port 10 -> OC 6 (shared with port 8)
/// Port 11 -> OC 4 (shared with port 9)
/// Port 12 -> OC 5
/// Port 13 -> OC 4 (shared with ports 9,11)
/// Port 14 -> OC 8
/// Port 15 -> OC 8 (shared with port 14)
///
UINT32 PortToOcPinUsbPort1[16]; // 64 bytes
///
/// USB OC Port Mapping Table 2: Alternate/expansion panel mapping.
/// Same format as Table 1 (UINT32 per port), 16+ entries.
///
/// Table 2: Rear panel / backplane USB port OC assignments:
/// Port 0 -> OC 0
/// Port 1 -> OC 1
/// Port 2 -> OC 1 (shared)
/// Port 3 -> OC 2
/// Port 4 -> OC 3
/// Port 5 -> OC 3 (shared)
/// Port 6 -> OC 8 (USB 3.0 rear panel)
/// Port 7 -> OC 8 (USB 3.0 rear panel, shared)
/// Port 8 -> OC 8 (USB 3.0 rear panel, shared)
/// Port 9 -> OC 8 (USB 3.0 rear panel, shared)
/// Ports 10-19 -> Packed 0x01020007
/// (OC pin 7, controller instance 1, port type 2)
///
UINT32 PortToOcPinUsbPort2[20]; // 80 bytes
} UBA_USBOC_CONFIG_DATA;
///
/// UBA_USBOC_CONFIG_FIXED_SIZE
/// The fixed size of the configuration data blob for this module.
///
#define UBA_USBOC_CONFIG_FIXED_SIZE 0x48c
///
/// UBA_USBOC_CONFIG_VERSION
/// Current version of the UBA USB OC config structure.
///
#define UBA_USBOC_CONFIG_VERSION 0x2
///
/// CMOS debug level register index. Port 0x70 selects the CMOS register;
/// port 0x71 reads/writes the value.
///
#define CMOS_DEBUG_LEVEL_REGISTER 0x4B
///
/// CMOS index port (RTC address register)
///
#define RTC_INDEX_PORT 0x70
///
/// CMOS data port (RTC data register)
///
#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 (from UefiBootServicesTableLib / UEFI standard)
// ===========================================================================/
//
// 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.
/// Cached in a module-level STATIC variable.
///
extern VOID *gHobList;
// ============================================================================
// Data Section Constants (embedded in the .data segment @ 0xB40)
// ===========================================================================/
///
/// DebugLib protocol GUID (used with gBS->LocateProtocol).
/// @note At .data offset +0x00 (binary address 0xB40).
/// GUID: 36232936-0E76-31C8-A13A-3AF2FC1C3932
///
#define DEBUGLIB_PROTOCOL_GUID \
{ 0x36232936, 0x0E76, 0x31C8, { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }
///
/// UBA board-type protocol GUID (used with gBS->LocateProtocol).
/// @note At .data offset +0x10 (binary address 0xB50).
/// GUID: E03E0D46-5263-4845-B0A4-58D57B3177E2
///
#define UBA_BOARD_TYPE_PROTOCOL_GUID \
{ 0xE03E0D46, 0x5263, 0x4845, { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }
///
/// USB OC config protocol GUID (protocol to register during entry).
/// @note At .data offset +0x20 (binary address 0xB60).
/// GUID: 2638009E-3850-4E4B-B05D-042A32DBB9D1
///
#define USBOC_CONFIG_PROTOCOL_GUID \
{ 0x2638009E, 0x3850, 0x4E4B, { 0xB0, 0x5D, 0x04, 0x2A, 0x32, 0xDB, 0xB9, 0xD1 } }
///
/// EFI_HOB_LIST_GUID (used to identify the HOB list in the config table).
/// @note At .data offset +0x30 (binary address 0xB70).
/// GUID: 7739F24C-93D7-11D4-9A3A-0090273FC14D
///
#define HOB_LIST_GUID \
{ 0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
// ============================================================================
// Function Declarations
// ===========================================================================/
/**
* Module entry point for UsbOcUpdateDxeNeonCityFPGA.
*
* Initializes UEFI global variables (gImageHandle, gST, gBS, gRT), locates the
* HOB list via GetHobList(), prints a debug banner, locates the UBA
* NeonCityFPGA board-type protocol, and registers USB OC configuration data
* by calling the protocol's RegisterUsbOcConfig 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 USB OC config was successfully registered.
* @return Other The UBA board-type protocol could not be located.
*/
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. Uses IsHobListGuid() for
* the comparison.
*
* Results are cached in the global mHobList (qword_C58).
*
* @param[in] ImageHandle The driver image handle (passed through from entry,
* may be unused in loop).
*
* @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 the first 8 bytes
* and second 8 bytes independently as 64-bit integers.
*
* Uses ReadUnaligned64() to read the GUID halves.
*
* @param[in] ImageHandle Unused parameter (passed for signature compatibility).
* @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 GetDebugProtocol() and calls
* its output function if the debug level determined by the 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 DebugPrint function,
* or 0 if the protocol is not available or the level is masked out.
*/
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 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 Result from the DebugLib protocol's DebugAssert function,
* or 0 if the protocol is not available.
*/
UINTN
DebugAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
);
/**
* 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 USB OC configuration
/// data. The registration function is at offset 0x10 within the interface
/// structure. An assertion handler is at offset 0x08.
///
typedef struct {
///
/// Reserved / unknown fields at offsets 0x00-0x07 (protocol revision/flags).
///
UINT64 Reserved0;
///
/// DebugAssert function at offset 0x08.
/// Called by DebugAssert() when an assertion fails.
///
/// @param[in] FileName Source file name.
/// @param[in] LineNumber Line number of the assertion.
/// @param[in] Description Assertion description string.
///
/// @return UINTN result.
///
UINTN
(EFIAPI *DebugAssert) (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
);
///
/// RegisterUsbOcConfig function at offset 0x10.
/// Registers the USB over-current configuration data.
///
/// @param[in] This Pointer to the UBA board-type protocol interface.
/// @param[in] ProtocolGuid GUID of the protocol to register
/// (UBA_NEONCITYFPGA_USBOC_CONFIG_PROTOCOL_GUID).
/// @param[in] ConfigData Pointer to the UBA_USBOC_CONFIG_DATA structure
/// containing the port-to-OC-pin mapping tables.
/// @param[in] ConfigDataSize Size of the configuration data structure in bytes.
///
/// @return EFI_STATUS.
///
EFI_STATUS
(EFIAPI *RegisterUsbOcConfig) (
IN VOID *This,
IN EFI_GUID *ProtocolGuid,
IN UBA_USBOC_CONFIG_DATA *ConfigData,
IN UINT64 ConfigDataSize
);
} UBA_NEONCITYFPGA_BOARD_TYPE_PROTOCOL;
///
/// DEBUGLIB_PROTOCOL
///
/// The DebugLib protocol interface obtained by GetDebugProtocol() via
/// gBS->LocateProtocol(). Provides DebugPrint and DebugAssert services
/// without linking to a static DebugLib implementation.
///
typedef struct {
///
/// DebugPrint function at offset 0x00.
///
/// @param[in] ErrorLevel Debug error level / severity mask.
/// @param[in] Format Format string.
/// @param[in] VaList Variable argument list.
///
/// @return UINTN result.
///
UINTN
(EFIAPI *DebugPrint) (
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
IN VA_LIST VaList
);
///
/// DebugAssert function at offset 0x08.
///
/// @param[in] FileName Source file name.
/// @param[in] LineNumber Line number.
/// @param[in] Description Assertion description.
///
/// @return UINTN result.
///
UINTN
(EFIAPI *DebugAssert) (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
);
} DEBUGLIB_PROTOCOL;
#endif /* _USB_OC_UPDATE_DXE_NEON_CITY_FPGA_H_ */