/**
 * @file SetupConfigUpdateDxeLightningRidgeEXECB1.h
 * @brief UBA (Universal BIOS Aggregator) Setup Configuration Update DXE Driver
 *        for LightningRidge EXECB1 platform (Grantley/Intel Purley).
 *
 * This DXE driver is part of PurleyRpPkg/Uba/UbaMain. It provides
 * platform-specific setup configuration for the LightningRidge EXECB1
 * board during the DXE phase.
 *
 * Key behavior:
 *   1. Saves UEFI globals (gImageHandle, gST, gBS, gRT) - standard library init
 *   2. Locates HOB List from SystemTable ConfigurationTable via gEfiHobListGuid
 *   3. Reads CMOS register 0x4B via I/O ports 0x70/0x71 to detect board variant
 *   4. Locates the UBA-LightningRidge protocol (GUID at 0xB50)
 *   5. Calls protocol to register "PSET" config data for GUID at 0xB70
 *
 * GUID map (.data layout):
 *   0xB40: Pattern GUID for protocol lookup inside module (GetUBASetupConfigProtocol)
 *   0xB50: LightningRidge EXECB1 protocol GUID (used by EntryPoint LocateProtocol)
 *   0xB60: gEfiHobListGuid (ConfigurationTable search)
 *   0xB70: Setup config registration key GUID
 *   0xB80: "PSET" Platform SETup configuration structure
 */

#ifndef __SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXECB1_H__
#define __SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXECB1_H__

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

//=============================================================================
// GUIDs
//=============================================================================

/**
 * GUID for UBA SetupConfig Protocol (internal to this module).
 * Used with gBS->LocateProtocol() to get a protocol interface with
 * DebugPrint-like and RegisterConfig-like functions.
 *
 * {36232936-0E76-31C8-A13A-3AF2FC1C3932}
 */
#define GUID_UBA_SETUP_CONFIG_PROTOCOL \
  { 0x36232936, 0x0E76, 0x31C8, \
    { 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }

/**
 * GUID for LightningRidge EXECB1 protocol (used in ModuleEntryPoint).
 * Passed to gBS->LocateProtocol() in the entry point.
 *
 * {E03E0D46-5263-4845-B0A4-58D57B3177E2}
 */
#define GUID_LIGHTNING_RIDGE_EXECB1_PROTOCOL \
  { 0xE03E0D46, 0x5263, 0x4845, \
    { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 } }

/**
 * gEfiHobListGuid - used to find HOB List in ConfigurationTable.
 *
 * {7739F24C-93D7-11D4-9A3A-0090273FC14D}
 */
#define GUID_HOB_LIST \
  { 0x7739F24C, 0x93D7, 0x11D4, \
    { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }

/**
 * GUID key for registering the setup configuration update.
 * Passed to protocol function at offset+16 as the registration key.
 *
 * {CD1F9574-DD03-4196-96AD-4965146F9665}
 */
#define GUID_SETUP_CONFIG_UPDATE \
  { 0xCD1F9574, 0xDD03, 0x4196, \
    { 0x96, 0xAD, 0x49, 0x65, 0x14, 0x6F, 0x96, 0x65 } }


//=============================================================================
// CMOS / Board Detection
//=============================================================================

/*
 * CMOS register 0x4B (RTC indexed) stores the board variant identifier:
 *   0x01 = LightningRidge EXECB1
 *   0x02 = LightningRidge EXECB2 (different debug filter)
 *   0x03 = LightningRidge EXECB3
 *   0x00 = unprogrammed -> fallback to MMIO at 0xFDAF0490
 *
 * Access: outb(0x70, inb(0x70)&0x80 | 0x4B); board = inb(0x71);
 *
 * The debug filter value determines which messages print:
 *   board==1 -> filter = 0x80000004
 *   board==2 -> filter = 0x80000006
 */
#define CMOS_REG_BOARD_INDEX   0x4B
#define CMOS_PORT_INDEX        0x70
#define CMOS_PORT_DATA         0x71

/*
 * Fallback MMIO for board detection when CMOS is unprogrammed.
 * [0xFDAF0490]: bit1 indicates variant, (val & 2) | 1 = board type
 */
#define BOARD_DETECT_MMIO      0xFDAF0490ULL


//=============================================================================
// PLATFORM_SETUP_CONFIG ("PSET")
//=============================================================================

/*
 * The .data section at 0xB80 holds a 24-byte structure:
 *   0xB80: Signature = "PSET" (0x54455350)
 *   0xB84: Version   = 1
 *   0xB88: field1    = 0x48C (relocated)
 *   0xB8C: field2    = 0
 *   0xB90: field3    = 0x48C (relocated)
 *   0xB94: field4    = 0
 *
 * The two non-zero fields at 0xB88/0xB90 have base relocations
 * recorded in the .reloc section, suggesting they may be absolute
 * pointer fixups, or the image is loaded at a non-default base.
 */
typedef struct {
  UINT32  Signature;   /* "PSET" */
  UINT32  Version;     /* 1 */
  UINT32  Field1;      /* 0x48C (reloc) */
  UINT32  Field2;      /* 0 */
  UINT32  Field3;      /* 0x48C (reloc) */
  UINT32  Field4;      /* 0 */
} PLATFORM_SETUP_CONFIG;

/*
 * Size of PLATFORM_SETUP_CONFIG as used in the RegisterConfig call.
 */
#define PLATFORM_SETUP_CONFIG_SIZE  24


//=============================================================================
// UBA Protocol Interface Layout
//=============================================================================

/*
 * The protocol located by GetUBASetupConfigProtocol() has this layout
 * (each entry is a 64-bit function pointer on x64):
 *
 *   +0x00: [0] Debug/filter function (used by CheckBoardTypeAndLog)
 *           Args: (UINTN DebugLevel, CHAR8 *DebugString, VA_LIST Args)
 *
 *   +0x08: [1] Debug print function (used by UBADebugPrint)
 *           Args: (CHAR8 *FileName, UINTN LineNumber, CHAR8 *Expression)
 *           This is the ASSERT handler replacement.
 *
 * The protocol located by ModuleEntryPoint via LocateProtocol(B50)
 * has an additional function at offset +0x10:
 *
 *   +0x10: [2] RegisterConfig function (used by ModuleEntryPoint)
 *           Args: (VOID *This, GUID *ConfigGuid, VOID *ConfigData, UINTN ConfigSize)
 *           Returns: EFI_STATUS
 */


//=============================================================================
// Global Variables (written at runtime by entry point)
//=============================================================================

/*
 * .data globals (defined in .c):
 *   0xB98: gImageHandle   (EFI_HANDLE)
 *   0xBA0: gST            (EFI_SYSTEM_TABLE*)
 *   0xBA8: gBS            (EFI_BOOT_SERVICES*)
 *   0xBB0: gRT            (EFI_RUNTIME_SERVICES*)
 *   0xBB8: gUbaProtocol   (VOID*) - cached UBA protocol
 *   0xBC0: gHobList       (VOID*) - cached HOB list
 *   0xBC8: gBoardType     (UINT8) - cached CMOS board index
 */
extern EFI_HANDLE           gImageHandle;
extern EFI_SYSTEM_TABLE    *gST;
extern EFI_BOOT_SERVICES   *gBS;
extern EFI_RUNTIME_SERVICES*gRT;
extern VOID                *gUbaProtocol;
extern VOID                *gHobList;
extern UINT8                gBoardType;


//=============================================================================
// Function Prototypes
//=============================================================================

/*
 * sub_48C - Return EFI_INVALID_PARAMETER status constant.
 * Called by CheckBoardTypeAndLog (via ASSERT macro expansion).
 */
EFI_STATUS
GetInvalidParameterStatus (
  VOID
  );

/*
 * sub_498 - Locate UBA SetupConfig Protocol (cache in gUbaProtocol).
 * Uses gBS->RaiseTPL(31), RestoreTPL(old), then LocateProtocol(GUID_B40,...).
 * If oldTPL > 16 after probe, returns NULL without calling LocateProtocol.
 * Caches result in gUbaProtocol.
 */
VOID *
GetUBASetupConfigProtocol (
  VOID
  );

/*
 * sub_518 - Board-type-aware log function.
 * Reads CMOS reg 0x4B to determine board type, sets debug filter mask,
 * and if (mask & DebugLevel) != 0, calls Protocol[0] with the args.
 */
UINTN
CheckBoardTypeAndLog (
  UINTN            DebugLevel,
  CHAR8           *DebugString,
  ...
  );

/*
 * sub_5A0 - Call Protocol[1] (debug print) with three params.
 * Wrapper that asserts file/line/expression via protocol.
 */
UINTN
UBADebugPrint (
  CHAR8           *FileName,
  UINTN            LineNumber,
  CHAR8           *Expression
  );

/*
 * sub_728 - Read unaligned UINT64 with NULL-pointer check.
 * Used to compare GUIDs as two 64-bit values.
 */
UINT64
ReadUnaligned64 (
  VOID            *Buffer
  );

/*
 * sub_6B8 - Compare two GUIDs via unaligned 64-bit halves.
 * Used for ConfigurationTable entry matching (HOB list search).
 */
BOOLEAN
CompareGuidUnaligned (
  GUID            *Guid1,
  VOID            *Entry
  );

/*
 * sub_5E0 - Find HOB List in SystemTable->ConfigurationTable.
 * Walks entries matching gEfiHobListGuid, caches interface in gHobList.
 * Asserts if not found.
 */
VOID *
GetHobListFromConfigTable (
  VOID
  );

/*
 * _ModuleEntryPoint (0x390) - Driver entry point.
 * Initializes globals, caches HOB list, prints ident string,
 * locates protocol via GUID_B50, and calls RegisterConfig at +16.
 */
EFI_STATUS
EFIAPI
SetupConfigUpdateEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  );

#endif /* __SLOT_DATA_UPDATE_DXE_LIGHTNING_RIDGE_EXECB1_H__ */