/** @file
  UsbOcUpdateDxeLightningRidgeEXECB2.h - Header for the USB Overcurrent
  Update DXE driver for the LightningRidge EXEC B2 platform.

  This DXE driver is part of the UBA (Unified BIOS Abstraction) framework under
  PurleyRpPkg.  Its sole purpose is to locate the UBA USB Overcurrent protocol,
  then invoke a protocol method passing platform-specific GUID and data so that
  the USB OC (overcurrent) settings are installed into ACPI tables for the
  LightningRidge EXEC B2 platform variant.

  Build origin (from PDB path):
    e:\hs\Build\HR6N0XMLK\DEBUG_VS2015\X64\PurleyRpPkg\Uba\UbaMain\Dxe\
    TypeLightningRidgeEXECB2\UsbOcUpdateDxe\UsbOcUpdateDxe\DEBUG\
    UsbOcUpdateDxeLightningRidgeEXECB2.pdb

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#ifndef USB_OC_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B2_H_
#define USB_OC_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B2_H_

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

// ---------------------------------------------------------------------------
// GUID Definitions
// ---------------------------------------------------------------------------

///
/// Protocol GUID for the UBA USB Overcurrent Protocol.
/// Located at 0xB70 in the binary.
///
/// {E03E0D46-5263-4845-B0A4-58D57B3177E2}
///
#define UBA_USB_OC_PROTOCOL_GUID \
  { 0xE03E0D46, 0x5263, 0x4845, \
    { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }

///
/// Platform sub-GUID identifying the LightningRidge EXEC B2 variant.
/// Used as the second parameter to the USB OC protocol method.
/// Located at 0xB80 in the binary.
///
/// {2638009E-3850-4E4B-B05D-042A32DBB9D1}
///
#define LIGHTNING_RIDGE_EXEC_B2_GUID \
  { 0x2638009E, 0x3850, 0x4E4B, \
    { 0xB0, 0x5D, 0x04, 0x2A, 0x32, 0xDB, 0xB9, 0xD1 } }

///
/// ACPI Table GUID (also used as HOB list GUID in EDK2 configuration table).
/// Used as the third parameter to the USB OC protocol method (destination
/// ACPI table information).
///
/// {7739F24C-93D7-11D4-9A3A-0090273FC14D}
///
#define EFI_ACPI_TABLE_GUID \
  { 0x7739F24C, 0x93D7, 0x11D4, \
    { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }

///
/// Protocol GUID for the UBA Debug Print Protocol.
/// Located at 0xB60 in the binary.
///
/// {36232936-0E76-31C8-A13A-3AF2FC1C3932}
///
#define UBA_DEBUG_PRINT_PROTOCOL_GUID \
  { 0x36232936, 0x0E76, 0x31C8, \
    { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }

// ---------------------------------------------------------------------------
// UBA USB Overcurrent Protocol Interface
// ---------------------------------------------------------------------------

///
/// Forward declaration
///
typedef struct _UBA_USB_OC_PROTOCOL UBA_USB_OC_PROTOCOL;

///
/// USB OC protocol function prototype.
/// This function is called at offset +0x10 in the protocol interface.
///
/// @param[in] This          Pointer to the UBA_USB_OC_PROTOCOL instance.
/// @param[in] PlatformGuid  GUID identifying the platform variant (LightningRidge).
/// @param[in] AcpiTableGuid GUID identifying the destination ACPI table storage.
/// @param[in] DataSize      Size of the configuration data being installed.
///
/// @return EFI_STATUS.
///
typedef
EFI_STATUS
(EFIAPI *UBA_USB_OC_SET_DATA)(
  IN UBA_USB_OC_PROTOCOL  *This,
  IN EFI_GUID             *PlatformGuid,
  IN EFI_GUID             *AcpiTableGuid,
  IN UINTN                DataSize
  );

///
/// UBA USB OC Protocol structure.
///
struct _UBA_USB_OC_PROTOCOL {
  ///
  /// Function at offset 0x00: likely DebugPrint or entry function.
  ///
  VOID    *Unknown0;
  ///
  /// Function at offset 0x08: likely error print / assert handler.
  ///
  VOID    *Unknown8;
  ///
  /// Function at offset 0x10: SetData/InstallUsbOcSettings.
  /// Called by the entry point to install platform-specific USB OC settings
  /// into ACPI tables.
  ///
  UBA_USB_OC_SET_DATA  SetData;
};

// ---------------------------------------------------------------------------
// UBA Debug Print Protocol Interface
// ---------------------------------------------------------------------------

///
/// Forward declaration
///
typedef struct _UBA_DEBUG_PRINT_PROTOCOL UBA_DEBUG_PRINT_PROTOCOL;

///
/// Debug print function prototype.
///
/// @param[in] ErrorLevel  Debug message error level mask.
/// @param[in] Format      Format string.
/// @param[in] ...          Additional arguments.
///
/// @return UINT8 (possibly number of characters printed, or status).
///
typedef
UINT8
(EFIAPI *UBA_DEBUG_PRINT)(
  IN UINTN       ErrorLevel,
  IN CONST CHAR8 *Format,
  ...
  );

///
/// UBA Debug Print Protocol structure.
///
struct _UBA_DEBUG_PRINT_PROTOCOL {
  ///
  /// Function at offset 0x00: DebugPrint.
  ///
  UBA_DEBUG_PRINT  DebugPrint;
  ///
  /// Function at offset 0x08: Assert/error handler.
  ///
  VOID             *AssertHandler;
};

// ---------------------------------------------------------------------------
// Global Variables (defined in .data section)
// ---------------------------------------------------------------------------

//
// These globals are stored in the .data segment (0xB60-0xCA0).
//

///
/// The EFI System Table pointer, cached at entry point (0xC50).
///
extern EFI_SYSTEM_TABLE  *gSystemTable;

///
/// The EFI Boot Services table pointer, cached from SystemTable->BootServices (0xC58).
///
extern EFI_BOOT_SERVICES  *gBootServices;

///
/// The ImageHandle passed to the entry point (0xC60).
///
extern EFI_HANDLE  gImageHandle;

///
/// The EFI Runtime Services table pointer, cached from SystemTable->RuntimeServices (0xC68).
///
extern EFI_RUNTIME_SERVICES  *gRuntimeServices;

///
/// Cached pointer to the UBA Debug Print Protocol interface.
/// Initialized lazily by GetDebugPrintProtocol() (sub_4B0).
/// Located at 0xC70.
///
extern UBA_DEBUG_PRINT_PROTOCOL  *gDebugPrintProtocol;

///
/// Cached HOB list pointer, initialized by GetHobList() (sub_5F8).
/// Located at 0xC78.
///
extern VOID  *gHobList;

///
/// CMOS register 0x4B value cached for the current boot.
/// Located at 0xC80.
///
extern UINT8  gCmosDebugLevel;

// ---------------------------------------------------------------------------
// Function Prototypes
// ---------------------------------------------------------------------------

///
/// Driver entry point.
///
/// Initializes UEFI service table globals, retrieves the HOB list, performs a
/// debug print, then locates the UBA USB OC protocol and invokes its SetData
/// method to install platform-specific USB overcurrent settings into ACPI.
///
/// @param[in] ImageHandle  The firmware-allocated handle for this driver.
/// @param[in] SystemTable  Pointer to the EFI System Table.
///
/// @return EFI_STATUS.
///
EFI_STATUS
EFIAPI
UsbOcUpdateEntryPoint(
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  );

///
/// Returns pointers to platform-specific static data tables.
///
/// This function is referenced by the component name protocol structures and
/// provides the static configuration data for the driver. It is not called
/// during the normal entry path.
///
/// @param[out] ConfigData1  Pointer to the first configuration table.
/// @param[out] ConfigData2  Pointer to the second configuration table.
/// @param[out] ConfigData3  Pointer to the third configuration table.
///
/// @return Always returns 0 (EFI_SUCCESS).
///
UINTN
EFIAPI
UsbOcGetConfigTables(
  OUT VOID  **ConfigData1,
  OUT VOID  **ConfigData2,
  OUT VOID  **ConfigData3
  );

///
/// Lazily retrieves and caches the UBA Debug Print Protocol.
///
/// Raises TPL to NOTIFY, checks if the protocol is cached, and if not, locates
/// it via gBS->LocateProtocol().  Returns the cached protocol pointer.
///
/// @return Pointer to the UBA_DEBUG_PRINT_PROTOCOL, or NULL if not found.
///
UBA_DEBUG_PRINT_PROTOCOL *
GetDebugPrintProtocol(
  VOID
  );

///
/// Debug print function with CMOS-based error level filtering.
///
/// Reads CMOS register 0x4B to determine the debug verbosity level, then
/// calls the UBA Debug Print protocol's DebugPrint function if the given
/// ErrorLevel passes the filter.
///
/// @param[in] ErrorLevel  Debug message error level (e.g., DEBUG_ERROR,
///                        DEBUG_INFO).
/// @param[in] Format      Format string.
/// @param[in] ...          Variable arguments for format string.
///
/// @return Non-zero if the message was printed, 0 if filtered or if the
///         debug protocol was not available.
///
UINT8
DebugPrint(
  IN UINTN       ErrorLevel,
  IN CONST CHAR8 *Format,
  ...
  );

///
/// Assert print function.
///
/// Called from assertion macros to print the failure location and expression.
/// Delegates to the UBA Debug Print Protocol's assert handler (offset +8).
///
/// @param[in] FileName    Source file name string.
/// @param[in] LineNumber  Line number of the assertion.
/// @param[in] Description Assertion expression or description string.
///
/// @return EFI_STATUS from the debug protocol, or error if protocol not found.
///
EFI_STATUS
EFIAPI
AssertPrint(
  IN CONST CHAR8  *FileName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *Description
  );

///
/// Retrieves the HOB (Hand-Off Block) list pointer from the UEFI Configuration
/// Table by searching for the entry matching gEfiAcpiTableGuid.
///
/// The result is cached in the global gHobList for subsequent calls.
///
/// @return Pointer to the HOB list, or NULL if not found.
///
VOID *
GetHobList(
  VOID
  );

///
/// Compares two GUIDs by comparing their 64-bit halves.
///
/// Reads two QWORD values from each GUID and checks for equality.  Used as
/// the GUID comparison helper for configuration table entry matching.
///
/// @param[in] Guid1  Pointer to the first GUID.
/// @param[in] Guid2  Pointer to the second GUID.
///
/// @return TRUE if the GUIDs are equal, FALSE otherwise.
///
BOOLEAN
EFIAPI
CompareGuid(
  IN CONST EFI_GUID  *Guid1,
  IN CONST EFI_GUID  *Guid2
  );

///
/// Reads a QWORD from a given address with NULL pointer validation.
///
/// Asserts if the pointer is NULL.  Returns the 64-bit value at the address.
///
/// @param[in] Buffer  Pointer to the QWORD to read.
///
/// @return The QWORD value at the given address.
///
UINT64
EFIAPI
ReadUnaligned64(
  IN CONST VOID  *Buffer
  );

#endif // USB_OC_UPDATE_DXE_LIGHTNING_RIDGE_EXEC_B2_H_