/** @file
  IIO Configuration Update DXE driver - Lightning Ridge EXRP platform variant.

  This DXE driver is part of the UBA (Universal BIOS Architecture) framework.
  It provides IIO (Integrated IO) configuration update data for the Lightning
  Ridge EXRP platform (Purley Refresh / Intel Xeon Scalable "Skylake-SP" family).

  The driver locates the UBA_PROTOCOL at boot time and sends IIO PCIe config
  update tables (identified by GUIDs) to the UBA protocol handler. These tables
  contain PCIe register AND/OR mask updates that are applied to IIO root ports.

  UEFI Phase: DXE
  Platform:   Purley RP (PurelyRpPkg)
  CPU:        Intel Xeon Scalable - Lightning Ridge EXRP
  Build:      VS2015, DEBUG, X64
  Source:     Uba/UbaMain/Dxe/TypeLightningRidgeEXRP/IioCfgUpdateDxe/

  Copyright (c) Intel Corporation. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#ifndef IIO_CFG_UPDATE_DXE_LIGHTNING_RIDGE_EXRP_H_
#define IIO_CFG_UPDATE_DXE_LIGHTNING_RIDGE_EXRP_H_

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

///
/// UBA Protocol GUID
/// The protocol used to communicate UBA (Universal BIOS Architecture) data
/// between platform-specific drivers and the UBA core.
///
#define UBA_PROTOCOL_GUID \
  { 0xE03E0D46, 0x5263, 0x4845, { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }

///
/// First IIO configuration data GUID - Socket IIO config block
///
#define IIO_CFG_UPDATE_GUID_1 \
  { 0x6FE6C559, 0x4F35, 0x4111, { 0x98, 0xE1, 0x33, 0x2A, 0x25, 0x15, 0x12, 0xF3 } }

///
/// Second IIO configuration data GUID - IIO misc config block
///
#define IIO_CFG_UPDATE_GUID_2 \
  { 0x0F722F2A, 0x650F, 0x448A, { 0xAB, 0xB7, 0x04, 0xEE, 0xCD, 0x75, 0xBB, 0x30 } }

///
/// Third IIO configuration data GUID - IIO PCIe config block
///
#define IIO_CFG_UPDATE_GUID_3 \
  { 0xEBD11A00, 0x8C5C, 0x4F71, { 0xBB, 0x9E, 0x53, 0x94, 0x03, 0x2B, 0x01, 0xF4 } }

///
/// Fourth IIO configuration data GUID - Additional IIO config block
///
#define IIO_CFG_UPDATE_GUID_4 \
  { 0x123BD082, 0x3201, 0x465C, { 0xB1, 0x39, 0x0C, 0xB8, 0xC7, 0x72, 0x08, 0xF8 } }

///
/// HOB GUID for IIO configuration HOB matching.
/// This GUID is used to find the IIO configuration HOB from the HOB list.
///
#define IIO_CFG_HOB_MATCH_GUID \
  { 0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }

///
/// UBA protocol interface structure.
/// Platform driver fills in the IIO config data, then calls RegisterData()
/// to send it to the UBA core for application.
///
typedef struct _UBA_PROTOCOL UBA_PROTOCOL;

///
/// UBA protocol function table (index-based ABI).
/// Offset 0:  Unknown / reserved
/// Offset 8:  Unknown / reserved
/// Offset 16: SetIIOConfigData
///   Registers a block of IIO configuration data identified by a GUID.
///
/// @param[in] This       Pointer to the UBA_PROTOCOL instance.
/// @param[in] Guid       GUID identifying the config data type.
/// @param[in] ConfigData Pointer to the IIO configuration data structure.
/// @param[in] Size       Size of the configuration data structure.
///
/// @retval EFI_SUCCESS   Config data was registered successfully.
///
typedef
EFI_STATUS
(EFIAPI *UBA_SET_IIO_CONFIG_DATA)(
  IN UBA_PROTOCOL          *This,
  IN EFI_GUID              *Guid,
  IN VOID                  *ConfigData,
  IN UINTN                 Size
  );

struct _UBA_PROTOCOL {
  UINT64                       Reserved0;            ///< Unknown field
  UINT64                       Reserved1;            ///< Unknown field
  UBA_SET_IIO_CONFIG_DATA      SetIIOConfigData;     ///< Offset +16
};

///
/// PIIO structure signature ("PIIO").
///
#define PIIO_STRUCTURE_SIGNATURE  SIGNATURE_32('P', 'I', 'I', 'O')

///
/// IIO Configuration Table Header (PIIO).
/// This header is followed by an array of IIO_CFG_ENTRY structures.
///
typedef struct {
  UINT32    Signature;      ///< "PIIO" - Platform IIO signature
  UINT32    Revision;       ///< Structure revision (1)
  UINT64    HeaderSize;     ///< Total size of this header structure
  UINT64    EntrySize;      ///< Size of each config entry (0x3C = 60 bytes)
  UINT64    NumEntries;     ///< Number of config entries (0x50C = 1292)
  UINT64    TotalSize;      ///< Total size of all entry data (0xC60 = 3168)
  UINT64    Reserved;       ///< Reserved field (0xD8 = 216)
  // Followed by IIO_CFG_ENTRY Entries[];
} PIIO_STRUCTURE;

///
/// Individual IIO Configuration Update Entry.
/// Describes a PCIe register modification to apply to an IIO device.
///
typedef struct {
  UINT8     Socket;         ///< Socket index (0xFF = all sockets)
  UINT8     Bus;            ///< Bus number (0xFF = all buses)
  UINT8     Device;         ///< Device number (0xFF = all devices)
  UINT8     Function;       ///< Function number (0xFF = all functions)
  UINT16    Register;       ///< PCI configuration register offset
  UINT8     AndMask;        ///< AND mask to apply to register value
  UINT8     OrMask;         ///< OR mask to apply to register value
  UINT8     Flags;          ///< Flags (bit 0: enable update)
  UINT8     Reserved[3];    ///< Padding / reserved
} IIO_CFG_ENTRY;

//
// RTC CMOS addresses used for platform type detection
//
#define RTC_CMOS_INDEX_PORT    0x70   ///< RTC CMOS index register
#define RTC_CMOS_DATA_PORT     0x71   ///< RTC CMOS data register
#define RTC_CMOS_INDEX_SKU     0x4B   ///< CMOS offset holding platform SKU info

//
// Hardware register for platform type detection
//
#define PLATFORM_INFO_REGISTER  0xFDAF0490  ///< Memory-mapped platform info register

//
// UBA debug level constants
//
#define UBA_DEBUG_ERROR     0x80000000
#define UBA_DEBUG_INFO      0x80000040
#define UBA_DEBUG_VERBOSE   0x80000044

//
// CMOS SKU values
//
#define CMOS_SKU_UNKNOWN    0
#define CMOS_SKU_TYPE1      1           ///< Platform type 1
#define CMOS_SKU_TYPE2      2           ///< Platform type 2
#define CMOS_SKU_TYPE3      3           ///< Platform type 3
#define CMOS_SKU_TYPE4      4           ///< Platform type 4 (max valid)

//
// Memory allocation type for boot services data
//
#define MEMORY_TYPE_BOOT_SERVICES_DATA  31

//
// Debug library protocol GUID (MdePkg standard)
// {0xE0D4DF48-CB79-4b33-9568-20E8AAA1EC47}
//
#define DEBUG_LIB_PROTOCOL_GUID \
  { 0xE0D4DF48, 0xCB79, 0x4B33, { 0x95, 0x68, 0x20, 0xE8, 0xAA, 0xA1, 0xEC, 0x47 } }

//
// ASSERT status type for EFI_ERROR
//
#define ASSERT_EFI_ERROR_STATUS  0x800000000000000EULL

// ---------------------------------------------------------------------------
// Function Declarations
// ---------------------------------------------------------------------------

/**
  Entry point for the IIO Configuration Update DXE driver.

  Initializes global UEFI table pointers (ImageHandle, SystemTable,
  BootServices, RuntimeServices), initializes the HOB list, then
  calls IioCfgUpdateMain() to perform the IIO configuration data update.

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.
  @param[in] SystemTable  A pointer to the EFI System Table.

  @return EFI_STATUS      Status code from IioCfgUpdateMain().
**/
EFI_STATUS
EFIAPI
ModuleEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  );

/**
  Main IIO configuration update routine.

  Locates the UBA protocol and sends the IIO configuration data tables
  (PIIO structures) for each of the four IIO config GUIDs to the UBA
  protocol handler.

  @retval EFI_SUCCESS           All IIO config data was registered.
  @retval EFI_UNSUPPORTED       UBA protocol not found.
  @retval EFI_INVALID_PARAMETER A config registration call failed.
**/
EFI_STATUS
IioCfgUpdateMain (
  VOID
  );

/**
  Returns EFI_UNSUPPORTED status stub.

  @return EFI_UNSUPPORTED       Always returns EFI_UNSUPPORTED.
**/
EFI_STATUS
EFIAPI
IioCfgUpdateUnsupported (
  VOID
  );

/**
  Gets the DebugLib protocol instance.

  Allocates a pool buffer of 0x10 bytes then locates the DebugLib protocol
  by GUID. Caches the protocol pointer in a global variable.

  @return Pointer to the DebugLib protocol interface, or NULL if not found.
**/
VOID *
GetDebugLibProtocol (
  VOID
  );

/**
  Platform-aware debug print function.

  Writes a formatted debug message through the DebugLib protocol.
  Also checks the CMOS RTC and platform info register to determine
  the platform SKU/type for conditional debug output.

  @param[in] DebugLevel    Debug message level (e.g., UBA_DEBUG_ERROR).
  @param[in] FormatString  Format string for the debug message.
  @param[in] ...           Variable arguments for the format string.
**/
VOID
EFIAPI
DebugPrintUba (
  IN UINTN       DebugLevel,
  IN CONST CHAR8 *FormatString,
  ...
  );

/**
  ASSERT assertion handler wrapper.

  Calls the DebugLib protocol's ASSERT handler with file/line/expression info.

  @param[in] FileName   Source file name string.
  @param[in] LineNumber Line number in the source file.
  @param[in] Expression Failed assertion expression string.
**/
VOID
EFIAPI
AssertHandler (
  IN CONST CHAR8 *FileName,
  IN UINTN       LineNumber,
  IN CONST CHAR8 *Expression
  );

/**
  Initializes the HOB (Hand-Off Block) list pointer.

  Finds the HOB list from the System Table's configuration table and
  searches for the IIO configuration HOB matching a specific GUID.
  Caches the HOB list pointer globally.

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.

  @return Pointer to the HOB list, or NULL if not found.
**/
VOID *
HobLibInit (
  IN EFI_HANDLE  ImageHandle
  );

/**
  Compares two GUIDs.

  @param[in] Guid1  Pointer to the first GUID.
  @param[in] Guid2  Pointer to the second GUID.

  @return TRUE if the GUIDs are identical, FALSE otherwise.
**/
BOOLEAN
EFIAPI
CompareGuid (
  IN EFI_GUID  *Guid1,
  IN EFI_GUID  *Guid2
  );

/**
  Reads a 64-bit value from potentially unaligned memory.

  @param[in] Buffer  Pointer to the memory to read (may be unaligned).

  @return The 64-bit value read from the buffer.
**/
UINT64
EFIAPI
ReadUnaligned64 (
  IN CONST VOID  *Buffer
  );

#endif // IIO_CFG_UPDATE_DXE_LIGHTNING_RIDGE_EXRP_H_