Newer
Older
AMI-Aptio-BIOS-Reversed / PurleySktPkg / SouthClusterLbg / PchInit / Dxe / PchInitDxe / PchInitDxe.c
@Ajax Dong Ajax Dong 2 days ago 60 KB Full restructure
/**
 * PchInitDxe.c - PCH Initialization DXE Driver
 *
 * Source: PchInitDxe.efi from HR650X Purley Platform (LBG PCH)
 * Source Tree: PurleySktPkg/SouthClusterLbg/PchInit/Dxe/
 *
 * This driver initializes the PCH during DXE phase including:
 *   - PCH policy HOB consumption
 *   - USB preconditioning (XHCI warm reset)
 *   - PCIe Root Port (RP) ASPM/L1SS/ClkReq configuration
 *   - RST PCIe storage remapping
 *   - Uplink (x16/x8) port programming
 *   - S3 Boot Script initialization
 *   - PCH ACPI NVS protocol installation
 *   - NHLT (Non-HDAudio ACPI Table) publishing
 *   - TraceHub (MIPI) reveal
 *   - GPIO configuration via sideband interface
 */

#include "PchInitDxe.h"

//
// ---------------------------------------------------------------------------
// Global Variable Definitions
// ---------------------------------------------------------------------------
//
#pragma section(".data")

// UEFI core globals (set by PchInitDxeEntry)
static EFI_HANDLE               gImageHandle      = NULL;
static EFI_SYSTEM_TABLE        *gSystemTable       = NULL;
static EFI_BOOT_SERVICES       *gBootServices      = NULL;
static EFI_RUNTIME_SERVICES    *gRuntimeServices   = NULL;
static EFI_DXE_SERVICES        *gDxeServicesTable  = NULL;
static VOID                    *gPciUsraProtocol   = NULL;

// PCD - PCIe Segment Bus Table
static VOID                    *gPcieSegBusTable   = NULL;
static UINT8                    gPcieSegBusBuffer[0x48];  // max PCD size

// PCH Policy HOB (from PEI phase)
static PCH_POLICY_HOB          *mPchPolicyHob      = NULL;

// HOB list pointer
static VOID                    *mHobList           = NULL;

// PCH LPC bridge MMIO base
static UINTN                    mLpcMmioBase       = 0;

// USB Precondition context
static USB_PRECONDITION_CONTEXT *mUsbContext       = NULL;

// USB ACPI timer tracking
static BOOLEAN                  mUsbAcpiTimerDone  = FALSE;
static UINT32                   mUsbAcpiBaseCounter = 0;

// PCH NVS Area pointer
static PCH_NVS_AREA            *mPchNvsArea        = NULL;

// PCIe IO Trap address
static UINT16                   mPcieIoTrapAddress = 0;

// S3 Boot Script globals
static BOOT_SCRIPT_ENTRY       *mBootScriptTable   = NULL;
static EFI_EVENT                mDxeSmmReadyToLockEvent = NULL;
static EFI_SMM_BASE2_PROTOCOL  *mSmmBase2          = NULL;
static VOID                    *mSmmBootScriptBuffer = NULL;
static BOOLEAN                  mBootScriptInited  = FALSE;
static BOOLEAN                  mSmmBootScriptInited = FALSE;
static VOID                    *mSmmReadyToBootReg = NULL;
static VOID                    *mSmmCallbackReg1   = NULL;
static VOID                    *mSmmCallbackReg2   = NULL;

// L1SS memory pool allocator
static UINT32                   mL1ssPoolAvailable = 0;

// L1SS configuration table
static UINT16                  *mL1ssConfigTable   = NULL;

// NHLT feature enable flags
static BOOLEAN                  mNhltDmic0         = FALSE;
static BOOLEAN                  mNhltDmic1         = FALSE;
static BOOLEAN                  mNhltSsp0          = FALSE;
static BOOLEAN                  mNhltSsp1          = FALSE;
static BOOLEAN                  mNhltSsp2          = FALSE;
static BOOLEAN                  mNhltBtRender      = FALSE;
static BOOLEAN                  mNhltBtCapture     = FALSE;
static BOOLEAN                  mNhltI2S           = FALSE;

// Saved ImageHandle copy
static EFI_HANDLE               mSavedImageHandle  = NULL;

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

static
EFI_STATUS
PchInitDxeEntry (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE    *SystemTable
  );

static
EFI_STATUS
PchInitEntryPoint (
  IN EFI_HANDLE           ImageHandle
  );

static
VOID
PchInitGlobalDataInit (
  VOID
  );

static
EFI_STATUS
PchInitS3BootScriptInit (
  VOID
  );

static
EFI_STATUS
PchS3BootScriptDeinit (
  VOID
  );

static
EFI_STATUS
PchInitS3BootScriptSave (
  VOID
  );

static
EFI_STATUS
PchRevealTraceHub (
  VOID
  );

static
VOID
PchUplinksInit (
  VOID
  );

static
EFI_STATUS
InitializePchDevice (
  VOID
  );

static
EFI_STATUS
PchUsbPrecondition (
  VOID
  );

static
BOOLEAN
EFIAPI
PchUsbPreconditionTimerCallback (
  IN VOID   *Context,
  IN UINT8   Port
  );

static
EFI_STATUS
ConfigurePmForRstRemapping (
  IN UINT8   ControllerIndex,
  IN UINT8   Enable
  );

static
VOID
PchPcieRpEarlyConfig (
  VOID
  );

static
EFI_STATUS
PchConfigureRpfnMapping (
  VOID
  );

static
VOID
PchOnEndOfDxe (
  VOID
  );

static
VOID
EFIAPI
PchOnEndOfDxeWrapper (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  );

static
VOID
EFIAPI
PchOnReadyToBoot (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  );

static
VOID
EFIAPI
PchOnReadyToBootEx (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  );

static
VOID
EFIAPI
PchOnExitBootServices (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  );

static
VOID
EFIAPI
PchOnProtocolNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  );

static
VOID
EFIAPI
PchOnSmmReadyToLockNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  );

static
VOID
EFIAPI
PchOnSmmReadyToBootNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  );

static
EFI_STATUS
PchAcpiOnEndOfDxe (
  VOID
  );

static
EFI_STATUS
InstallPchNvsProtocol (
  IN EFI_HANDLE  ImageHandle
  );

static
VOID
PchUpdateNvsArea (
  VOID
  );

static
EFI_STATUS
PublishNhltAcpiTable (
  IN PCH_POLICY_HOB  *Policy
  );

static
EFI_STATUS
LockDownUnusedRstPcie (
  IN UINT8   Controller
  );

static
EFI_STATUS
ConfigureRstPcieStorageRemapping (
  IN UINT8   Controller,
  IN UINT8   Function,
  IN UINT8   Device
  );

static
EFI_STATUS
RstPcieStorageRemappingLateConfig (
  VOID
  );

static
EFI_STATUS
DetectPcieStorageDevices (
  VOID
  );

static
EFI_STATUS
PcieEndPointL1ssConfig (
  IN UINTN    Address,
  IN UINT32  *Config,
  IN UINT8    L1ssOffset,
  IN UINTN    Index,
  IN UINT16  *NextL1ssAddr
  );

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

/**
 * Standard UEFI DXE driver entry point.
 */
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE    *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = PchInitDxeEntry (ImageHandle, SystemTable);
  if (EFI_ERROR (Status)) {
    Status = PchS3BootScriptDeinit ();
  }

  return Status;
}

// ===========================================================================
// SECTION 1: Initialization Sequence
// ===========================================================================

/**
 * AutoGen-style DXE entry. Initializes all UEFI core globals,
 * configures PCH debug port, copies PCIe segment bus table from PCD,
 * and initializes the S3 boot script system.
 */
static
EFI_STATUS
PchInitDxeEntry (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE    *SystemTable
  )
{
  EFI_STATUS      Status;
  UINT64          PcdValue;
  UINTN           PcdSize;
  UINT16          PostCode;
  BOOLEAN         PostCode0;
  UINT32          TimerValue;

  // --- Save UEFI core globals ---
  gImageHandle = ImageHandle;
  gSystemTable = SystemTable;
  gBootServices = SystemTable->BootServices;
  gRuntimeServices = SystemTable->RuntimeServices;

  // Get DxeServicesTable
  Status = gSystemTable->GetConfigurationTable (
                          &gEfiDxeServicesTableGuid,
                          (VOID **)&gDxeServicesTable
                          );
  ASSERT_EFI_ERROR (Status);
  ASSERT (gDxeServicesTable != NULL);

  // Get PCI USRA protocol
  if (gPciUsraProtocol == NULL) {
    Status = gBootServices->LocateProtocol (
                             &gEfiPciUsraProtocolGuid,
                             NULL,
                             &gPciUsraProtocol
                             );
    ASSERT_EFI_ERROR (Status);
    ASSERT (gPciUsraProtocol != NULL);
  }

  // Initialize HOB list
  PchInitGlobalDataInit ();

  // Copy PCIe Segment Bus Table from PCD
  PcdValue = PcdGet64 (PcdPcieSegmentBusTable);
  PcdSize = PcdGetSize (PcdPcieSegmentBusTable);
  ASSERT (sizeof (gPcieSegBusBuffer) >= PcdSize);
  CopyMem (gPcieSegBusBuffer, (VOID *)(UINTN)PcdValue, PcdSize);

  // PCH debug port sequence (POST code 0x80)
  PostCode = IoRead8 (0x80);
  PostCode0 = (PostCode & 0x200) != 0;
  TimerValue = IoRead32 (0x508) & 0xFFFFFF;

  IoWrite8 (0x80, 0);   // enable POST
  while (((TimerValue + 357 - IoRead32 (0x508)) & 0x800000) == 0) {
    IoDelayShort ();     // delay loop
  }
  IoWrite8 (0x80, 1);   // disable POST

  if (PostCode0) {
    IoWrite8 (0x80, 0);  // restore original state
  } else {
    IoWrite8 (0x80, 1);
  }

  // Initialize S3 boot script system
  Status = PchInitS3BootScriptInit ();
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
 * Main PCH initialization entry point (PchInit.c).
 * Consumes PCH policy HOB, loads RSTe Option ROMs, initializes
 * PCH devices, installs ACPI NVS protocol, and registers UEFI events.
 */
static
EFI_STATUS
PchInitEntryPoint (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS            Status;
  EFI_HOB_GUID_TYPE    *GuidHob;
  PCH_POLICY_HOB       *PolicyHob;
  EFI_EVENT             Event;
  VOID                 *Registration;
  UINTN                 Index;

  DEBUG ((DEBUG_INFO, "Uefi PchInitEntryPoint() Start\n"));
  DEBUG ((DEBUG_INFO, "Common PchInitEntryPoint() Start\n"));

  mSavedImageHandle = ImageHandle;

  // --- Step 1: Locate PCH Policy HOB ---
  GuidHob = GetNextGuidHob (&gPchPolicyHobGuid);
  ASSERT (GuidHob != NULL);
  mPchPolicyHob = (PCH_POLICY_HOB *)(GuidHob + 1);

  // Load SATA RSTe Option ROM if configured
  if ((*(UINT32 *)((UINT8 *)mPchPolicyHob + 2231) & 0x2000) != 0) {
    Status = gBootServices->LocateProtocol (
                             &gPchSataRsteProtocolGuid,
                             NULL,
                             &Registration
                             );
    if (EFI_ERROR (Status)) {
      Status = gBootServices->ConnectController (
                               ImageHandle,
                               &gPchSataRsteProtocolGuid,
                               NULL,
                               FALSE
                               );
      if (!EFI_ERROR (Status)) {
        DEBUG ((DEBUG_INFO, "Sata RSTe EFI OpRom load triggered\n"));
      } else {
        DEBUG ((DEBUG_ERROR, "Sata RSTe EFI OpRom load NOT triggered (Status:%r)!!!\n", Status));
      }
    }
  }

  // Load Secondary SATA RSTe Option ROM
  if ((*(UINT32 *)((UINT8 *)mPchPolicyHob + 3440) & 0x2000) != 0) {
    Status = gBootServices->LocateProtocol (
                             &gSecondarySataRsteProtocolGuid,
                             NULL,
                             &Registration
                             );
    if (EFI_ERROR (Status)) {
      Status = gBootServices->ConnectController (
                               mSavedImageHandle,
                               &gSecondarySataRsteProtocolGuid,
                               NULL,
                               FALSE
                               );
      if (!EFI_ERROR (Status)) {
        DEBUG ((DEBUG_INFO, "Secondary Sata RSTe EFI OpRom load triggered\n"));
      } else {
        DEBUG ((DEBUG_ERROR, "Secondary Sata RSTe EFI OpRom load NOT triggered (Status:%r)!!!\n", Status));
      }
    }
  }

  DEBUG ((DEBUG_INFO, "Common PchInitEntryPoint() End\n"));

  // --- Step 2: Initialize PCH Devices ---
  DEBUG ((DEBUG_INFO, "InitializePchDevice() Start\n"));

  PchCycleDecodingPwrmBaseGet (&Registration);

  {
    PCH_POLICY_HOB  *DeviceConfig;
    UINT8           *Buffer;

    Buffer = AllocateZeroPool (sizeof (PCH_POLICY_HOB));
    ASSERT (Buffer != NULL);

    if (Buffer != NULL) {
      Buffer[0] = 1;  // config version
      PchInitDeviceConfig (Buffer);

      // USB Precondition
      if ((mPchPolicyHob->UsbOtgEnable & 1) != 0) {
        PchUsbPrecondition ();
        *((UINT64 *)Buffer + 1) = (UINT64)mUsbContext;
      }

      // Configure Power Management for RST Remapping
      Status = ConfigurePmForRstRemapping (
                *(UINT8 *)((UINT8 *)mPchPolicyHob + 3508),
                *(UINT8 *)((UINT8 *)mPchPolicyHob + 3509)
                );
      ASSERT_EFI_ERROR (Status);

      // Early PCIe RP configuration (ASPM/L1SS)
      PchPcieRpEarlyConfig ();

      // Configure RP Function Number mapping
      Status = PchConfigureRpfnMapping ();
      ASSERT_EFI_ERROR (Status);

      // Install device config protocol
      Status = gBootServices->InstallMultipleProtocolInterfaces (
                               &Event,
                               &gPchDeviceConfigProtocolGuid,
                               Buffer,
                               NULL
                               );
      ASSERT_EFI_ERROR (Status);
    } else {
      ASSERT (FALSE);  // allocation failure
    }
  }

  DEBUG ((DEBUG_INFO, "InitializePchDevice() End\n"));

  // --- Step 3: Install PCH NVS Protocol ---
  Status = InstallPchNvsProtocol (ImageHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // --- Step 4: Register Protocol Notify ---
  Status = UefiLibRegisterProtocolNotify (
             &gPchSmmProtocolNotifyGuid,
             PchOnProtocolNotify,
             &Registration
             );

  // --- Step 5: Register EndOfDxe Event ---
  Status = gBootServices->CreateEvent (
                           EVT_NOTIFY_SIGNAL,
                           TPL_CALLBACK,
                           PchOnEndOfDxeWrapper,
                           NULL,
                           &Event
                           );
  ASSERT_EFI_ERROR (Status);
  Status = gBootServices->SetTimer (
                           Event,
                           TimerEventSignal,
                           PchOnEndOfDxeWrapper,
                           0
                           );
  ASSERT_EFI_ERROR (Status);

  // --- Step 6: Register ReadyToBoot Event ---
  Status = UefiLibCreateReadyToBootEvent (&Event);
  ASSERT_EFI_ERROR (Status);

  // --- Step 7: Register Additional ReadyToBoot Notify ---
  Status = gBootServices->CreateEvent (
                           EVT_NOTIFY_SIGNAL,
                           TPL_NOTIFY,
                           PchOnReadyToBootEx,
                           NULL,
                           &Event
                           );
  ASSERT_EFI_ERROR (Status);

  // --- Step 8: Register ExitBootServices Event ---
  Status = UefiLibCreateLegacyBootEvent (&Registration);
  ASSERT_EFI_ERROR (Status);

  DEBUG ((DEBUG_INFO, "Uefi PchInitEntryPoint() End\n"));

  return Status;
}

// ===========================================================================
// SECTION 2: PCH Device Configuration
// ===========================================================================

/**
 * Main PCH device initialization. Programs PMC base, PCR registers,
 * PCIe RPs, USB, and other PCH controllers.
 */
static
EFI_STATUS
InitializePchDevice (
  VOID
  )
{
  EFI_STATUS     Status;
  UINTN          PwrmBase;
  UINTN          AcpiBase;
  UINTN          MmioBase;
  UINTN          Index;
  UINTN          RpCount;
  UINT16         DeviceId;
  UINT8          PchSku;
  UINT32         Data32;

  // --- Get base addresses ---
  Status = PchCycleDecodingPwrmBaseGet (&PwrmBase);
  Status = PchCycleDecodingAcpiBaseGet (&AcpiBase);
  MmioBase = PchPciExpressBaseAddress (0, 0, 0);
  PchSku = PchInfoLibGetPchSku ();

  // --- Program PMC registers ---
  // PMC base: read PCR, set SLP_S0 and various PM registers
  PchPcrRead (PID_PCH_IOSF, 0x1D0, 4, (UINT8 *)&Data32);
  Data32 |= BIT0;  // enable PMC
  PchPcrWrite (PID_PCH_IOSF, 0x1D0, 4, Data32);

  // --- Program P2SB registers ---
  // Configure P2SB MMIO base and hide

  // --- Program GPIO communities ---
  // For each GPIO community, configure PCR pad config registers

  // --- Program SATA controller ---
  // Configure SATA BARs, interrupt, and port enable

  // -- USB Precondition (XHCI warm reset) --
  if ((*(UINT8 *)((UINT8 *)mPchPolicyHob + 2263) & 1) != 0) {
    PchUsbPrecondition ();
  }

  // --- RSTe Power Management configuration ---
  Status = ConfigurePmForRstRemapping (
            mPchPolicyHob->RstRemapController0,
            mPchPolicyHob->RstRemapEnable
            );
  ASSERT_EFI_ERROR (Status);

  // --- Early PCIe RP configuration ---
  PchPcieRpEarlyConfig ();

  // --- RP Function Number mapping ---
  Status = PchConfigureRpfnMapping ();
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}

/**
 * Early configuration of all PCIe Root Ports.
 * Programs ASPM, L1SS, clock request, and LTR per port.
 */
static
VOID
PchPcieRpEarlyConfig (
  VOID
  )
{
  UINTN   RpCount;
  UINTN   Index;
  UINTN   RpMmioBase;
  UINT8   Device;
  UINT8   Function;
  UINT32  RpConfig;
  UINT16  AspmVal;
  INT32   L1ssVal;

  RpCount = (PchInfoLibGetPchSku () == PCH_SKU_LEWISBURG) ? 20 : 12;

  for (Index = 0; Index < RpCount; Index++) {
    // Get RP device/function
    GetPchPcieRpDevFun ((UINT8)Index, &Device, &Function);
    RpMmioBase = PchPciExpressBaseAddress (0, Device, Function);

    // Read config space header
    // Check for device present (Vendor ID != 0xFFFF)

    // Program ASPM for this RP
    AspmVal = (Index << 8) |
              (mPchPolicyHob->PcieRpMaxPayload[Index] << 4) |
              mPchPolicyHob->PcieRpMaxReadReq[Index];
    PcieRpConfigureAspm (2, RpMmioBase + 0x44C, &AspmVal, &RpConfig);

    // Program L1SS for this RP
    L1ssVal = (Index << 16) |
              (mPchPolicyHob->PcieRpMaxPayload[Index] << 8) |
              mPchPolicyHob->PcieRpMaxReadReq[Index];
    PcieRpConfigureL1ss (2, RpMmioBase + 0x4B4, &L1ssVal, (VOID *)&AspmVal, 1, 1);

    // Configure GPIO CLKREQ for this RP
    if (*(UINT32 *)(RpMmioBase + 0x450) & BIT16) {
      GpioConfigurePcieRpClkReq (2, RpMmioBase + 0x450, NULL, RpMmioBase + 0x450);
    }
  }
}

/**
 * Power management configuration for RST PCIe storage remapping.
 * Programs per-port power management registers.
 */
static
EFI_STATUS
ConfigurePmForRstRemapping (
  IN UINT8   ControllerIndex,
  IN UINT8   Enable
  )
{
  EFI_STATUS    Status;
  UINT8         SataMode;
  UINTN         SataMmioBase;
  UINTN         Index;
  UINTN         PortCount;

  SataMode = mPchPolicyHob->SataControllerMode;

  if (SataMode == 0) {
    DEBUG ((DEBUG_INFO, "Can't perform RST PCIe Storage Remapping when Sata Controller is Disabled\n"));
    return EFI_UNSUPPORTED;
  }

  if (SataMode != 2) {  // not RAID mode
    DEBUG ((DEBUG_INFO, "Can't perform RST PCIe storage remapping when Sata Controller mode is not RAID mode\n"));
    return EFI_UNSUPPORTED;
  }

  DEBUG ((DEBUG_INFO, "ConfigurePmForRstRemapping: Low Power Programming - Recommended Setting\n"));

  // Get SATA controller MMIO base
  SataMmioBase = MmioWrite32 (0, 23, 0);

  PortCount = (PchInfoLibGetPchSku () == PCH_SKU_LEWISBURG) ? 8 : 3;

  for (Index = 0; Index < PortCount; Index++) {
    // Program port power management registers
    // Disable/Enable RST remap per port based on policy
    UINT8  *PortCfg = (UINT8 *)mPchPolicyHob + 2131 + (Index * 4);

    if ((*PortCfg & 2) == 0) {
      // Port not used by RST - configure power management
      Mmiowrite32 (SataMmioBase + 0x98 + (Index * 0x100), 0x80000000);
      Mmiowrite32 (SataMmioBase + 0x9C + (Index * 0x100), 0x00000000);
    }
  }

  // Configure per-port GPIO CLKREQ
  GpioConfigurePcieRpClkReq (1, SataMmioBase + 0x90, NULL, SataMmioBase + 0x90);
  GpioConfigurePcieRpClkReq (2, SataMmioBase + 0x9C, NULL, SataMmioBase + 0x9C);

  // Program SATA controller power management
  Mmiowrite32 (SataMmioBase + 0x9C, 0x80000000 | (Enable << 16));

  return EFI_SUCCESS;
}

// ===========================================================================
// SECTION 3: USB Precondition
// ===========================================================================

/**
 * XHCI USB preconditioning. Performs warm reset and port
 * programming to prepare USB ports for OS usage.
 */
static
EFI_STATUS
PchUsbPrecondition (
  VOID
  )
{
  EFI_STATUS                    Status;
  USB_PRECONDITION_CONTEXT     *Context;
  EFI_PCI_IO_PROTOCOL          *PciIo;
  UINTN                         XhciBase;
  UINT32                        Usb2PortCount;
  UINT32                        MmioBase;
  UINTN                         Index;

  if ((mPchPolicyHob->UsbOtgEnable & 1) == 0) {
    return EFI_SUCCESS;
  }

  // Locate XHCI PCI IO protocol
  Status = gBootServices->LocateProtocol (
                           &gEfiPciIoProtocolGuid,
                           NULL,
                           (VOID **)&PciIo
                           );
  ASSERT_EFI_ERROR (Status);

  // Get XHCI MMIO base
  XhciBase = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0x10, 1, &XhciBase);
  XhciBase &= 0xFFFFFFF0;

  DEBUG ((DEBUG_INFO, "XHCI base address %lx\n", XhciBase));

  // Enable XHCI MMIO
  MmioBase = MmioWrite32 (0, 20, 0);
  *(UINT32 *)(MmioBase + 16) = (UINT32)XhciBase;
  MmioWrite8 ((UINT8 *)(MmioBase + 4), 6);  // enable bus master

  // Get USB2 port count from XHCI capability registers
  Usb2PortCount = (*(UINT32 *)(XhciBase + 0x8008) >> 8) & 0xFF;

  // Allocate precondition context
  Context = AllocateZeroPool (sizeof (USB_PRECONDITION_CONTEXT));
  ASSERT (Context != NULL);

  if (Context != NULL) {
    Context->Signature = USB_PRECOND_SIGNATURE;
    Context->PortCount = Usb2PortCount;

    // Build port bitmap
    for (Index = 0; Index < Usb2PortCount; Index++) {
      UINT32  PortSc = *(UINT32 *)(XhciBase + 0x480 + (Index * 16));
      if (PortSc & BIT0) {
        Context->PortBitmap |= (1 << Index);
        *(UINT32 *)(XhciBase + 0x480 + (Index * 16)) =
          (PortSc & 0xFFFFFDED) | 0x210;
      }
    }

    // Set timer handler
    mUsbAcpiTimerDone = FALSE;
    PchCycleDecodingAcpiBaseGet (&MmioBase);
    if (MmioBase) {
      mUsbAcpiBaseCounter = IoRead32 (MmioBase + 8) & 0xFFFFFF;
    }

    CopyMem (Context + 3, &mUsbAcpiBaseCounter, 32);
    *((UINT8 *)Context + 96) = 0;
    Context->TimerCallback = PchUsbPreconditionTimerCallback;
    mUsbContext = (USB_PRECONDITION_CONTEXT *)(Context + 1);
  }

  // Restore XHCI MMIO config
  Mmiowrite32 (MmioBase + 4, MmioRead32 (MmioBase + 4) & 0xFFF9);
  *(UINT32 *)(MmioBase + 16) = 0;

  // Close XHCI MMIO window
  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x10, 1, &XhciBase);

  return EFI_SUCCESS;
}

/**
 * Timer callback for USB preconditioning.
 * Polls ACPI timer for timeout, programs XHCI port registers.
 */
static
BOOLEAN
EFIAPI
PchUsbPreconditionTimerCallback (
  IN VOID   *Context,
  IN UINT8   Port
  )
{
  USB_PRECONDITION_CONTEXT *UsbContext;
  UINT32                    XhciBar;
  UINTN                     Index;
  UINTN                     PortCount;

  UsbContext = BASE_CR (Context, USB_PRECONDITION_CONTEXT, Context);

  if (UsbContext->Signature != USB_PRECOND_SIGNATURE) {
    ASSERT (UsbContext->Signature == USB_PRECOND_SIGNATURE);
    return FALSE;
  }

  if (UsbContext->Done) {
    return FALSE;
  }

  // Wait for ACPI timer synchronization
  if (!mUsbAcpiTimerDone) {
    UINTN   LoopCount;
    UINT32  AcpiBase;
    UINT32  CurrentTimer;

    LoopCount = 0;
    while (LoopCount < 500) {
      PchCycleDecodingAcpiBaseGet (&AcpiBase);
      if (AcpiBase) {
        CurrentTimer = IoRead32 (AcpiBase + 8) & 0xFFFFFF;
        if (CurrentTimer >= mUsbAcpiBaseCounter &&
            CurrentTimer <= mUsbAcpiBaseCounter + 0x100000 + 179001) {
          // Timer progressed, OK
        }
        if (CurrentTimer >= mUsbAcpiBaseCounter &&
            CurrentTimer <= mUsbAcpiBaseCounter + 179001) {
          mUsbAcpiTimerDone = TRUE;
          mUsbAcpiBaseCounter = 0;
          break;
        }
        if (CurrentTimer + 0x100000 > mUsbAcpiBaseCounter + 179001) {
          mUsbAcpiBaseCounter = CurrentTimer;
        }
      }
      MicroSecondDelay (100);
      LoopCount++;
      if (mUsbAcpiTimerDone) {
        break;
      }
    }
  }

  // Get XHCI MMIO base and program ports
  XhciBar = MmioWrite32 (
              (UINT8)UsbContext->BarIndex,
              (UINT8)UsbContext->Bus,
              (UINT8)UsbContext->Device
              );

  if (UsbContext->PortBitmap != 0) {
    BOOLEAN PortsPending = FALSE;
    PortCount = UsbContext->PortCount;

    for (Index = 0; Index < PortCount; Index++) {
      if ((1 << Index) & UsbContext->PortBitmap) {
        UINT32  *PortReg = (UINT32 *)((XhciBar & 0xFFFFFFF0) + (Index * 16));
        if (*PortReg & BIT0) {
          PortsPending = TRUE;
          // Program port for warm reset
          *PortReg = (*PortReg & 0xFF01FFFD) | 0x103E0;
        } else {
          UsbContext->PortBitmap &= ~(1 << Index);
        }
      }
    }

    if (PortsPending) {
      MicroSecondDelay (20000);
      for (Index = 0; Index < PortCount; Index++) {
        if ((1 << Index) & UsbContext->PortBitmap) {
          UINT32  *PortReg = (UINT32 *)((XhciBar & 0xFFFFFFF0) + (Index * 16));
          *PortReg = (*PortReg & 0xFF01FFFD) | 0x10201;
        }
      }
    }

    UsbContext->Done = TRUE;
  }

  return (UsbContext->PortBitmap & (1 << Port)) != 0;
}

// ===========================================================================
// SECTION 4: Uplink Port Programming
// ===========================================================================

/**
 * Configures PCH Uplink ports (x16 and x8 PCIe ports).
 * Programs max payload size and max read size for uplink connections.
 */
static
VOID
PchUplinksInit (
  VOID
  )
{
  EFI_STATUS   Status;
  UINTN        Bus;
  UINTN        Device;
  UINT16       VendorId;
  UINTN        RpOffset;
  UINT8        MaxPayload;
  UINT8        MaxReadSize;

  if (mPchPolicyHob == NULL) {
    DEBUG ((DEBUG_ERROR, "\nERROR!!! PchUplinksInit() - mPchPolicyHob is a NULL pointer.\n"));
    return;
  }

  // Determine PCH SKU
  UINT8 PchSku = PchInfoLibGetPchSku ();

  // --- Find x16 Uplink Port ---
  BOOLEAN FoundX16 = FALSE;
  for (Device = 0; Device < 0xFF; Device++) {
    MmioBase = MmioWrite32 (Device, 0, 0);
    VendorId = MmioRead32 (MmioBase + 2);

    if ((UINT16)VendorId == 0x37C0) {
      // Found x16 Uplink (Device ID = 0x37C0)
      FoundX16 = TRUE;

      // Program Max Payload Size
      MaxPayload = *(UINT8 *)((UINT8 *)mPchPolicyHob + 2116);
      UINTN MpsReg = MmioBase + 52;

      switch (MaxPayload) {
        case 0:  IoWrite32 (MpsReg, 0); break;
        case 3:  IoWrite32 (MpsReg, 5); break;
        case 4:  IoWrite32 (MpsReg, 6); break;
        case 5:  IoWrite32 (MpsReg, 9); break;
        case 6:  IoWrite32 (MpsReg, 10); break;
        default: IoWrite32 (MpsReg, 0); break;
      }

      // Program Max Read Size
      MaxReadSize = *(UINT8 *)((UINT8 *)mPchPolicyHob + 2118);
      UINTN MrsReg = MmioBase + 34;

      switch (MaxReadSize) {
        case 0:  IoWrite32 (MrsReg, 0); break;
        case 1:  IoWrite32 (MrsReg, 1); break;
        case 2:  IoWrite32 (MrsReg, 2); break;
        default:
          DEBUG ((DEBUG_ERROR, "PchUplink x16 programming error! Unsupported Max Payload Size!\n"));
          break;
      }

      // Program downstream ports (function 0-5)
      for (UINTN Func = 0; Func < 6; Func++) {
        UINTN DsMmio = MmioWrite32 (Device + 1, Func, 0);
        MmioRead32 (DsMmio + 2);
        MmioWrite8 (DsMmio + 272, 0x2000);
      }

      break;
    }
  }

  if (!FoundX16) {
    DEBUG ((DEBUG_ERROR, "PchUplink programming error! Can not find the Uplink x16 port.\n"));
  }

  // --- Find x8 Uplink Port (for certain PCH SKUs) ---
  if (PchSku == 3) {
    MmioBase = mLpcMmioBase;
    if (mLpcMmioBase == 0) {
      mLpcMmioBase = MmioWrite32 (0, 31, 0);
    }
  }

  UINT16 LpcVidDid = MmioRead32 (mLpcMmioBase + 2);
  if (LpcVidDid != 0xA1C3 && LpcVidDid != 0xA246 && LpcVidDid != 0xA242) {
    // No secondary uplink needed
    if (!FoundX16) return;
    goto ProgramDownstream;
  }

  // Find x8 Uplink
  for (Device = 0; Device < 0xFF; Device++) {
    MmioBase = MmioWrite32 (Device, 0, 0);
    VendorId = MmioRead32 (MmioBase + 2);

    if ((UINT16)VendorId == 0x37C1) {
      // Found x8 Uplink (Device ID = 0x37C1)
      // Program Max Payload Size
      MaxPayload = *(UINT8 *)((UINT8 *)mPchPolicyHob + 2117);

      switch (MaxPayload) {
        case 0:  IoWrite32 (MmioBase + 52, 0); break;
        case 3:  IoWrite32 (MmioBase + 52, 5); break;
        case 4:  IoWrite32 (MmioBase + 52, 6); break;
        case 5:  IoWrite32 (MmioBase + 52, 9); break;
        case 6:  IoWrite32 (MmioBase + 52, 10); break;
        default: IoWrite32 (MmioBase + 52, 16); break;
      }

      // Program Max Read Size
      MaxReadSize = *(UINT8 *)((UINT8 *)mPchPolicyHob + 2119);
      switch (MaxReadSize) {
        case 0:  IoWrite32 (MmioBase + 34, -8); break;
        case 1:  IoWrite32 (MmioBase + 34, 1); break;
        case 2:  IoWrite32 (MmioBase + 34, 2); break;
        default:
          DEBUG ((DEBUG_ERROR, "PchUplink x8 programming error! Unsupported Max Payload Size!\n"));
          break;
      }

ProgramDownstream:
      // Program downstream port at function 2
      MmioBase = MmioWrite32 (Device + 1, 2, 0);
      MmioRead32 (MmioBase + 2);
      MmioWrite8 (MmioBase + 272, 0x2000);
      break;
    }
  }

  if (!FoundX16) {
    DEBUG ((DEBUG_ERROR, "PchUplink programming error! Can not find the Uplink x8 port.\n"));
  }
}

// ===========================================================================
// SECTION 5: ACPI NVS Protocol
// ===========================================================================

/**
 * Allocates and installs the PCH NVS protocol.
 * The NVS area is a 0x26D byte buffer shared with ACPI ASL code.
 */
static
EFI_STATUS
InstallPchNvsProtocol (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS  Status;
  VOID       *NvsBuffer;
  UINTN       Index;

  DEBUG ((DEBUG_INFO, "Install PCH NVS protocol\n"));

  // Allocate NVS buffer (0x26D bytes)
  Status = gBootServices->AllocatePages (
                           AllocateAnyPages,
                           EfiACPIMemoryNVS,
                           EFI_SIZE_TO_PAGES (0x26D),
                           &NvsBuffer
                           );
  ASSERT_EFI_ERROR (Status);

  ZeroMem (NvsBuffer, 0x26D);

  // Set signature
  *(UINT32 *)NvsBuffer = 0x01070000;

  // Install protocol
  Status = gBootServices->InstallMultipleProtocolInterfaces (
                           &ImageHandle,
                           &gPchNvsProtocolGuid,
                           NvsBuffer,
                           NULL
                           );
  ASSERT_EFI_ERROR (Status);

  // Copy GPIO group info into NVS buffer
  {
    UINT8  *GpioInfo = (UINT8 *)GpioGetGroupInfoTable ();

    for (Index = 0; Index < 3; Index++) {
      *((UINT8 *)NvsBuffer + Index + 377) = *(GpioInfo + Index * 64 - 33);
      *((UINT8 *)NvsBuffer + Index + 380) = *(GpioInfo + Index * 64);
      *((UINT8 *)NvsBuffer + Index + 383) = *(GpioInfo + Index * 64 - 63);
      *((UINT16 *)NvsBuffer + Index + 193) = *((UINT16 *)GpioInfo + Index * 32 - 31);
      *((UINT8 *)NvsBuffer + Index + 392) = *(GpioInfo + Index * 64 - 60);
      *((UINT32 *)NvsBuffer + Index + 98) = *((UINT32 *)GpioInfo + Index * 16 - 14);
      *((UINT16 *)NvsBuffer + Index + 203) = *((UINT16 *)GpioInfo + Index * 32 - 26);
      *((UINT32 *)NvsBuffer + Index + 103) = *((UINT32 *)GpioInfo + Index * 16 - 12);
      *((UINT16 *)NvsBuffer + Index + 212) = *((UINT16 *)GpioInfo + Index * 32 - 22);
      *((UINT16 *)NvsBuffer + Index + 215) = *((UINT16 *)GpioInfo + Index * 32 - 21);
      *((UINT16 *)NvsBuffer + Index + 218) = *((UINT16 *)GpioInfo + Index * 32 - 20);
      *((UINT16 *)NvsBuffer + Index + 221) = *((UINT16 *)GpioInfo + Index * 32 - 19);
      *((UINT32 *)NvsBuffer + Index + 112) = *((UINT32 *)GpioInfo + Index * 16 - 21);
      *((UINT32 *)NvsBuffer + Index + 115) = *((UINT32 *)GpioInfo + Index * 16 - 20);
      *((UINT32 *)NvsBuffer + Index + 118) = *((UINT32 *)GpioInfo + Index * 16 - 19);
      *((UINT32 *)NvsBuffer + Index + 121) = *((UINT32 *)GpioInfo + Index * 16 - 18);
    }
  }

  // Register ACPI EndOfDxe processing
  Status = gBootServices->CreateEvent (
                           EVT_NOTIFY_SIGNAL,
                           TPL_NOTIFY,
                           PchAcpiOnEndOfDxe,
                           NULL,
                           &Event
                           );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
 * Populates the PCH NVS area with runtime configuration data
 * including PCH SKU, LPC device ID, PCIe RP config, GPIO info, etc.
 */
static
VOID
PchUpdateNvsArea (
  VOID
  )
{
  UINTN   Index;
  UINT16  PchSku;
  UINT16  LpcDeviceId;
  UINTN   P2sbVal;

  if (mPchNvsArea == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "PchUpdateNvsArea\n"));

  PchSku = PchInfoLibGetPchSku ();
  mPchNvsArea->PchSku = PchSku;

  // Set GPIO port config
  mPchNvsArea->GpioPadCfg[0] = *(UINT8 *)((UINT8 *)mPchPolicyHob + 2028);

  // Set SATA port presence
  UINTN RpCount = (PchSku == 1) ? 20 : 12;
  for (Index = 0; Index < RpCount; Index++) {
    mPchNvsArea->GpioPadCfg[Index] = *(UINT8 *)((UINT8 *)mPchPolicyHob + 46 + (Index * 100));
  }

  // Set PCIe segment bus number for NVS
  mPchNvsArea->GpioBaseAddr = PcieAddressDecode (0);

  // Fill in PCIe RP BDF per port
  Index = 8;
  UINTN Offset = 204;
  for (Index = 0; Index < RpCount; Index++) {
    UINT8   Device;
    UINT8   Function;
    UINT64  RpBdf;

    GetPchPcieRpDevFun ((UINT8)Index, &Device, &Function);
    mPchNvsArea->PcieRpBusDevFun[Index] = (UINT32)((UINT8)Function | (Device << 16));

    mPchNvsArea->PcieRpMaxPayload[Offset] =
      *(UINT16 *)((UINT8 *)mPchPolicyHob + 48 + (Index * 100));
    mPchNvsArea->PcieRpMaxReadReq[Offset] =
      *(UINT16 *)((UINT8 *)mPchPolicyHob + 50 + (Index * 100));

    Offset += 2;
    Index += 1;
  }

  // Set PCH SKU and LPC Device ID
  mPchNvsArea->PchSku = PchSku;
  LpcDeviceId = PchInfoLibGetLpcDeviceId ();
  mPchNvsArea->LpcDeviceId = LpcDeviceId;

  // Get P2SB value
  PchP2sbRead ((UINTN)mPchNvsArea, NULL, (INT32 *)&P2sbVal);
  switch (P2sbVal & 3) {
    case 1: mPchNvsArea->PchIoApicBase = 0xFEC01000; break;
    case 2: mPchNvsArea->PchIoApicBase = 0xFEC02000; break;
    case 3: mPchNvsArea->PchIoApicBase = 0xFEC03000; break;
    default: mPchNvsArea->PchIoApicBase = 0xFEC00000; break;
  }

  // Set TraceHub enable flag
  mPchNvsArea->Tolud[8] = (*(UINT8 *)((UINT8 *)mPchPolicyHob + 2727) & 1);

  // Configure GPIO pad ownership
  {
    INT32   IoApic0, IoApic1, IoApic2;
    GpioGetPchGpiStatus (&IoApic0, &IoApic1, &IoApic2);
    mPchNvsArea->PchIoApicBaseLength =
      (3 << (2 * IoApic2)) | (2 << (2 * IoApic1)) | (1 << (2 * IoApic0));
  }

  // Set per-port GPIO pad native function status
  for (INT32 Pin = 256; Pin < 0x10D; Pin++) {
    if (Pin != IoApic0 && Pin != IoApic1 && Pin != IoApic2) {
      UINT8  GpioGroup;
      UINT32 Ownership;

      GpioGetGroupInfoTable (&GpioGroup);
      for (UINT8 Pad = 0; Pad < *(UINT32 *)(60 * (UINT8)Pin + GpioGetGroupInfoTable() + 56); Pad++) {
        UINT32 PadAddr;
        GpioGetPadConfigAddr (0x1000000 + Pad, 0, 0x1000000 + Pad - 0x1000000, &PadAddr);
        if (PadAddr) {
          UINT32 LateCfg[4];
          ConfigureRstPcieStorageRemapLate (0x1000000 + Pad, LateCfg);
          if (((LateCfg[0] >> 13) & 0x1F) == 9 && ((LateCfg[0] >> 13) & 0xE0) == 0x20) {
            mPchNvsArea->SataPortInterface[Pin - 256] |= (1 << Pad);
          }
        }
      }
    }
  }

  // Set SATA port SSD presence
  mPchNvsArea->SataPortInterface[11] =
    ((*(UINT8 *)((UINT8 *)mPchPolicyHob + 2903) & 3) == 2);

  // Find SATA port with speed 20 / multiplier 2
  if (*(UINT8 *)((UINT8 *)mPchPolicyHob + 3036)) {
    UINT8  *SataInfo = (UINT8 *)mPchPolicyHob + 3041;
    for (Index = 0; Index < *(UINT8 *)((UINT8 *)mPchPolicyHob + 3036); Index++) {
      if (*(SataInfo - 1) == 20 && *SataInfo == 2) {
        mPchNvsArea->SataPortInterface[12] = *(SataInfo + 2);
      }
      SataInfo += 4;
    }
  }
}

// ===========================================================================
// SECTION 6: ACPI EndOfDxe Processing (NHLT + NVS Patch)
// ===========================================================================

/**
 * ACPI EndOfDxe handler.
 * Publishes NHLT ACPI table, updates NVS area, and patches
 * NVS addresses into ASL name space.
 */
static
EFI_STATUS
PchAcpiOnEndOfDxe (
  VOID
  )
{
  EFI_STATUS   Status;
  UINT16       HdAudioVidDid;

  DEBUG ((DEBUG_INFO, "PchAcpiOnEndOfDxe() Start\n"));

  PchInfoLibGetPchSku ();
  gBootServices->CloseEvent (gEvent);

  // --- HD Audio ACPI Init ---
  DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() Start\n"));

  // Check HD Audio presence
  HdAudioVidDid = MmioRead32 ((UINT16 *)MmioWrite32 (0, 31, 3) + 2);
  if (HdAudioVidDid == 0xFFFF ||
      (*(UINT8 *)((UINT8 *)mPchPolicyHob + 2735) & 4) == 0) {
    DEBUG ((DEBUG_INFO, "AudioDSP: Non-HDAudio ACPI Table (NHLT) not set!\n"));
  } else {
    EFI_STATUS NhltStatus;
    NhltStatus = PublishNhltAcpiTable (
                   (UINT32 *)((UINT8 *)mPchPolicyHob + 2735)
                   );
    DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() End - Status = %r\n", NhltStatus));
  }

  // Update NVS area
  PchUpdateNvsArea ();

  // Initialize ASL update library
  Status = AslUpdateLibInit ();
  ASSERT_EFI_ERROR (Status);

  // Patch PCH NVS address into ASL (Name: NPCH, value: NVS base)
  {
    UINT16 NvsSegment = 0x26D;
    UINT32 NvsAddr = (UINT32)(UINTN)mPchNvsArea;

    Status = AslUpdateNameValue (
               SIGNATURE_32 ('N', 'P', 'C', 'H'),  // 0x4843504E
               (INT16 *)&NvsAddr,
               4
               );
    ASSERT_EFI_ERROR (Status);

    Status = AslUpdateNameValue (
               SIGNATURE_32 ('N', 'P', 'C', 'L'),  // 0x4C43504E
               &NvsSegment,
               2
               );
    ASSERT_EFI_ERROR (Status);
  }

  DEBUG ((DEBUG_INFO, "PchAcpiOnEndOfDxe() End\n"));

  return EFI_SUCCESS;
}

// ===========================================================================
// SECTION 7: NHLT ACPI Table Publishing
// ===========================================================================

/**
 * Publishes the Non-HD Audio ACPI Table (NHLT) for audio DSP.
 * Locates the NHLT from existing ACPI tables (XSDT/RSDT),
 * constructs endpoint descriptors, and installs the table.
 */
static
EFI_STATUS
PublishNhltAcpiTable (
  IN PCH_POLICY_HOB  *Policy
  )
{
  EFI_STATUS               Status;
  EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  VOID                    *NhltBuffer;
  UINTN                    NhltSize;
  EFI_ACPI_SDT_PROTOCOL   *AcpiSdt;
  EFI_ACPI_TABLE_VERSION   TableVersion;
  VOID                    *Table;

  DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() Start\n"));

  // Parse feature mask to set global enable flags
  switch (Policy->FeatureMask & 3) {
    case 1: mNhltDmic1 = TRUE; break;
    case 2: mNhltSsp0 = TRUE; break;
    case 3: mNhltDmic0 = TRUE; break;
  }

  if (Policy->FeatureMask & 4) {
    mNhltSsp1 = TRUE;
    mNhltSsp2 = TRUE;
  }

  if (Policy->FeatureMask & 8) {
    mNhltBtRender = TRUE;
    mNhltBtCapture = TRUE;
    mNhltI2S = TRUE;
  }

  // Locate ACPI table protocol
  Status = gBootServices->LocateProtocol (
                           &gEfiAcpiTableProtocolGuid,
                           NULL,
                           (VOID **)&AcpiTable
                           );
  if (!EFI_ERROR (Status) && AcpiTable != NULL) {
    // Construct NHLT endpoints
    VOID    *Endpoints;
    UINTN    TotalSize;

    NhltEndpointConstructor (&NhltBuffer, &TotalSize);

    // Construct NHLT header
    DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor() Start\n"));
    ((EFI_ACPI_DESCRIPTION_HEADER *)NhltBuffer)->Signature =
      EFI_ACPI_3_0_NHLT_SIGNATURE;
    ((EFI_ACPI_DESCRIPTION_HEADER *)NhltBuffer)->Length =
      (UINT32)(TotalSize + 37);
    ((EFI_ACPI_DESCRIPTION_HEADER *)NhltBuffer)->Revision = 0;
    CopyMem (NhltBuffer + 10, "INTEL ", 6);
    NhltBuffer[28] = 2;
    DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor(), NhltAcpiTable->Header.Length = %d B\n",
           ((EFI_ACPI_DESCRIPTION_HEADER *)NhltBuffer)->Length));

    // Install ACPI table
    Status = AcpiTable->SetAcpiTable (
                          AcpiTable,
                          NhltBuffer,
                          (BOOLEAN)((EFI_ACPI_DESCRIPTION_HEADER *)NhltBuffer)->Length,
                          &TableVersion
                          );
    DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() End\n"));
  } else {
    Status = EFI_NOT_FOUND;
  }

  // Locate NHLT from existing RSDT/XSDT for NVS update
  DEBUG ((DEBUG_INFO, "LocateNhltAcpiTable() Start\n"));

  Status = gSystemTable->GetConfigurationTable (
                           &gEfiAcpiTableGuid,
                           &Table
                           );
  if (EFI_ERROR (Status) || Table == NULL) {
    DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp == NULL\n"));
    return EFI_NOT_FOUND;
  }

  // Scan XSDT/RSDT for NHLT signature
  {
    UINT32  *EntryArray;
    UINTN    EntryCount;
    UINTN    Index;

    // RSDT/XSDT parsing
    EntryArray = (UINT32 *)((UINT8 *)Table + 36);
    EntryCount = (*(UINT32 *)((UINT8 *)Table + 4) - 36) / 8;

    for (Index = 0; Index < EntryCount; Index++) {
      EFI_ACPI_DESCRIPTION_HEADER *TableHeader;

      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)EntryArray[Index];
      if (TableHeader->Signature == EFI_ACPI_3_0_NHLT_SIGNATURE) {
        DEBUG ((DEBUG_INFO, "Found NhltTable, Address = 0x%016x\n", (UINTN)TableHeader));

        // Update NVS area with NHLT address/length
        mPchNvsArea->NhltAddress = (UINT64)(UINTN)TableHeader;
        mPchNvsArea->NhltLength = TableHeader->Length;
        mPchNvsArea->PostProcessingModuleMask = Policy->PostProcessingModuleMask;

        NhltAcpiTableDump ((UINTN)TableHeader, (UINTN)mPchNvsArea, 0);
        break;
      }
    }
  }

  return Status;
}

// ===========================================================================
// SECTION 8: EndOfDxe Processing
// ===========================================================================

/**
 * EndOfDxe callback. Locks down SATA, programs PCIe IO Trap,
 * reveals TraceHub, configures P2SB.
 */
static
VOID
PchOnEndOfDxe (
  VOID
  )
{
  UINTN       SmbusMmio;
  UINT16      SmbusVidDid;
  UINT16     *IoTrapAddr;
  EFI_STATUS  Status;

  DEBUG ((DEBUG_INFO, "Common PchOnEndOfDxe() Start\n"));

  // Lock down unused RST PCIe on primary SATA
  LockDownUnusedRstPcie (1);

  // Lock down unused RST PCIe on secondary SATA (if present)
  SmbusMmio = MmioWrite32 (0, 17, 5);
  SmbusVidDid = MmioRead32 ((UINT16 *)(SmbusMmio + 2));
  if (SmbusVidDid != 0xFFFF) {
    LockDownUnusedRstPcie (2);
  }

  // Get PCIe IO Trap address
  Status = gBootServices->LocateProtocol (
                           &gPchIoTrapProtocolGuid,
                           NULL,
                           (VOID **)&IoTrapAddr
                           );
  ASSERT_EFI_ERROR (Status);
  mPcieIoTrapAddress = *IoTrapAddr;
  DEBUG ((DEBUG_INFO, "PcieIoTrapAddress: %0x\n", mPcieIoTrapAddress));

  // Process locks in InitializePchDevice
  if ((*(UINT8 *)((UINT8 *)mPchPolicyHob + 2763) & 1) == 0) {
    INT32   AspmVal = 1;
    INT32   L1ssVal = -1;

    PchPciExpressBaseAddress (198, 0x0C, 0xFFFFFFFF, 1);
    PcieRpConfigureAspm (2, 0xFDB00000 + 0x1C, &AspmVal, &L1ssVal);
    PcieRpConfigureL1ss (2, 0xFDA0FE0C, (UINT32)&AspmVal, (UINT32)&AspmVal, 1, 1);
    PchPciExpressBaseAddress (187, 0xB1C, 0xFFFFFFFF, 256);
  }

  Status = InitializePchDevice ();
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Error when processing locks in PchOnEndOfDxe \n"));
    ASSERT (FALSE);
  }

  // Program PCIe IO Trap boot script
  if (mPcieIoTrapAddress) {
    UINT8   BootScriptEntry[19];
    UINT32  Zero = 0;

    BootScriptEntry[0] = 0;
    BootScriptEntry[1] = 23;  // IO_WRITE opcode
    BootScriptEntry[2] = 2;   // width = UINT16
    *(UINT64 *)&BootScriptEntry[3] = mPcieIoTrapAddress;
    BootScriptEntry[11] = 1;
    *(UINT32 *)&BootScriptEntry[12] = 0;

    // Write entry to boot script
    VOID *EntryBuf = BootScriptAllocateEntry (23);
    if (EntryBuf != NULL) {
      CopyMem (EntryBuf, BootScriptEntry, 19);
      CopyMem ((UINT8 *)EntryBuf + 19, &Zero, 4);
      BootScriptSaveAsSmmCallback (EntryBuf);
    }
  } else {
    ASSERT (FALSE);
  }

  // --- P2SB Configuration ---
  DEBUG ((DEBUG_INFO, "ConfigureP2sbOnEndOfDxe() Start\n"));
  PchSteppingCheck ();
  PchInfoLibGetPchSku ();

  if ((mPchPolicyHob->P2sbUnlock & 1) == 0) {
    UINTN  P2sbBase = MmioWrite32 (0, 31, 1);
    BOOLEAN AcpiBaseSet;

    PchCycleDecodingAcpiBaseIsSet (P2sbBase, &AcpiBaseSet);
    *(UINT8 *)(P2sbBase + 227) |= BIT7;  // P2SB hide
    if (!AcpiBaseSet) {
      *(UINT8 *)(P2sbBase + 225) = 1;   // ACPI base disable
    }
  }

  DEBUG ((DEBUG_INFO, "ConfigureP2sbOnEndOfDxe() End\n"));
  DEBUG ((DEBUG_INFO, "Common PchOnEndOfDxe() End\n"));
}

/**
 * Wrapper for PchOnEndOfDxe registered with EndOfDxe event.
 */
static
VOID
EFIAPI
PchOnEndOfDxeWrapper (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  DEBUG ((DEBUG_INFO, "Uefi PchOnEndOfDxe() Start\n"));
  gBootServices->CloseEvent (Event);
  PchOnEndOfDxe ();
  DEBUG ((DEBUG_INFO, "Uefi PchOnEndOfDxe() End\n"));
}

/**
 * ReadyToBoot callback.
 * Programs boot script for PCIe IO Trap address.
 */
static
VOID
EFIAPI
PchOnReadyToBoot (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() Start\n"));

  if (Event != NULL) {
    gBootServices->CloseEvent (Event);
  }

  if (mPcieIoTrapAddress) {
    IoWrite16 (mPcieIoTrapAddress, 0);
  } else {
    ASSERT (FALSE);
  }

  DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() End\n"));
}

/**
 * Additional ReadyToBoot notification callback.
 */
static
VOID
EFIAPI
PchOnReadyToBootEx (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  if (Event != NULL) {
    gBootServices->CloseEvent (Event);
  }
}

/**
 * ExitBootServices callback.
 * Sets flag in NVS area indicating OS is taking over.
 */
static
VOID
EFIAPI
PchOnExitBootServices (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  // Signal OS handoff in NVS area
  mPchNvsArea->DebugFlag = 1;
}

// ===========================================================================
// SECTION 9: Protocol Notify Callback
// ===========================================================================

/**
 * Protocol installed notification callback.
 * Triggers Uplink init and xHCI MMIO programming when
 * PchSmmProtocol is installed.
 */
static
VOID
EFIAPI
PchOnProtocolNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  UINTN   MmioBase;

  DEBUG ((DEBUG_INFO, "Uefi PchOnProtocolNotify() Start\n"));

  // Check if PchSmmProtocol is already installed
  Status = gBootServices->LocateProtocol (
                           &gPchSmmProtocolNotifyGuid,
                           NULL,
                           &Registration
                           );
  if (!EFI_ERROR (Status)) {
    return;  // Already installed, skip
  }

  gBootServices->CloseEvent (Event);

  // Initialize Uplink ports
  PchUplinksInit ();

  // Configure xHCI MMIO
  MmioBase = MmioWrite32 (0, 31, 0);
  *(UINT8 *)(MmioBase + 4) |= 3;

  // Check PCH stepping for LPC config
  if (*(UINT8 *)PciExpressLibRead (0xFC) == 4) {
    PchLpcWriteIo (462, 0);
    PchLpcWriteIo (464, 45248);
  }

  // Reveal TraceHub if PMC not configured
  UINTN PwrmBase;
  PchCycleDecodingPwrmBaseGet (&PwrmBase);
  if ((*(UINT32 *)(PwrmBase + 1488) & 1) == 0) {
    PchRevealTraceHub ();
  }

  // Check xHCI status
  MmioBase = MmioWrite32 (0, 20, 2);
  UINT16 XhciVidDid = MmioRead32 ((UINT16 *)MmioBase);
  if (XhciVidDid != 0xFFFF) {
    if ((*(UINT32 *)(MmioBase + 16) & 0xFFFFF000) != 0 ||
        *(UINT32 *)(MmioBase + 20) != 0) {
      *(UINT8 *)(MmioBase + 4) |= 2;  // enable bus master
    }
  }
}

// ===========================================================================
// SECTION 10: TraceHub Configuration
// ===========================================================================

/**
 * Reveals TraceHub (MIPI) controller by programming
 * SW_LBAR, FW_LBAR, and MTB_LBAR registers.
 */
static
EFI_STATUS
PchRevealTraceHub (
  VOID
  )
{
  UINT32  *PmcMmio;

  DEBUG ((DEBUG_INFO, "PchRevealTraceHub() - Start\n"));

  // Check if TraceHub is disabled in policy
  if ((*(UINT8 *)((UINT8 *)mPchPolicyHob + 3308) & 4) == 0) {
    PchPciExpressBaseAddress (188, 0x938, 0xFFFFFFFE, 0);
  }

  // Program TraceHub FW_LBAR and SW_LBAR
  PmcMmio = (UINT32 *)MmioWrite32 (0, 31, 7);

  DEBUG ((DEBUG_INFO, "PchRevealTraceHub() - BEFORE: SW_LBAR = 0x%08x\n", PmcMmio[6]));

  PmcMmio[7] = 0;                              // FW_LBAR high
  PmcMmio[6] = 0xFE200000;                     // SW_LBAR low

  DEBUG ((DEBUG_INFO, "PchRevealTraceHub() - FW_LBAR = 0x%08x\n", PmcMmio[28]));
  DEBUG ((DEBUG_INFO, "PchRevealTraceHub() - MTB_LBAR = 0x%08x\n", PmcMmio[4]));
  DEBUG ((DEBUG_INFO, "PchRevealTraceHub() - SW_LBAR = 0x%08x\n", PmcMmio[6]));

  return EFI_SUCCESS;
}

// ===========================================================================
// SECTION 11: SATA Lockdown
// ===========================================================================

/**
 * Locks down unused RST PCIe ports on a SATA controller.
 */
static
EFI_STATUS
LockDownUnusedRstPcie (
  IN UINT8   Controller
  )
{
  UINTN   SataMmio;
  UINT8  *PortCfg;
  UINTN   PortCount;

  if (Controller == 1) {
    // Primary SATA (Device 23, Function 0)
    SataMmio = MmioWrite32 (0, 23, 0);
    PortCount = (PchInfoLibGetPchSku () == PCH_SKU_LEWISBURG) ? 8 : 3;
    PortCfg = (UINT8 *)mPchPolicyHob + 2131;
  } else if (Controller == 2) {
    // Secondary SATA (Device 17, Function 5)
    SataMmio = MmioWrite32 (0, 17, 5);
    PortCfg = (UINT8 *)mPchPolicyHob + 3364;
    PortCount = 6;
  } else {
    DEBUG ((DEBUG_ERROR, "Error: Invalid SATA controller during SATA late DXE configuration!\n"));
    ASSERT (FALSE);
    return EFI_INVALID_PARAMETER;
  }

  UINT16  EnableMask = 0;
  UINT32  PortEnable;

  if (PchInfoLibGetPchSku () == 2) {
    // Lewisburg-Refresh: use secondary port config
    PortCount = 6;
    UINT16 SasPorts = MmioRead32 ((UINT16 *)(SataMmio + 146));

    for (Index = 0; Index < (UINTN)((PchInfoLibGetPchSku () == 1) ? 8 : 3); Index++) {
      UINT32  PortConfig = *(UINT32 *)((UINT8 *)mPchPolicyHob + 8 * Index + 2143);
      if ((PortConfig & 2) != 0 || ((256 << Index) & SasPorts) != 0 ||
          (*(UINT8 *)((UINT8 *)mPchPolicyHob + 2131) & 2) != 0 || (PortConfig & 8) != 0) {
        EnableMask |= (PortConfig & 1) << Index;
      }
    }

    MmioWrite8 ((UINT16 *)(SataMmio + 144), (~(UINT8)EnableMask & 7) << 8);
    GpioConfigurePcieRpClkReq (1, SataMmio + 144, NULL, SataMmio + 144);
    MmioWrite8 ((UINT16 *)(SataMmio + 146), EnableMask);
  } else {
    for (Index = 0; Index < PortCount; Index++) {
      if ((*(PortCfg + 12) & 2) != 0 ||
          ((1 << Index) & *(UINT32 *)(SataMmio + 148)) != 0 ||
          (*PortCfg & 2) != 0 ||
          (*(PortCfg + 12) & 8) != 0) {
        EnableMask |= (*(PortCfg + 12) & 1) << Index;
      }
      PortCfg += 4;
    }

    *(UINT32 *)(SataMmio + 144) |= ((UINT8)~EnableMask << 16);
    GpioConfigurePcieRpClkReq (2, SataMmio + 144, NULL, SataMmio + 144);
    MmioWrite8 ((UINT16 *)(SataMmio + 148), EnableMask);
  }

  GpioConfigurePcieRpClkReq (1, SataMmio + 144, NULL, SataMmio + 144);
  *(UINT32 *)(SataMmio + 156) |= BIT31;  // SATA lockdown

  GpioConfigurePcieRpClkReq (2, SataMmio + 156, NULL, SataMmio + 156);

  return EFI_SUCCESS;
}

// ===========================================================================
// SECTION 12: S3 Boot Script
// ===========================================================================

/**
 * Initializes the S3 boot script system.
 * Allocates boot script buffer, registers SMM callbacks.
 */
static
EFI_STATUS
PchInitS3BootScriptInit (
  VOID
  )
{
  EFI_STATUS              Status;
  UINT64                  BufferSize;
  VOID                   *BootScriptBuffer;
  EFI_SMM_BASE2_PROTOCOL *SmmBase2;
  VOID                   *Registration;

  // Check if boot script is already initialized (via PCD 137)
  if (mBootScriptTable == NULL) {
    Status = gBootServices->AllocatePages (
                             AllocateAnyPages,
                             EfiReservedMemoryType,
                             1,
                             &BootScriptBuffer
                             );
    ASSERT_EFI_ERROR (Status);

    mBootScriptTable = (BOOT_SCRIPT_ENTRY *)BootScriptBuffer;
    mBootScriptInited = TRUE;

    // Set PCD to store boot script pointer
    PcdSet64 (PcdS3BootScriptTablePtr, (UINT64)BootScriptBuffer);
    ZeroMem (BootScriptBuffer, 0x20);

    // Register for SmmReadyToLock notification
    mDxeSmmReadyToLockEvent = UefiLibRegisterProtocolNotify (
                                &gEfiDxeSmmReadyToLockProtocolGuid,
                                PchOnSmmReadyToLockNotify,
                                &Registration
                                );
    ASSERT (mDxeSmmReadyToLockEvent != NULL);
  }

  // Save boot script table pointer
  mBootScriptTable = (BOOT_SCRIPT_ENTRY *)(UINTN)PcdGet64 (PcdS3BootScriptTablePtr);

  // Check for SMM base2 protocol
  Status = gBootServices->LocateProtocol (
                           &gEfiSmmBase2ProtocolGuid,
                           NULL,
                           (VOID **)&SmmBase2
                           );
  if (!EFI_ERROR (Status) && SmmBase2 != NULL) {
    BOOLEAN InSmram;

    Status = SmmBase2->InSmram (SmmBase2, &InSmram);
    if (!EFI_ERROR (Status) && InSmram &&
        SmmBase2->GetSmstLocation (SmmBase2, &gSmmSystemTable) != NULL) {

      // Allocate SMM boot script buffer
      Status = SmmBase2->SmmAllocatePool (
                           SmmBase2,
                           EfiRuntimeServicesData,
                           0x20,
                           &mSmmBootScriptBuffer
                           );
      if (EFI_ERROR (Status)) {
        BufferSize = (UINTN)PcdGet64 (PcdS3BootScriptTableSize);
        Status = SmmBase2->SmmAllocatePool (
                             SmmBase2,
                             EfiRuntimeServicesData,
                             (UINTN)BufferSize,
                             &mSmmBootScriptBuffer
                             );
        ASSERT_EFI_ERROR (Status);
        mSmmBootScriptInited = TRUE;

        PcdSet64 (PcdS3BootScriptTableSmmPtr, (UINT64)mSmmBootScriptBuffer);
        ZeroMem (mSmmBootScriptBuffer, 0x20);

        // Register SMM communication handlers
        Status = SmmBase2->SmmRegisterProtocolNotify (
                             SmmBase2,
                             &gEfiSmmReadyToLockProtocolGuid,
                             PchOnSmmReadyToLockNotify,
                             &Registration
                             );
        ASSERT_EFI_ERROR (Status);

        Status = SmmBase2->SmmRegisterProtocolNotify (
                             SmmBase2,
                             &gEfiSmmReadyToBootProtocolGuid,
                             PchOnSmmReadyToBootNotify,
                             &Registration
                             );
        ASSERT_EFI_ERROR (Status);
      }
    }
  }

  return EFI_SUCCESS;
}

// ===========================================================================
// SECTION 13: Protocol Notify (SMM)
// ===========================================================================

/**
 * SMM ReadyToLock notification handler.
 */
static
VOID
EFIAPI
PchOnSmmReadyToLockNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  DEBUG ((DEBUG_INFO, "%a() in %a module\n", __FUNCTION__, "BootScriptSave.c"));
}

/**
 * SMM ReadyToBoot notification handler.
 */
static
VOID
EFIAPI
PchOnSmmReadyToBootNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
}

/**
 * SMM communication callback for boot script operations.
 */
static
VOID
EFIAPI
PchOnSmmCommunication (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  // Handle SMM communication for boot script
}

// ===========================================================================
// SECTION 14: Helper Function Stubs
// ===========================================================================

/**
 * Initialize HOB list pointer from system configuration table.
 */
static
VOID
PchInitGlobalDataInit (
  VOID
  )
{
  EFI_STATUS  Status;

  if (mHobList == NULL) {
    Status = gSystemTable->GetConfigurationTable (
                             &gEfiHobListGuid,
                             &mHobList
                             );
    ASSERT_EFI_ERROR (Status);
    ASSERT (mHobList != NULL);
  }
}

/**
 * S3 boot script deinitialization (on driver unload).
 */
static
EFI_STATUS
PchS3BootScriptDeinit (
  VOID
  )
{
  // Close events, free buffers
  if (mDxeSmmReadyToLockEvent != NULL) {
    gBootServices->CloseEvent (mDxeSmmReadyToLockEvent);
  }

  if (mBootScriptInited && mBootScriptTable != NULL) {
    PcdSet64 (PcdS3BootScriptTablePtr, 0);
    mBootScriptInited = FALSE;
  }

  return EFI_SUCCESS;
}

/**
 * PCH stepping check for feature support.
 * Verifies PCH stepping/mask to determine which features are available.
 */
UINTN
EFIAPI
PchSteppingCheck (
  VOID
  )
{
  // Returns PCH stepping mask
  return 0;
}

/**
 * Get PCH SKU (Lewisburg = 1, Lewisburg-Refresh = 2).
 * Returns the PCH SKU from silicon register.
 */
UINT8
EFIAPI
PchInfoLibGetPchSku (
  VOID
  )
{
  return PCH_SKU_LEWISBURG;
}

/**
 * Get LPC device identifier.
 */
UINT16
EFIAPI
PchInfoLibGetLpcDeviceId (
  VOID
  )
{
  return 0;
}

/**
 * Read PCH Private Configuration Register (PCR).
 * Access via Port ID + Offset mapped to MMIO.
 */
EFI_STATUS
EFIAPI
PchPcrRead (
  IN UINT8   Pid,
  IN UINT16  Offset,
  IN UINT8   Size,
  OUT UINT8 *Buffer
  )
{
  if ((Size - 1) & Offset) {
    DEBUG ((DEBUG_ERROR, "PchPcrRead error. Invalid Offset: %x Size: %x", Offset, Size));
    ASSERT (FALSE);
    return EFI_INVALID_PARAMETER;
  }

  UINTN  Address = (Offset | ((Pid | 0xFD00) << 16));

  switch (Size) {
    case 1: *Buffer = *(volatile UINT8 *)Address; break;
    case 2: *(UINT16 *)Buffer = MmioRead32 ((UINT16 *)Address); break;
    case 4: *(UINT32 *)Buffer = *(volatile UINT32 *)Address; break;
    default: return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
 * Write PCH Private Configuration Register (PCR).
 * Validates offset alignment and access restrictions via SBI.
 */
EFI_STATUS
EFIAPI
PchPcrWrite (
  IN UINT8   Pid,
  IN UINT16  Offset,
  IN UINT8   Size,
  IN UINT32  Data
  )
{
  UINTN  Address = (Offset | ((Pid | 0xFD00) << 16));

  if ((Offset & 3) != 0) {
    DEBUG ((DEBUG_ERROR, "PchPcrWrite error. Invalid Offset: %x Size: %x", Offset, Size));
    ASSERT (FALSE);
    return EFI_INVALID_PARAMETER;
  }

  *(volatile UINT32 *)Address = Data;
  return EFI_SUCCESS;
}

/**
 * P2SB (Primary to Sideband) read access.
 */
EFI_STATUS
EFIAPI
PchP2sbRead (
  IN UINTN   MmioBase,
  OUT VOID  *Buffer
  )
{
  // Implementation: read P2SB register via MMIO
  return EFI_SUCCESS;
}

/**
 * Check if ACPI base address decode is enabled.
 */
BOOLEAN
EFIAPI
PchCycleDecodingAcpiBaseIsSet (
  IN UINTN   MmioBase,
  OUT BOOLEAN *IsSet
  )
{
  return FALSE;
}

/**
 * Get ACPI base address from PCH.
 */
EFI_STATUS
EFIAPI
PchCycleDecodingAcpiBaseGet (
  OUT UINTN *AcpiBase
  )
{
  return EFI_SUCCESS;
}

/**
 * Get Power Management base address from PCH.
 */
EFI_STATUS
EFIAPI
PchCycleDecodingPwrmBaseGet (
  OUT UINTN *PwrmBase
  )
{
  return EFI_SUCCESS;
}

/**
 * Register a protocol notification handler.
 */
EFI_EVENT
EFIAPI
UefiLibRegisterProtocolNotify (
  IN EFI_GUID  *ProtocolGuid,
  IN EFI_EVENT_NOTIFY  NotifyFunction,
  OUT VOID    **Registration
  )
{
  EFI_STATUS  Status;
  EFI_EVENT   Event;

  ASSERT (ProtocolGuid != NULL);
  ASSERT (NotifyFunction != NULL);
  ASSERT (Registration != NULL);

  Status = gBootServices->CreateEvent (
                           EVT_NOTIFY_SIGNAL,
                           TPL_CALLBACK,
                           NotifyFunction,
                           NULL,
                           &Event
                           );
  ASSERT_EFI_ERROR (Status);

  Status = gBootServices->RegisterProtocolNotify (
                           ProtocolGuid,
                           Event,
                           Registration
                           );
  ASSERT_EFI_ERROR (Status);

  return Event;
}

/**
 * Create a ReadyToBoot event.
 */
EFI_STATUS
EFIAPI
UefiLibCreateReadyToBootEvent (
  OUT EFI_EVENT *Event
  )
{
  return gBootServices->CreateEvent (
                         EVT_NOTIFY_SIGNAL,
                         TPL_CALLBACK,
                         PchOnReadyToBoot,
                         NULL,
                         Event
                         );
}

/**
 * Create a Legacy Boot event.
 */
EFI_STATUS
EFIAPI
UefiLibCreateLegacyBootEvent (
  OUT VOID **Registration
  )
{
  EFI_EVENT  Event;

  return gBootServices->CreateEvent (
                         EVT_NOTIFY_SIGNAL,
                         TPL_CALLBACK,
                         PchOnExitBootServices,
                         NULL,
                         &Event
                         );
}

/**
 * Get PCH PCIe Root Port device and function from port number.
 */
EFI_STATUS
EFIAPI
GetPchPcieRpDevFun (
  IN  UINT8   RpNumber,
  OUT UINT8  *Device,
  OUT UINT8  *Function
  )
{
  // Each PCH PCIe RP occupies 1 device with 1 function
  *Device = RpNumber + 1;
  *Function = 0;
  return EFI_SUCCESS;
}

/**
 * Get PCH PCIe Root Port count.
 */
UINTN
EFIAPI
GetPchPcieRpNumber (
  VOID
  )
{
  return MAX_PCIE_ROOT_PORTS;
}

/**
 * Allocate memory pool.
 */
VOID *
EFIAPI
MemoryAllocatePool (
  IN UINTN  Size
  )
{
  return AllocatePool (Size);
}

/**
 * Free memory pool.
 */
VOID
EFIAPI
MemoryFreePool (
  IN VOID  *Buffer
  )
{
  FreePool (Buffer);
}

/**
 * Microsecond stall wrapper.
 */
VOID
EFIAPI
MemoryStall (
  IN UINTN  Microseconds
  )
{
  gBootServices->Stall (Microseconds);
}

/**
 * IO delay - short wait for PCH reset sequencing.
 */
static
VOID
IoDelayShort (
  VOID
  )
{
  // Short delay for PCH register programming
}

/**
 * IO delay end marker.
 */
static
VOID
IoDelayEnd (
  VOID
  )
{
}