/** @file
  StaticSkuDataDxeLightningRidgeEXECB3 -- Static SKU/Platform Data DXE Driver

  This UEFI DXE driver provides static SKU and platform configuration data
  for Lightning Ridge EXEC B3 platforms. It installs the following static
  data tables via a custom protocol:

    - UMPT (UEFI Memory Population Table):
        Socket-to-memory-channel topology describing DIMM population for
        multi-socket configurations (up to 8 sockets, 3 channels per socket).

    - PIRQ (Platform IRQ Routing) / CCT (Core Configuration Table):
        Processor core-to-APIC-interrupt routing maps for up to 8 logical
        processors per cluster, covering 4 interrupt vectors per core.

    - CFH (Core Family Hierarchy):
        Extended core topology data describing per-core capabilities
        (type 0x1F entries indicating core count per cluster).

    - ACPF (ACPI Processor Info):
        ACPI _SB CPU device mapping associating processor GUIDs with
        their ACPI namespace identifiers.

  The driver entry point:
    1. Initializes UEFI globals (gImageHandle, gST, gBS, gRT).
    2. Locates the Platform Protocol (GUID E03E0D46-...).
    3. Walks the HOB list to discover the platform database.
    4. Registers static data tables via the protocol's install interface.

  NOTE: This driver has zero IAT imports (no DLL/PE dependencies). All
  functionality is provided by the UEFI boot and runtime services tables.

  Image base 0x0, image size 0xFB60.

  Copyright (C) 2025, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "StaticSkuDataDxeLightningRidgeEXECB3.h"

//
// -------------------------------------------------------------------------
// Protocol GUIDs
// -------------------------------------------------------------------------
//

STATIC CONST EFI_GUID  mPlatformProtocolGuid =
  STATIC_SKU_DATA_PLATFORM_PROTOCOL_GUID;

STATIC CONST EFI_GUID  mStaticSkuDataProtocolGuid =
  STATIC_SKU_DATA_PROTOCOL_GUID;

STATIC CONST EFI_GUID  mPirqProtocolGuid =
  { 0x0FF8A1CF, 0xA0AB, 0x4AC0,
    { 0xBF, 0xC9, 0x34, 0xA7, 0x8F, 0x68, 0xDD, 0x8A } };

STATIC CONST EFI_GUID  mAcpiProcessorInfoGuid =
  { 0x4C1F48A5, 0xC976, 0x4D90,
    { 0x9F, 0x03, 0x8E, 0x9B, 0x1C, 0x32, 0x7F, 0xCF } };

STATIC CONST EFI_GUID  mAcpiProcessorDataGuid =
  { 0x81129EF8, 0x391D, 0x4F63,
    { 0xAE, 0x99, 0x58, 0x51, 0x7E, 0xC0, 0x77, 0xE3 } };

STATIC CONST EFI_GUID  mHobMemoryAllocModuleGuid =
  { 0x7739F24C, 0x93D7, 0x11D4,
    { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } };

//
// -------------------------------------------------------------------------
// Globals
// -------------------------------------------------------------------------
//

EFI_HANDLE            gImageHandle      = NULL;  ///< Offset 0xF550
EFI_SYSTEM_TABLE      *gST              = NULL;  ///< Offset 0xF540
EFI_BOOT_SERVICES     *gBS              = NULL;  ///< Offset 0xF548
EFI_RUNTIME_SERVICES  *gRT              = NULL;  ///< Offset 0xF558
VOID                  *gPlatformProtocol = NULL; ///< Offset 0xF560
VOID                  *gHobList         = NULL;  ///< Offset 0xF568
UINT8                 gCmosIndex        = 0;     ///< Offset 0xF570

//
// -------------------------------------------------------------------------
// Debug Assertion Strings  (offset 0x780 - 0x3F00)
// -------------------------------------------------------------------------
//

STATIC CONST CHAR8  mAssertEfiError[]       = "\nASSERT_EFI_ERROR (Status = %r)\n";
STATIC CONST CHAR8  mAssertNotEfiError[]    = "!EFI_ERROR (Status)";
STATIC CONST CHAR8  mAssertImageHandle[]    = "gImageHandle != ((void *) 0)";
STATIC CONST CHAR8  mAssertSystemTable[]    = "gST != ((void *) 0)";
STATIC CONST CHAR8  mAssertBootServices[]   = "gBS != ((void *) 0)";
STATIC CONST CHAR8  mAssertRuntimeServices[]= "gRT != ((void *) 0)";
STATIC CONST CHAR8  mAssertHobList[]        = "mHobList != ((void *) 0)";
STATIC CONST CHAR8  mAssertBuffer[]         = "Buffer != ((void *) 0)";

STATIC CONST CHAR8  mFilePathBootServices[] =
  "e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c";
STATIC CONST CHAR8  mFilePathHobLib[] =
  "e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c";
STATIC CONST CHAR8  mFilePathRuntimeServices[] =
  "e:\\hs\\MdePkg\\Library\\UefiRuntimeServicesTableLib\\UefiRuntimeServicesTableLib.c";
STATIC CONST CHAR8  mFilePathUnaligned[] =
  "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c";

//
// ACPI namespace method names for SKU data access
//
STATIC CONST CHAR8  mAcpiNameCCT0[] = "_SB_.CCT0";
STATIC CONST CHAR8  mAcpiNameCCT1[] = "_SB_.CCT1";
STATIC CONST CHAR8  mAcpiNameCCT2[] = "_SB_.CCT2";
STATIC CONST CHAR8  mAcpiNameCCT3[] = "_SB_.CCT3";
STATIC CONST CHAR8  mAcpiNameCCT4[] = "_SB_.CCT4";
STATIC CONST CHAR8  mAcpiNameCCT5[] = "_SB_.CCT5";
STATIC CONST CHAR8  mAcpiNameCCT6[] = "_SB_.CCT6";
STATIC CONST CHAR8  mAcpiNameCCT7[] = "_SB_.CCT7";
STATIC CONST CHAR8  mAcpiNameCCT8[] = "_SB_.CCT8";
STATIC CONST CHAR8  mAcpiNameCFH0[] = "_SB_.CFH0";

//
// -------------------------------------------------------------------------
// Static Data Section Layout  (0x4080 - 0xF580)
// -------------------------------------------------------------------------
// The .data section contains the platform HOB descriptor block followed
// by the UMPT config table, UMPT data entries, PIRQ routing, core family
// hierarchy, ACPI processor info, and memory topology tables.
//

//
// Platform HOB descriptor at 0x40A0.
// Structure: HOB GUID, tag 'UMPT', version, data ptr, config ptr,
//            PIRQ protocol GUID, tag 'PIRQ', version, PIRQ data ptr,
//            ACPI processor GUID, NULL sentinel, size.
//
STATIC CONST struct {
  EFI_GUID    HobGuid;           ///< gEfiHobMemoryAllocModuleGuid
  UINT32      UmptTag;           ///< 'UMPT' = 0x54504D55
  UINT32      UmptVersion;       ///< 1
  VOID        *UmptDataPtr;      ///< -> 0x9060 (UMPT data entries)
  VOID        *UmptConfigPtr;    ///< -> 0x9040 (UMPT config descriptors)
  EFI_GUID    PirqProtocolGuid;  ///< STATIC_SKU_DATA_PROTOCOL_GUID
  UINT32      PirqTag;           ///< 'PIRQ' = 0x51524950
  UINT32      PirqVersion;       ///< 1
  VOID        *PirqDataPtr;      ///< -> 0x90D8 (PIRQ data entries)
  EFI_GUID    AcpiProcGuid;      ///< ACPI_PROCESSOR_INFO_PROTOCOL_GUID
  UINT64      NullSentinel;      ///< NULL terminator
  UINT64      AcpiDataSize;      ///< 1984 = 0x7C0
} mPlatformHobBlock = {
  { 0x7739F24C, 0x93D7, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } },
  0x54504D55,   // 'UMPT'
  1,
  (VOID *)0x9060,
  (VOID *)0x9040,
  { 0x0FF8A1CF, 0xA0AB, 0x4AC0, { 0xBF, 0xC9, 0x34, 0xA7, 0x8F, 0x68, 0xDD, 0x8A } },
  0x51524950,   // 'PIRQ'
  1,
  (VOID *)0x90D8,
  { 0x4C1F48A5, 0xC976, 0x4D90, { 0x9F, 0x03, 0x8E, 0x9B, 0x1C, 0x32, 0x7F, 0xCF } },
  0,
  1984
};

//
// UMPT configuration table at 0x9040.
// Each entry: { UINT64 DataOffset, UINT64 DataSize }
//
STATIC CONST TABLE_DESCRIPTOR  mUmptConfigTable[] = {
  { 0xD690, 59  },  // Socket memory topology (59 bytes)
  { 0xC2C0, 211 },  // IOAPIC interrupt routing (211 bytes)
  { 0x9110, 25  },  // Socket core/thread map (25 bytes)
  { 0xDB30, 2   },  // Config sentinel (2 bytes)
};

//
// UMPT data entries at 0x9060.
// Each entry: { UINT64 DataOffset, UINT64 DataSize }
//
STATIC CONST TABLE_DESCRIPTOR  mUmptDataTable[] = {
  { 0x9110, 25  },  // Socket core topology map
  { 0xDB30, 2   },  // Config sentinel
  { 0xDB60, 275 },  // Core Family Hierarchy (CFH)
  { 0xBD80, 67  },  // Core Configuration Table (CCT)
};

//
// ACPI Processor Data block at 0x9020.
//
STATIC CONST struct {
  UINT32    Tag;              ///< 'ACPF' = 0x46504341
  UINT32    Version;          ///< 1
  UINT32    ProcessorType;    ///< 0x4100
  UINT32    Reserved1;
  EFI_GUID  ProcessorGuid;    ///< {81129EF8-391D-4F63-AE99-58517EC077E3}
  UINT64    DataOffset;       ///< 0xD690
  UINT32    ProcessorCount;   ///< 59 = 0x3B
  UINT32    Reserved2;
} mAcpiProcessorBlock = {
  0x46504341,  // 'ACPF'
  1,
  0x4100,
  0,
  { 0x81129EF8, 0x391D, 0x4F63, { 0xAE, 0x99, 0x58, 0x51, 0x7E, 0xC0, 0x77, 0xE3 } },
  0xD690,
  0x3B,
  0
};

//
// PIRQ data table header at 0x40D8.
//
STATIC CONST struct {
  UINT32    Tag;              ///< 'PIRQ' = 0x51524950
  UINT32    Flags;            ///< 1
  VOID      *DataPtr;         ///< -> 0x90D8 (PIRQ routing entries)
  EFI_GUID  Guid;             ///< ACPI_PROCESSOR_INFO_PROTOCOL_GUID
} mPirqDataTable = {
  0x51524950,   // 'PIRQ'
  1,
  (VOID *)0x90D8,
  { 0x4C1F48A5, 0xC976, 0x4D90, { 0x9F, 0x03, 0x8E, 0x9B, 0x1C, 0x32, 0x7F, 0xCF } },
};

//
// Memory socket topology data at 0xD690 (59+ bytes).
// 20-byte entries: { UINT32 Socket; UINT8 Reserved[7]; UINT8 Type;
//                     UINT8 SubType; UINT8 ChannelMap[3]; UINT8 Reserved2[3] }
//
STATIC CONST UINT8  mSocketMemoryTopology[] = {
  // Socket 0, DDR5 (Type=0x0A), channels [4,5,6] (A/B/C)
  0x01,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0A,0x00,0x04, 0x05,0x06,0x00,0x00,
  0x01,0x00,0x00,0x00, 0x01,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0A,0x01,0x06, 0x04,0x05,0x00,0x00,
  0x01,0x00,0x00,0x00, 0x02,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0A,0x02,0x05, 0x06,0x04,0x00,0x00,
  0x01,0x00,0x00,0x00, 0x03,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0A,0x03,0x06, 0x04,0x05,0x00,0x00,
  // Socket 1, Type=0x0B, channels rotated
  0x02,0x00,0x00,0x00, 0x01,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0B,0x01,0x06, 0x04,0x05,0x00,0x00,
  0x02,0x00,0x00,0x00, 0x02,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0B,0x02,0x05, 0x06,0x04,0x00,0x00,
  0x02,0x00,0x00,0x00, 0x03,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0B,0x03,0x06, 0x04,0x05,0x00,0x00,
  // Socket 2, Type=0x0C
  0x03,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0C,0x00,0x04, 0x05,0x06,0x00,0x00,
  0x03,0x00,0x00,0x00, 0x01,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0C,0x01,0x06, 0x04,0x05,0x00,0x00,
  0x03,0x00,0x00,0x00, 0x02,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0C,0x02,0x05, 0x06,0x04,0x00,0x00,
  0x03,0x00,0x00,0x00, 0x03,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0C,0x03,0x06, 0x04,0x05,0x00,0x00,
  // Socket 3, Type=0x0D
  0x04,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0D,0x00,0x04, 0x05,0x06,0x00,0x00,
  // Socket 4, Type=0x0E
  0x05,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0E,0x00,0x04, 0x05,0x06,0x00,0x00,
  // Socket 5, Type=0x0F
  0x06,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x0F,0x00,0x04, 0x05,0x06,0x00,0x00,
  // Socket 6, Type=0x10
  0x07,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x10,0x00,0x04, 0x05,0x06,0x00,0x00,
  0x07,0x00,0x00,0x00, 0x01,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x10,0x01,0x06, 0x04,0x05,0x00,0x00,
};

//
// Socket core/thread topology at 0x9110 (25 bytes).
//
STATIC CONST UINT8  mSocketCoreTopology[] = {
  0x01,0x00,0x00,0x00, 0x00,0x10,0xC0,0xFE,  // Socket 0, APIC base 0xFEC00000
  0x09,0x20,0x00,0x00, 0x01,0x00,0x00,0x00,  // Type 0x20, count=9
  0x00,0x80,0xC0,0xFE, 0x0A,0x20              // Socket 1, APIC base 0xFEC08000,...
};

//
// IOAPIC interrupt routing data at 0xC2C0 (211 bytes).
// 12-byte entries: mapping from PCIe slot/device to IOAPIC input pins.
//
STATIC CONST UINT8  mIoApicRoutingData[] = {
  // Entry 0: flags=0xFF, ioapic=0x00, intin=0x09, dev=0x07
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x00,0x09,0x07, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x04,0x00,0x09,0x02, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x04,0x01,0x09,0x03, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x04,0x02,0x09,0x02, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x04,0x03,0x09,0x03, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x04,0x00,0x09,0x02, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x04,0x01,0x09,0x02, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x04,0x02,0x09,0x02, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00, 0xFF,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x04,0x03,0x09,0x02, 0x00,0x00,0x03,0x00, 0x03,0x00,0x00,0x00,
};

//
// Core Family Hierarchy at 0xDB60 (275 bytes).
// 16-byte entries: {UINT16 Type(0x001F), UINT8 Cluster, UINT8 Reserved[2],
//                    UINT8 Flags, UINT8 ApicId, UINT16 Reserved2, UINT32 Caps}
//
STATIC CONST UINT8  mCoreFamilyHierarchy[] = {
  // Clusters 0-10, each with type 0x1F (standard core)
  // Type(2)=0x1F, Cluster=0, Caps=8
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 1: ApicId=1
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 2: ApicId=2
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x02, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 3: ApicId=3
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x03, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 4: ApicId=4
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x04, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 5: ApicId=5
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x05, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 6: ApicId=6
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x06, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 7: ApicId=7
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x07, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 8: ApicId=8, caps=1
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x08, 0x00,0x00,0x01,0x00, 0x01,0x00,0x00,0x00,
  // Cluster 9: ApicId=9
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x09, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster A: ApicId=0xA
  0x00,0x00,0x00,0x00, 0x1F,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x08,0x0A, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
};

//
// Core Configuration Table (CCT) at 0xBD80 (67 bytes).
// 16-byte entries: {UINT16 Type(0x001C), UINT8 Index, UINT8 Reserved[3],
//                    UINT8 Flags, UINT8 ApicCluster, UINT8 CoreMap[4],
//                    UINT32 Reserved2}
//
STATIC CONST UINT8  mCoreConfigTable[] = {
  // Cluster 0, 4-way interleave: cores [16,17,18,19]
  0x00,0x00,0x00,0x00, 0x1C,0x00,0xFF,0x00, 0xFF,0x00,0xFF,0x00,
  0x00,0x08,0x10,0x11, 0x12,0x13,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 1, rotated: [17,18,19,16]
  0x1C,0x01,0xFF,0x00, 0xFF,0x00,0xFF,0x00, 0x00,0x08,0x11,0x12,
  0x13,0x10,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 2, rotated: [18,19,16,17]
  0x1C,0x02,0xFF,0x00, 0xFF,0x00,0xFF,0x00, 0x00,0x08,0x12,0x13,
  0x10,0x11,0x00,0x00, 0x00,0x00,0x00,0x00,
  // Cluster 3, rotated: [19,16,17,18]
  0x1C,0x03,0xFF,
};

//
// UMPT entry 1 sentinel (2 bytes) at 0xDB30.
//
STATIC CONST UINT8  mConfigSentinel[] = { 0x00, 0x00 };

//
// PIRQ routing entries header at 0x90D8.
// Entries: {UINT64 DataPtr, UINT64 Size, ...}
//
STATIC CONST TABLE_DESCRIPTOR  mPirqDataEntries[] = {
  { 0xBD70, 7    },  // PIRQ entry 0: 7 bytes header
  { 0x9660, 1    },  // PIRQ entry 1
  { 0x9240, 0x20E},  // PIRQ entry 2: large routing table
  { 0,       1    },  // Terminator
};

//
// PIRQ routing entry at 0xBD70 (7 bytes header).
//
STATIC CONST UINT8  mPirqRoutingHeader[] = {
  0x0B, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x05,
};

//
// -------------------------------------------------------------------------
// Helper Functions
// -------------------------------------------------------------------------
//

/**
  Retrieves the platform protocol interface.

  Singleton accessor. On first call it locates the protocol via
  gBS->LocateProtocol. Subsequent calls return the cached pointer.

  @return Pointer to the platform protocol interface, or NULL.

**/
VOID *
GetPlatformProtocol (
  VOID
  )
{
  EFI_STATUS  Status;

  if (gPlatformProtocol == NULL) {
    Status = gBS->LocateProtocol (
                    (EFI_GUID *)&mPlatformProtocolGuid,
                    NULL,
                    &gPlatformProtocol
                    );
    if (EFI_ERROR (Status)) {
      gPlatformProtocol = NULL;
    }
  }

  return gPlatformProtocol;
}

/**
  Reports an assertion/debug message through the platform protocol.

  @param[in] FileName     Source file name string.
  @param[in] LineNumber   Line number in the source file.
  @param[in] Description  Assert/error description.

**/
VOID
DebugReport (
  IN CONST CHAR8  *FileName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *Description
  )
{
  VOID     *PlatformProtocol;
  UINT64   (*DebugFunc)(CONST CHAR8 *, UINTN, CONST CHAR8 *);

  PlatformProtocol = GetPlatformProtocol ();
  if (PlatformProtocol != NULL) {
    //
    // Protocol function at offset +8: DebugReport(file, line, desc)
    //
    DebugFunc = *(UINT64 (**)(CONST CHAR8 *, UINTN, CONST CHAR8 *))(
                  (UINT8 *)PlatformProtocol + 8
                  );
    if (DebugFunc != NULL) {
      DebugFunc (FileName, LineNumber, Description);
    }
  }
}

/**
  Reads an unaligned 64-bit value from memory.
  Equivalent to ReadUnaligned64 from BaseLib.

  @param[in] Buffer  Pointer to the buffer to read from.

  @return The 64-bit value read from the buffer.

**/
UINT64
EFIAPI
ReadUnaligned64 (
  IN CONST VOID  *Buffer
  )
{
  if (Buffer == NULL) {
    DebugReport (mFilePathUnaligned, 192, mAssertBuffer);
    return 0;
  }

  return *(const UINT64 *)Buffer;
}

/**
  Retrieves and caches the HOB list pointer.

  Walks the system configuration table entries to find the HOB list
  matching gEfiHobMemoryAllocModuleGuid. Caches the result in gHobList.

  @param[in] ImageHandle  The image handle (unused in this implementation).

  @return Pointer to the HOB list, or NULL.

**/
VOID *
GetHobList (
  IN EFI_HANDLE  ImageHandle
  )
{
  UINTN   HobCount;
  UINTN   Index;
  VOID    *TableEntry;

  if (gHobList != NULL) {
    return gHobList;
  }

  //
  // Walk the system configuration table.
  // gST + 104 = NumberOfTableEntries (offset 0x68 in EFI_SYSTEM_TABLE)
  // gST + 112 = ConfigurationTable  (offset 0x70)
  //
  HobCount = *(UINTN *)((UINT8 *)gST + 104);
  if (HobCount > 0) {
    for (Index = 0; Index < HobCount; Index++) {
      TableEntry = (VOID *)(*(UINTN *)((UINT8 *)gST + 112) + (Index * 24));
      if (CompareHobGuid (
            (EFI_GUID *)&mHobMemoryAllocModuleGuid,
            (EFI_GUID *)TableEntry
            )) {
        //
        // Found -- the data pointer is at offset +16 in the table entry.
        //
        gHobList = *(VOID **)((UINT8 *)TableEntry + 16);
        break;
      }
    }
  }

  if (gHobList == NULL) {
    DebugWrite (0x8000000000000000ULL, mAssertEfiError, 0x800000000000000EULL);
    DebugReport (mFilePathHobLib, 54, mAssertNotEfiError);
    DebugReport (mFilePathHobLib, 55, mAssertHobList);
  }

  return gHobList;
}

/**
  Compares two GUIDs for equality.

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

  @retval TRUE   The GUIDs are identical.
  @retval FALSE  The GUIDs differ or a pointer is NULL.

**/
BOOLEAN
EFIAPI
CompareHobGuid (
  IN EFI_GUID  *Guid1,
  IN EFI_GUID  *Guid2
  )
{
  UINT64  FirstHalf;
  UINT64  SecondHalf;

  if ((Guid1 == NULL) || (Guid2 == NULL)) {
    return FALSE;
  }

  FirstHalf  = ReadUnaligned64 (Guid1);
  SecondHalf = ReadUnaligned64 ((UINT8 *)Guid1 + 8);

  return (FirstHalf  == ReadUnaligned64 (Guid2)) &&
         (SecondHalf == ReadUnaligned64 ((UINT8 *)Guid2 + 8));
}

/**
  Writes debug output via the platform protocol's debug function.
  Reads CMOS index register to determine the debug verbosity level.

  @param[in] ErrorCode       EFI error code or status value.
  @param[in] FormatString    Format string to output.
  @param[in] ...             Variable argument list.

  @return The result code from the debug output function.

**/
UINT8
DebugWrite (
  IN UINT64       ErrorCode,
  IN CONST CHAR8  *FormatString,
  ...
  )
{
  VOID     *PlatformProtocol;
  UINT8    (*DebugFunc)(UINT64, CONST CHAR8 *, ...);
  UINT8    Result;
  UINT8    CmosIndex;
  UINT8    CmosValue;

  PlatformProtocol = GetPlatformProtocol ();
  if (PlatformProtocol == NULL) {
    return 0;
  }

  //
  // Read CMOS register to determine debug verbosity.
  // Index register 0x70, data register 0x71.
  //
  CmosValue = __inbyte (0x70);
  __outbyte (0x70, (CmosValue & 0x80) | 0x4B);
  CmosIndex = __inbyte (0x71);
  gCmosIndex = CmosIndex;

  if (CmosIndex > 3) {
    if (CmosIndex == 0) {
      //
      // Read debug level from platform-specific memory location.
      //
      CmosIndex = (*(volatile UINT8 *)0xFDAF0490 & 2) | 1;
    }
  }

  Result = CmosIndex - 1;
  if (Result <= 0xFD) {
    if (CmosIndex == 1) {
      ErrorCode = 0x80000004ULL;    // DEBUG_INFO
    } else {
      ErrorCode = 0x80000006ULL;    // DEBUG_VERBOSE
    }

    if ((ErrorCode & ErrorCode) != 0) {
      DebugFunc = *(UINT8 (**)(UINT64, CONST CHAR8 *, ...))PlatformProtocol;
      if (DebugFunc != NULL) {
        return DebugFunc (ErrorCode, FormatString, &FormatString + 1);
      }
    }
  }

  return Result;
}

//
// -------------------------------------------------------------------------
// Entry Point
// -------------------------------------------------------------------------
//

/**
  Main entry point for the Static Sku Data DXE driver.

  Initializes UEFI globals, locates the platform protocol, retrieves
  the HOB list, and installs static SKU data tables.

  Table installation calls the protocol's function at offset +16,
  passing protocol GUID, data pointer, and size.

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

  @retval EFI_SUCCESS           The driver initialized successfully.
  @retval EFI_INVALID_PARAMETER ImageHandle or SystemTable was NULL.
  @retval EFI_NOT_FOUND         The platform protocol was not found.

**/
EFI_STATUS
EFIAPI
ModuleEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS          Status;
  VOID                *PlatformProtocol;
  UINT64              (*InstallTableFunc)(VOID *, VOID *, VOID *, UINT64);

  //
  // Store global UEFI handles for library-style access.
  //
  gImageHandle = ImageHandle;
  if (ImageHandle == NULL) {
    DebugReport (mFilePathBootServices, 51, mAssertImageHandle);
    return EFI_INVALID_PARAMETER;
  }

  gST = SystemTable;
  if (SystemTable == NULL) {
    DebugReport (mFilePathBootServices, 57, mAssertSystemTable);
    return EFI_INVALID_PARAMETER;
  }

  gBS = SystemTable->BootServices;
  if (gBS == NULL) {
    DebugReport (mFilePathBootServices, 63, mAssertBootServices);
    return EFI_INVALID_PARAMETER;
  }

  gRT = SystemTable->RuntimeServices;
  if (gRT == NULL) {
    DebugReport (mFilePathRuntimeServices, 47, mAssertRuntimeServices);
    return EFI_INVALID_PARAMETER;
  }

  //
  // Initialize the platform protocol and HOB list.
  //
  GetHobList (ImageHandle);

  //
  // Locate the platform protocol interface.
  //
  Status = gBS->LocateProtocol (
                  (EFI_GUID *)&mPlatformProtocolGuid,
                  NULL,
                  &PlatformProtocol
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  gPlatformProtocol = PlatformProtocol;

  //
  // Install static SKU data protocol.
  // Protocol GUID: 0FF8A1CF-A0AB-4AC0-BFC9-34A78F68DD8A
  // Install function at offset +16 in the protocol interface.
  //
  InstallTableFunc = (UINT64 (*)(VOID *, VOID *, VOID *, UINT64))(
                       (UINT8 *)PlatformProtocol + 16
                       );
  if (InstallTableFunc == NULL) {
    return EFI_UNSUPPORTED;
  }

  //
  // Install the Static SKU Data protocol with PIRQ routing info.
  //
  Status = (EFI_STATUS)InstallTableFunc (
                         PlatformProtocol,
                         (VOID *)&mStaticSkuDataProtocolGuid,
                         (VOID *)&mPlatformHobBlock.PirqProtocolGuid,
                         24
                         );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Install the PIRQ routing data table.
  //
  Status = (EFI_STATUS)InstallTableFunc (
                         PlatformProtocol,
                         (VOID *)&mPirqProtocolGuid,
                         (VOID *)&mPirqDataTable,
                         16
                         );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Install the ACPI processor info table.
  //
  Status = (EFI_STATUS)InstallTableFunc (
                         PlatformProtocol,
                         (VOID *)&mAcpiProcessorInfoGuid,
                         (VOID *)&mAcpiProcessorBlock.AcpiProcGuid,
                         16
                         );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}