Newer
Older
AMI-Aptio-BIOS-Reversed / UsbOcUpdateDxeLightningRidgeEXECB1 / UsbOcUpdateDxeLightningRidgeEXECB1.h
@Ajax Dong Ajax Dong 2 days ago 15 KB Init
/**
 * @file UsbOcUpdateDxeLightningRidgeEXECB1.h
 *
 * @brief UsbOcUpdateDxeLightningRidgeEXECB1 - UEFI DXE driver for USB over-current
 *        (OC) protection configuration on the LightningRidgeEXECB1 platform.
 *
 * MODULE TYPE: DXE Driver (Index 0021 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 protection settings for the LightningRidgeEXECB1
 *   platform. At entry it:
 *     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 the UBA board-type protocol via gBS->LocateProtocol().
 *     3. Registers USB OC configuration data via the protocol's registration
 *        function, passing a UBA_USBOC_CONFIG_DATA structure (signature "PUSB",
 *        version 2, 0x48C bytes total config size).
 *     4. Provides debug output via the EDK2 DebugLib protocol obtained through
 *        gBS->LocateProtocol().
 *
 * This module is analogous to UsbOcUpdateDxeLightningRidgeEXRP, but for the
 * EXECB1 platform variant. The ECB1 variant has a different USB port layout
 * (3 port mapping entries instead of 4).
 *
 * DEPENDENCIES (Protocols consumed):
 *   - UBA Board-Type Protocol (GUID: e03e0d46-5263-4845-b0a4-58d57b3177e2)
 *     Shared protocol across all UBA platform variants. Located to register
 *     the USB OC configuration.
 *   - EFI_HOB_LIST_GUID (7739f24c-93d7-11d4-9a3a-0090273fc14d)
 *     Used to locate the HOB list from the system configuration table.
 *   - EDK2 Debug Library Protocol (GUID: 36232936-0e76-31c8-a13a-3af2fc1c3932)
 *     Used for debug output and assertion handling. Obtained lazily via
 *     gBS->LocateProtocol().
 *
 * DEPENDENCIES (Protocols produced):
 *   - UBA LightningRidgeEXECB1 USB OC Config Protocol
 *     (GUID: 2638009e-3850-4e4b-b05d-042a32dbb9d1)
 *     Registered with a UBA_USBOC_CONFIG_DATA interface.
 *
 * HARDWARE ACCESS:
 *   - CMOS ports 0x70/0x71: Read debug level setting mask from CMOS register 0x4B
 *   - MMIO 0xFDAF0490: Board configuration register (fallback debug level source)
 *
 * LIBRARY DEPENDENCIES:
 *   - UefiBootServicesTableLib (gImageHandle, gST, gBS)
 *   - UefiRuntimeServicesTableLib (gRT)
 *   - DxeHobLib (HOB list parsing)
 *   - BaseLib (unaligned read: ReadUnaligned64)
 *   - DebugLib (DEBUG macro via CmosDebugLevelProvider)
 */

#ifndef _USB_OC_UPDATE_DXE_LIGHTNINGRIDGE_EXECB1_H_
#define _USB_OC_UPDATE_DXE_LIGHTNINGRIDGE_EXECB1_H_

#include "../uefi_headers/Uefi.h"

// ============================================================================
// GUID Definitions
// ===========================================================================/

///
/// GUID used to locate the DebugLib protocol via gBS->LocateProtocol().
/// This is an EDK2-internal protocol, not part of the UEFI specification.
/// {36232936-0E76-31C8-A13A-3AF2FC1C3932}
///
#define EFI_DEBUG_LIB_PROTOCOL_GUID \
  { 0x36232936, 0x0E76, 0x31C8, { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }

///
/// 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 GUID shared across all UBA platform
/// variants (NeonCityFPGA, LightningRidgeEXRP, LightningRidgeEXECB1, etc.).
/// The platform differentiation is done through the config data content,
/// not the protocol GUID.
/// {E03E0D46-5263-4845-B0A4-58D57B3177E2}
///
#define UBA_BOARD_TYPE_PROTOCOL_GUID \
  { 0xE03E0D46, 0x5263, 0x4845, { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }

///
/// UBA_LIGHTNINGRIDGEEXECB1_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 OC configuration for LightningRidgeEXECB1.
/// {2638009E-3850-4E4B-B05D-042A32DBB9D1}
///
/// NOTE: This GUID is the SAME across all LightningRidge USB OC update variants
/// (EXRP, EXECB1, EXECB2), meaning only one variant can be active at runtime.
///
#define UBA_LIGHTNINGRIDGEEXECB1_USBOC_CONFIG_PROTOCOL_GUID \
  { 0x2638009E, 0x3850, 0x4E4B, { 0xB0, 0x5D, 0x04, 0x2A, 0x32, 0xDB, 0xB9, 0xD1 } }

// ============================================================================
// Structure Definitions
// ===========================================================================/

///
/// UBA_USBOC_CONFIG_DATA
/// Structure passed to the UBA board-type protocol to register the USB
/// over-current configuration data for the LightningRidgeEXECB1 platform.
///
/// The signature is "PUSB" (little-endian: 'P','U','S','B'), which is "BSUP"
/// in big-endian -- likely derived from "USB Port" or similar naming.
///
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. Size = 0x48C (1164) bytes.
  ///
  UINT64    Size;
} UBA_USBOC_CONFIG_DATA;

///
/// UBA_USBOC_PORT_MAP_ENTRY
/// Structure describing one USB port's over-current (OC) mapping.
/// These entries define how USB ports relate to OC sense pins on the
/// LightningRidgeEXECB1 platform's USB controller.
///
/// The module has 3 entries in its port mapping table at 0xBA0-0xBD0
/// (vs. 4 entries in the EXRP variant).
///
typedef struct {
  ///
  /// Offset within the USB controller's register space for this port's
  /// OC configuration.
  ///
  UINT32    ControllerOffset;
  ///
  /// USB port number (1-based or hardware port index).
  ///
  UINT32    UsbPortNumber;
  ///
  /// OC sense pin number or bitmask used to detect over-current conditions
  /// on this port.
  ///
  UINT32    OcPinNumber;
  ///
  /// Configuration flags for this port entry. Semantics are platform-specific.
  ///
  UINT32    Flags;
} UBA_USBOC_PORT_MAP_ENTRY;

///
/// Number of USB OC port mapping entries in the static configuration.
/// ECB1 has 3 entries vs. EXRP's 4.
///
#define USB_OC_PORT_MAP_ENTRY_COUNT  3

///
/// UBA_USBOC_CONFIG_FIXED_SIZE
/// The fixed size of the configuration data associated with this module
/// (matching the "PUSB" header's Size field).
///
#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. 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

///
/// EFI_NOT_FOUND error status code.
/// Used for debug level comparison and ASSERT_EFI_ERROR output.
///
#define EFI_NOT_FOUND                ((EFI_STATUS)(14ULL << 63))

// ============================================================================
// 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 (cached at qword_C78).
///
extern VOID               *gHobList;

// ============================================================================
// Function Declarations
// ===========================================================================/

/**
 * Module entry point for UsbOcUpdateDxeLightningRidgeEXECB1.
 *
 * 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 the USB OC configuration data
 * by calling the protocol's registration function at offset +0x10.
 *
 * @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 protocol was registered.
 * @return Other           Returned directly from LocateProtocol if the UBA
 *                         board-type protocol is not available.
 */
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  );

/**
 * Provides USB OC configuration data pointer set.
 *
 * NOTE: This function has no callers in this module (it is dead code).
 * It returns pointers to the three USB OC configuration data blocks:
 *   - &mUsbOcPortMap (0xBA0): USB OC port mapping table (3 entries)
 *   - &mUsbOcConfigData (0xBF0): Additional USB OC configuration data
 *   - &mUsbOcPortDesc (0xC18): USB OC port descriptor array
 *
 * May be intended as a callback or for external use via a function pointer.
 *
 * @param[out] a1  Pointer to receive address of USB OC port mapping table.
 * @param[out] a2  Pointer to receive address of USB OC config data.
 * @param[out] a3  Pointer to receive address of USB OC descriptor array.
 *
 * @return 0 (EFI_SUCCESS).
 */
UINTN
UsbOcGetConfig (
  OUT VOID  **a1,
  OUT VOID  **a2,
  OUT VOID  **a3
  );

/**
 * 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 via ReadUnaligned64().
 *
 * Results are cached in the global variable mHobList (qword_C78).
 *
 * @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 (passed through from GetHobList).
 * @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 EDK2 DebugLib protocol).
 *
 * Resolves the DebugLib protocol interface via GetDebugProtocol() 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
 * 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
  );

/**
 * Reads an unaligned 64-bit value from memory.
 *
 * Wraps the BaseLib ReadUnaligned64() concept 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 shared across all UBA
/// platform variants (NeonCityFPGA, LightningRidgeEXRP, LightningRidgeEXECB1).
///
/// The registration function is at offset 0x10 within the interface structure.
/// The DebugAssert handler is at offset 0x08.
///
typedef struct {
  ///
  /// Unknown field at offset 0x00 (may contain protocol revision or header).
  ///
  UINT64   Reserved0;
  ///
  /// Function at offset 0x08. Debug assertion handler.
  /// Called from DebugAssert() when an assertion fires.
  ///
  /// Signature: UINTN (EFIAPI *DebugAssertHandler)(
  ///   IN CONST CHAR8  *FileName,
  ///   IN UINTN        LineNumber,
  ///   IN CONST CHAR8  *Description
  ///   );
  ///
  UINT64   DebugAssertHandler;
  ///
  /// Function at offset 0x10. Registers the USB OC configuration data.
  ///
  /// @param[in] This            Pointer to the UBA board-type protocol interface.
  /// @param[in] ConfigGuid      GUID of the protocol to register
  ///                            (UBA_LIGHTNINGRIDGEEXECB1_USBOC_CONFIG_PROTOCOL_GUID).
  /// @param[in] ConfigData      Pointer to the UBA_USBOC_CONFIG_DATA structure.
  /// @param[in] ConfigDataSize  Size of the configuration data structure in bytes
  ///                            (16 = sizeof(UBA_USBOC_CONFIG_DATA)).
  ///
  /// @return EFI_STATUS.
  ///
  EFI_STATUS
  (EFIAPI *RegisterUsbOcConfig) (
    IN VOID                    *This,
    IN EFI_GUID                *ConfigGuid,
    IN UBA_USBOC_CONFIG_DATA   *ConfigData,
    IN UINT64                  ConfigDataSize
    );
} UBA_BOARD_TYPE_PROTOCOL;

///
/// DEBUGLIB_PROTOCOL
///
/// The protocol interface for the EDK2 Debug Library protocol, obtained via
/// gBS->LocateProtocol() using EFI_DEBUG_LIB_PROTOCOL_GUID.
/// Lazily resolved and cached by GetDebugProtocol().
///
typedef struct {
  ///
  /// Function at offset 0x00. Debug print/output function.
  ///
  /// @param[in] ErrorLevel  Debug error level mask.
  /// @param[in] Format      Format string.
  /// @param[in] VaList      Variable argument list.
  ///
  /// @return Number of characters output, or implementation-defined value.
  ///
  UINTN
  (EFIAPI *DebugPrint) (
    IN UINTN       ErrorLevel,
    IN CONST CHAR8 *Format,
    IN VA_LIST     VaList
    );
  ///
  /// Function at offset 0x08. Debug assertion handler.
  ///
  /// @param[in] FileName     Source file name.
  /// @param[in] LineNumber   Line number of the assertion.
  /// @param[in] Description  Description of the failed assertion.
  ///
  /// @return Implementation-defined (typically 0 or an abort status).
  ///
  UINTN
  (EFIAPI *DebugAssert) (
    IN CONST CHAR8  *FileName,
    IN UINTN        LineNumber,
    IN CONST CHAR8  *Description
    );
} DEBUGLIB_PROTOCOL;

#endif /* _USB_OC_UPDATE_DXE_LIGHTNINGRIDGE_EXECB1_H_ */