Newer
Older
AMI-Aptio-BIOS-Reversed / SBDXE / SBDXE.c
@Ajax Dong Ajax Dong 2 days ago 42 KB Init
/** @file
  SBDXE -- South Bridge DXE Driver.

  Provides South Bridge initialization for Purley/Lewisburg PCH:
    - Installs driver binding and protocol interfaces
    - Manages XHCI USB port-per-port disable based on HII configuration
    - Configures PCIe segment/bus routing via PCIE_SEG_BUS_TABLE
    - Integrates with S3 Boot Script save/restore and SMM LockBox
    - Detects PCH stepping and SKU for runtime policy decisions

  Copyright (c) 2017-2019, American Megatrends Inc. (AMI)
  Copyright (c) 2017-2019, Intel Corporation.
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/DxeHobLib.h>
#include <Library/PciExpressLib.h>
#include <Library/PrintLib.h>
#include <Protocol/PciIo.h>
#include <Protocol/SmmCommunication.h>
#include <Protocol/PiPcd.h>
#include <Guid/Acpi.h>
#include <Guid/EventGroup.h>

#include "SBDXE.h"

//
// ============================================================================
// Global Data
// ============================================================================
//
EFI_HANDLE            gImageHandle       = NULL;
EFI_SYSTEM_TABLE     *gST                = NULL;
EFI_BOOT_SERVICES    *gBS                = NULL;
EFI_RUNTIME_SERVICES *gRT                = NULL;

//
// HOB list pointer (from DXE HOB library)
//
VOID    *gHobList  = NULL;

//
// PciUsra (MM PCI base) from DxeMmPciBaseLib
//
VOID    *gPciUsra  = NULL;

//
// PciExpress Base Address (from PCD)
//
UINT64  gPciExpressBaseAddr = 0;

//
// PCH stepping / SKU global state
//
UINT32  gPchStepping = 3;    ///< Initial state; determined at first call
UINT32  gPchSku      = 3;

//
// Boot Script / S3 state
//
UINT64   gBootScriptTable     = 0;
UINT64   gBootScriptTable2    = 0;
UINT8    gBootScriptLocked    = 0;
BOOLEAN  gS3BootScriptInitialized     = FALSE;
BOOLEAN  gSmmReadyToLockOccurred      = FALSE;

//
// XHCI USB port disable state: set to TRUE after first callback
//
BOOLEAN  gXhciPortDisableDone = FALSE;

//
// PCD protocol, SMM Communication protocol
//
VOID    *gPcdProtocol         = NULL;
VOID    *gSmmCommunicationProtocol = NULL;

//
// PciUsra via SMM PCI base protocol
//
STATIC VOID  *mPciUsra = NULL;

//
// ============================================================================
// GUID Definitions
// ============================================================================
//
EFI_GUID gPchRcConfigGuid            = { 0x6350F689, 0x6EF9, 0x4B9A, { 0x87, 0xA0, 0xBB, 0xF6, 0x4D, 0x35, 0x08, 0xED }};
EFI_GUID gBootScriptContextGuid      = { 0x5C6590C9, 0x11D5, 0x4A1B, { 0xA8, 0xF5, 0x4B, 0x62, 0x3B, 0x4D, 0x3C, 0x42 }};
EFI_GUID gBootScriptExecutorGuid     = { 0x9BDBB6F3, 0x600A, 0x42FF, { 0xBD, 0x15, 0x92, 0x05, 0x1B, 0x0A, 0xDD, 0x8E }};

EFI_GUID gEfiPciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
EFI_GUID gEfiSmmCommunicationProtocolGuid = EFI_SMM_COMMUNICATION_PROTOCOL_GUID;
EFI_GUID gEfiPcdProtocolGuid             = { 0x11B0836B, 0x1D4A, 0x4BDE, { 0x88, 0x87, 0x7F, 0x06, 0xE2, 0x13, 0x22, 0xC4 }};

//
// GUID for PiSmmCommunicationRegionTable (for SMM LockBox)
//
EFI_GUID gSmmCommRegionGuid          = { 0x8E7BE0F9, 0x3D41, 0x42D9, { 0x9F, 0xFF, 0xAC, 0xC0, 0x88, 0xC2, 0xC8, 0x32 }};

//
// ============================================================================
// Function Prototypes (local)
// ============================================================================
//
STATIC
EFI_STATUS
GetPcdProtocol (
  VOID
  );

STATIC
VOID
SbdInstallPcieSegBusTable (
  VOID
  );

// ============================================================================
// Internal helper: ASSERT macro with message
// ============================================================================

/**
  Internal assertion helper.  Called by ASSERT macros from UEFI libraries.
  Logs the assertion to the debug console and then breaks.
**/
VOID
SbdAssert (
  IN CONST CHAR8  *FileName,
  IN UINTN         LineNumber,
  IN CONST CHAR8  *Description
  );

/**
  Debug print helper.  Routes to the UEFI debug output if the debug level
  is enabled.
**/
VOID
SbdDebugPrint (
  IN UINTN        ErrorLevel,
  IN CONST CHAR8 *Format,
  ...
  );

// ============================================================================
// Internal: PciExpress MMIO address computation
// ============================================================================

/**
  Get the PCI Express MMIO base address from the PCD protocol.

  @return PCI Express MMIO base address, or 0 if unavailable.
**/
UINT64
GetPciExpressBaseAddress (
  VOID
  )
{
  return gPciExpressBaseAddr;
}

// ============================================================================
// PCH SKU Detection
// ============================================================================

/**
  Detect PCH SKU (PCH-H vs PCH-LP) based on LPC/eSPI device ID.

  Reads the LPC device ID via PCI config space and categorizes it:
    - Some device IDs indicate PCH-H (SKU 1)
    - Others indicate PCH-LP (SKU 2)

  @return 1 for PCH-H, 2 for PCH-LP, 3 if unrecognized.
**/
UINT32
GetPchSku (
  VOID
  )
{
  UINTN   LpcDevId;
  UINT32  Sku = 3;

  if (gPchSku == 3) {
    //
    // Read LPC/eSPI device ID from PCI config space (Bus 0, Dev 31, Func 0, offset 2)
    //
    LpcDevId = IoRead16 (PCI_EXPRESS_LIB_ADDRESS (0, 31, 0, 0x02));

    //
    // Check if device ID falls in the PCH-H range
    // PCH-H device IDs typically include A1xx-A14x, A150-A1FF range
    //
    if (((LpcDevId + 24128) & 0xFF70) == 0) {
      //
      // This is PCH-H (SKU 1)
      //
      Sku = 1;
    } else if ((UINT16)(LpcDevId + 25280) <= 8) {
      //
      // This is PCH-LP (SKU 2)
      //
      Sku = 2;
    } else {
      DEBUG ((DEBUG_ERROR, "Unsupported PCH SKU, LpcDeviceId: 0x%04x!\n", (UINT16)LpcDevId));
      ASSERT (!"Unsupported PCH SKU");
    }

    gPchSku = Sku;
  }

  return gPchSku;
}

// ============================================================================
// PCH Stepping Detection
// ============================================================================

/**
  Determine the PCH stepping (silicon revision) by reading the PCI config
  space of the LPC/eSPI controller and the RTC CMOS register.

  Stepping values:
     0  = A0 step
     1  = A1 step
     2  = A2 step
     3  = B0 step
     4  = B1 step
    35  = C1 (PCH-LP D0)
    36  = C2 (PCH-LP D1)
    37  = C3 (PCH-LP D2)
    38  = C4 (PCH-LP D3)
    48  = D0
    49  = D1
    50  = D2
    51  = D3
    52  = E0
    53  = E1
    54  = Unknown/unsupported

  @return PCH stepping identifier.
**/
UINT32
GetPchStepping (
  VOID
  )
{
  UINT32   Stepping;
  UINT8    RevId;
  UINT32   LpcDeviceId;
  UINTN    PchInfoBase;

  if (gPchStepping != 54) {
    return gPchStepping;
  }

  //
  // Read the PCH RID (Revision ID) from PCI config
  // Get the base address for PCH info from the PchInfoLib
  //
  PchInfoBase = PciExpressRead32 (
                  PCI_EXPRESS_LIB_ADDRESS (0, 31, 0, 0x00)
                  );

  RevId = (UINT8)(PchInfoBase >> 8);

  //
  // Read the LPC device ID for stepping decode
  //
  LpcDeviceId = IoRead16 (PCI_EXPRESS_LIB_ADDRESS (0, 31, 0, 0x02));

  //
  // Decode stepping based on Device ID + Rev ID
  //

  //
  // A-stepping devices (LbgA0/A1/A2)
  //
  if (((LpcDeviceId + 24128) & 0xFF70) == 0) {
    //
    // PCH-H with known A-step: map rev ID to stepping
    //
    switch (RevId) {
      case 0x00:
        return 0;   // A0
      case 0x10:
        return 1;   // A1
      case 0x20:
        return 2;   // A2
      case 0x30:
        return 3;   // B0
      case 0x31:
        return 4;   // B1
      default:
        DEBUG ((DEBUG_ERROR,
          "Unsupported PCH Stepping. Supporting PCH stepping starting from LbgA0 and above\n"));
        ASSERT (!"Unsupported PCH Stepping");
        return 54;
    }
  }

  //
  // C-stepping or later (PCH-LP or newer PCH-H)
  //
  if ((UINT16)(LpcDeviceId + 25280) <= 8) {
    switch (RevId) {
      case 0x10:
        return 35;   // C1 / LP D0
      case 0x11:
        return 36;   // C2 / LP D1
      case 0x20:
        return 37;   // C3 / LP D2
      case 0x21:
        return 38;   // C4 / LP D3
      default:
        goto Unsupported;
    }
  }

  //
  // If none of the above, check for D/E stepping
  //
  if (((LpcDeviceId + 24128) & 0xFF70) != 0) {
    return 54;      // Unknown, keep default
  }

  //
  // Check the RTC CMOS register for stepping hints
  //
  {
    UINT8  CmosVal;

    CmosVal = IoRead8 (RTC_INDEX_PORT);
    IoWrite8 (RTC_INDEX_PORT, CmosVal & 0x80 | RTC_REGISTER_B);
    RevId = IoRead8 (RTC_DATA_PORT);

    if (RevId > 3) {
      if (gPchStepping == 0) {
        RevId = MmioRead8 (0xFDAF0490) & 2 | 1;
      } else {
        RevId = 0;
      }
    }

    if (RevId == 1) {
      return 48;    // D0
    } else if (RevId == 2) {
      return 49;    // D1
    } else if (RevId == 3) {
      return 50;    // D2
    } else if (RevId == 4) {
      return 51;    // D3
    } else if (RevId == 5) {
      return 52;    // E0
    } else if (RevId == 6) {
      return 53;    // E1
    } else {
      return 54;    // Unknown
    }
  }

Unsupported:
  DEBUG ((DEBUG_ERROR,
    "Unsupported PCH Stepping. Supporting PCH stepping starting from LbgA0 and above\n"));
  ASSERT (!"((BOOLEAN)(0==1))");
  return 54;
}

// ============================================================================
// XHCI Per-Port Disable Logic
// ============================================================================

/**
  Internal helper: write a DWORD to an XHCI MMIO register.

  @param  XhciBar  XHCI controller MMIO base address.
  @param  Offset   Register offset from XhciBar.
  @param  Value    32-bit value to write.
**/
STATIC
VOID
XhciWrite32 (
  IN UINTN   XhciBar,
  IN UINTN   Offset,
  IN UINT32  Value
  )
{
  MmioWrite32 (XhciBar + Offset, Value);
}

/**
  Internal helper: read a DWORD from an XHCI MMIO register.

  @param  XhciBar  XHCI controller MMIO base address.
  @param  Offset   Register offset from XhciBar.

  @return 32-bit value read.
**/
STATIC
UINT32
XhciRead32 (
  IN UINTN   XhciBar,
  IN UINTN   Offset
  )
{
  return MmioRead32 (XhciBar + Offset);
}

/**
  Disable a single USB port on the XHCI controller.

  For HS (USB 2.0) ports: sets PORTSC = 0x210 (Port Reset + Port Disable)
  and waits for the port to become disabled.
  For SS (USB 3.0) ports: sets PORTSC = 0x8000FE00 (Port Disable + Link Error)
  and waits for the port to become disabled.

  @param  XhciBar    XHCI MMIO base address.
  @param  PortBase   PORTSC register offset for this port.
  @param  PortNumber Physical port number (0-based).
  @param  IsSSPort   TRUE if SuperSpeed (USB 3.0) port.
**/
VOID
XhciDisablePort (
  IN UINTN    XhciBar,
  IN UINTN    PortBase,
  IN UINTN    PortNumber,
  IN BOOLEAN  IsSSPort
  )
{
  UINT32  PortSc;
  UINT32  Timeout;

  PortSc = XhciRead32 (XhciBar, PortBase);

  if ((PortSc & BIT1) == 0) {
    //
    // Port is already disabled, nothing to do.
    //
    return;
  }

  DEBUG ((DEBUG_INFO, "Disable port %d under Xhci controller\n", PortNumber + 1));

  //
  // Issue port disable
  //
  if (IsSSPort) {
    //
    // For SS ports, set Port Disable + Reset
    //
    XhciWrite32 (XhciBar, PortBase, 0x8000FE00);
    //
    // Wait up to 3 seconds (3000 * 1ms)
    //
    for (Timeout = 0; Timeout < 3000; Timeout++) {
      PortSc = XhciRead32 (XhciBar, PortBase);
      if ((PortSc & 0x280001) != BIT0) {
        break;
      }
      gBS->Stall (1000);
    }
  } else {
    //
    // For HS ports, set Port Reset + Port Disable
    //
    XhciWrite32 (XhciBar, PortBase, 0x210);
    //
    // Wait up to 200ms (200 * 1ms)
    //
    for (Timeout = 0; Timeout < 200; Timeout++) {
      PortSc = XhciRead32 (XhciBar, PortBase);
      if ((PortSc & 0x200001) != BIT0) {
        break;
      }
      gBS->Stall (1000);
    }
  }
}

/**
  USB Per-Port Disable Callback.

  Invoked by the UEFI event mechanism (notify function) after the
  PchRcConfiguration variable is ready.  Reads per-port enable/disable
  flags from the HII configuration and programs the XHCI controller's
  Port Disable Override (PDO) and SuperSpeed Port Enable (SSPE) registers
  accordingly.

  @param[in] Event   Event whose notification function is being invoked.
  @param[in] Context Pointer to the notification function's context.

  @return Status code.
**/
EFI_STATUS
EFIAPI
UsbPerPortDisableCallback (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  UINTN                     XhciBar;
  UINT32                    HsPdo;
  UINT32                    SsPdo;
  UINT32                    SsPe;
  UINT32                    Sku;
  UINT32                    MaxHsPorts;
  UINT32                    MaxSsPorts;
  UINT32                    PortIndex;
  UINT32                    PortScOffset;
  UINTN                     PdoPortOffset;
  UINT8                     PortConfig[1552];
  UINT16                    ConfigDataSize;
  UINT16                    ConfigRequest;
  UINT32                    *PciAddr;
  EFI_STATUS                Status;
  UINT8                     PortEnabled;
  UINT8                     DisableMask;

  if (gXhciPortDisableDone) {
    goto Done;
  }

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

  //
  // Determine PCH SKU for port count and register layout
  //
  Sku = GetPchSku ();
  if (Sku == 2) {
    MaxHsPorts = 10;
    MaxSsPorts = 6;
  } else {
    MaxHsPorts = 14;
    MaxSsPorts = 10;
  }

  //
  // Read PchRcConfiguration variable from runtime services
  //
  ConfigDataSize = sizeof (PortConfig);
  ZeroMem (PortConfig, sizeof (PortConfig));

  Status = gRT->GetVariable (
                  L"PchRcConfiguration",
                  &gPchRcConfigGuid,
                  NULL,
                  &ConfigDataSize,
                  PortConfig
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to read PchRcConfiguration: %r\n", Status));
    goto Done;
  }

  //
  // Read XHCI BAR
  //
  ConfigRequest = 0xA0010;  // EFI_PCI_IO_ATTRIBUTE_MEMORY
  PciAddr = (UINT32 *)gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, NULL);

  //
  // Simplified: Read XHCI MMIO BAR from PCI config space (Dev 20, Func 0)
  //
  XhciBar = PciExpressRead32 (PCI_EXPRESS_LIB_ADDRESS (0, 20, 0, 0x10));
  if ((XhciBar & 0xFFFFFFF0) == 0) {
    DEBUG ((DEBUG_ERROR, "XHCI BAR is 0!\n"));
    goto Done;
  }
  XhciBar &= 0xFFFFFFF0;

  //
  // Handle 64-bit BAR if needed
  //
  if ((PciExpressRead32 (PCI_EXPRESS_LIB_ADDRESS (0, 20, 0, 0x10)) & 0x06) == 0x04) {
    XhciBar |= (UINTN)PciExpressRead32 (PCI_EXPRESS_LIB_ADDRESS (0, 20, 0, 0x14)) << 32;
  }

  DEBUG ((DEBUG_INFO, "Xhci Bar = %lx\n", XhciBar));

  //
  // Read current HS PDO, SS PDO, and SSPE values
  //
  HsPdo = XhciRead32 (XhciBar, XHCI_HSPDO_OFS);
  if (Sku == 2) {
    SsPdo = HsPdo & 0x3FF;
    SsPe  = 0;
  } else {
    SsPdo = XhciRead32 (XhciBar, XHCI_SSPDO_OFS) & 0x7FFF;
    SsPe  = 0;
  }

  //
  // Process HS (USB 2.0) ports
  //
  for (PortIndex = 0; PortIndex < MaxHsPorts; PortIndex++) {
    PortEnabled = PortConfig[38 + PortIndex];
    DisableMask = (UINT32)(1 << PortIndex);

    if (PortEnabled == 1) {
      //
      // User wants port disabled
      //
      HsPdo &= ~DisableMask;

      if (PortIndex < 12) {
        PortScOffset = XHCI_PORTSC_OFS + PortIndex * XHCI_PORTSC_STRIDE;
      } else {
        PortScOffset = (PortIndex - 12) * XHCI_PORTSC_STRIDE + 0x0540;
      }
    } else {
      //
      // User wants port enabled
      //
      HsPdo |= DisableMask;
    }
  }

  //
  // Process SS (USB 3.0) ports
  //
  for (PortIndex = 0; PortIndex < MaxSsPorts; PortIndex++) {
    PortEnabled = PortConfig[54 + PortIndex];
    DisableMask = (UINT32)(1 << PortIndex);

    if (PortEnabled == 1) {
      SsPdo &= ~DisableMask;
    } else {
      SsPdo |= DisableMask;
    }
  }

  //
  // Compute SSPE value
  //
  if (PortConfig[1254] != 0) {
    //
    // All SS ports explicitly managed
    //
    if (Sku == 2) {
      SsPe = SsPdo & 0x3C0;
    } else {
      SsPe = 0;
    }
  } else {
    //
    // Derive SSPE from SS PDO
    //
    SsPe = SsPdo;
  }

  //
  // Write back the PDO and SSPE registers
  //
  DEBUG ((DEBUG_INFO, "Write back Xhci HS PDO value: %x to HS PDO register\n", HsPdo));
  XhciWrite32 (XhciBar, XHCI_HSPDO_OFS, HsPdo);

  DEBUG ((DEBUG_INFO, "Write back Xhci SS PDO value: %x to SS PDO register\n", SsPdo));
  XhciWrite32 (XhciBar, XHCI_SSPDO_OFS, SsPdo);

  DEBUG ((DEBUG_INFO, "Write back Xhci SSPE value: %x to SSPE register\n", SsPe));
  XhciWrite32 (XhciBar, XHCI_SSPE_OFS, SsPe);

  //
  // Now physically disable each port that was marked for disable
  //
  {
    UINT32  HsDisableCount;
    UINT32  SsDisableCount;

    HsDisableCount = 0;
    SsDisableCount = 0;

    for (PortIndex = 0; PortIndex < MaxHsPorts; PortIndex++) {
      if (PortConfig[38 + PortIndex] == 1) {
        //
        // This HS port needs to be disabled
        //
        if (PortIndex < 12) {
          PortScOffset = XHCI_PORTSC_OFS + PortIndex * XHCI_PORTSC_STRIDE;
        } else {
          PortScOffset = (PortIndex - 12) * XHCI_PORTSC_STRIDE + 0x0540;
        }
        XhciDisablePort (XhciBar, PortScOffset, PortIndex, FALSE);
      }
    }

    for (PortIndex = 0; PortIndex < MaxSsPorts; PortIndex++) {
      if (PortConfig[54 + PortIndex] == 1) {
        //
        // This SS port needs to be disabled
        //
        if (Sku == 2) {
          if (PortIndex >= 6) {
            PortScOffset = (PortIndex - 6) * XHCI_PORTSC_STRIDE + 0x0540;
          } else {
            PortScOffset = (PortIndex + 12) * XHCI_PORTSC_STRIDE + 0x0480;
          }
        } else {
          if (PortIndex >= 10) {
            PortScOffset = (PortIndex - 10) * XHCI_PORTSC_STRIDE + 0x0580;
          } else {
            PortScOffset = (PortIndex + 16) * XHCI_PORTSC_STRIDE + 0x0480;
          }
        }
        XhciDisablePort (XhciBar, PortScOffset, PortIndex, TRUE);
      }
    }
  }

  gXhciPortDisableDone = TRUE;
  DEBUG ((DEBUG_INFO, "USBPerPortDisableCallback - End\n"));

Done:
  if (Event != NULL) {
    gBS->CloseEvent (Event);
  }
  return EFI_SUCCESS;
}

// ============================================================================
// Boot Script Support
// ============================================================================

/**
  Save a data buffer to the SMM LockBox as a boot script entry.

  This function communicates with the SMM LockBox handler via the
  SMM Communication protocol.  The lockbox entry is identified by
  the boot script context GUID.

  @param[in] Buffer      Pointer to the data to save.
  @param[in] BufferSize  Size of the data in bytes.

  @return EFI_SUCCESS on success, or error code from LockBox protocol.
**/
EFI_STATUS
SaveBootScriptToLockBox (
  IN VOID   *Buffer,
  IN UINTN   BufferSize
  )
{
  EFI_SMM_COMMUNICATION_PROTOCOL  *SmmComm;
  EFI_SMM_COMMUNICATE_HEADER       CommHeader;
  UINT64                           CommSize;
  UINT8                            LocalBuffer[EFI_PAGE_SIZE];
  UINT8                           *BufferPtr;
  EFI_STATUS                       Status;

  DEBUG ((DEBUG_INFO, "SmmLockBoxDxeLib SaveLockBox - Enter\n"));

  if ((Buffer == NULL) || (BufferSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  SmmComm = (EFI_SMM_COMMUNICATION_PROTOCOL *)gSmmCommunicationProtocol;
  if (SmmComm == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Prepare SMM communication buffer for LockBox save
  //
  BufferPtr = &LocalBuffer[0];
  ZeroMem (BufferPtr, sizeof (LocalBuffer));

  //
  // Build the LockBox communication buffer:
  //   [0..15]   = Guid (boot script context GUID)
  //   [16..23]  = Command (48 = Save LockBox)
  //   [24..31]  = ReturnStatus (~0UL = no status)
  //   [32..35]  = Signature (1)
  //   [36..39]  = Length (48 bytes header)
  //   [40..55]  = LockBox GUID (buffer GUID)
  //   [56..63]  = Buffer address
  //   [64..71]  = Buffer size
  //
  CopyMem (BufferPtr, &gBootScriptContextGuid, sizeof (EFI_GUID));
  *((UINT64 *)&BufferPtr[16]) = 48;    // EFI_SMM_LOCK_BOX_COMMAND_SAVE
  *((UINT64 *)&BufferPtr[24]) = (UINT64)-1;
  *((UINT32 *)&BufferPtr[32]) = 1;     // EFI_SMM_LOCK_BOX_SIGNATURE
  *((UINT32 *)&BufferPtr[36]) = 48;    // Header size
  CopyMem (&BufferPtr[40], Buffer, 16);
  *((UINT64 *)&BufferPtr[56]) = (UINT64)Buffer;
  *((UINT64 *)&BufferPtr[64]) = BufferSize;

  CommSize = 72;
  Status = SmmComm->Communicate (SmmComm, &LocalBuffer[0], &CommSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "SaveLockBox communicate failed: %r\n", Status));
    return Status;
  }

  Status = *((UINT64 *)&LocalBuffer[24]);
  DEBUG ((DEBUG_INFO, "SmmLockBoxDxeLib SaveLockBox - Exit (%r)\n", Status));
  return Status;
}

/**
  Set attributes on the boot script LockBox entry.

  Currently sets the attribute to 1 (LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE).
  This must be called after SaveBootScriptToLockBox() to prevent the
  boot script from being overwritten in memory during S3 resume.

  @return EFI_SUCCESS on success, or error code from LockBox protocol.
**/
EFI_STATUS
SetBootScriptLockBoxAttributes (
  VOID
  )
{
  EFI_SMM_COMMUNICATION_PROTOCOL  *SmmComm;
  UINT8                            LocalBuffer[EFI_PAGE_SIZE];
  UINT8                           *BufferPtr;
  UINT64                           CommSize;
  EFI_STATUS                       Status;

  DEBUG ((DEBUG_INFO, "SmmLockBoxDxeLib SetLockBoxAttributes - Enter\n"));

  SmmComm = (EFI_SMM_COMMUNICATION_PROTOCOL *)gSmmCommunicationProtocol;
  if (SmmComm == NULL) {
    return EFI_NOT_FOUND;
  }

  BufferPtr = &LocalBuffer[0];
  ZeroMem (BufferPtr, sizeof (LocalBuffer));

  //
  // Build LockBox communication buffer for SetAttributes command
  //
  CopyMem (BufferPtr, &gBootScriptContextGuid, sizeof (EFI_GUID));
  *((UINT64 *)&BufferPtr[16]) = 40;    // EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES
  *((UINT64 *)&BufferPtr[24]) = (UINT64)-1;
  *((UINT32 *)&BufferPtr[32]) = 4;     // Header version
  *((UINT32 *)&BufferPtr[36]) = 40;    // Header size
  CopyMem (&BufferPtr[40], &gBootScriptContextGuid, sizeof (EFI_GUID));
  *((UINT64 *)&BufferPtr[56]) = 1;     // LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE

  CommSize = 64;
  Status = SmmComm->Communicate (SmmComm, &LocalBuffer[0], &CommSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "SetLockBoxAttributes communicate failed: %r\n", Status));
    return Status;
  }

  Status = *((UINT64 *)&LocalBuffer[24]);
  DEBUG ((DEBUG_INFO, "SmmLockBoxDxeLib SetLockBoxAttributes - Exit (%r)\n", Status));
  return Status;
}

// ============================================================================
// S3 Boot Script Initialization
// ============================================================================

/**
  Allocate and prepare memory for the S3 boot script table.

  This function is called on first usage of the boot script library
  if no pre-allocated table exists.

  @param[out] Table   Receives the pointer to the boot script table.

  @retval EFI_SUCCESS  Table was allocated and initialized.
**/
STATIC
EFI_STATUS
InitBootScriptTable (
  OUT UINT64  *Table
  )
{
  EFI_STATUS  Status;
  UINT64      PcdValue;

  PcdValue = 0xFFFFFFFFULL;

  //
  // Allocate runtime memory page for the boot script table
  //
  Status = gBS->AllocatePages (AllocateAnyPages, EfiRuntimeServicesData, 1, &PcdValue);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to allocate boot script table: %r\n", Status));
    return Status;
  }

  gS3BootScriptInitialized = TRUE;

  //
  // Store the PCD value for the boot script table address
  //
  PcdSet64S (PcdBootScriptTableAddress, PcdValue);

  //
  // Signal that the boot script table is ready
  //
  gBootScriptTable = PcdValue;
  gBootScriptTable2 = PcdValue;

  //
  // Register notification for DxeSmmReadyToLock
  //
  EfiCreateEventReadyToBoot (
    TPL_CALLBACK,
    BootScriptReadyToLockNotify,
    NULL,
    &gEventDxeSmmReadyToLock
    );

  return EFI_SUCCESS;
}

/**
  Boot Script Ready-to-Lock notification callback.

  Invoked when the DxeSmmReadyToLock group signal is fired.
  Saves the current boot script entries to the SMM LockBox,
  then registers additional callbacks for boot script close.

  @param[in] Event   Event that triggered this notification.
  @param[in] Context Not used.
**/
VOID
EFIAPI
BootScriptReadyToLockNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  if (!gSmmReadyToLockOccurred) {
    gSmmReadyToLockOccurred = TRUE;
    DEBUG ((DEBUG_INFO, "%a() in SBDxe module\n", __FUNCTION__));

    if (gS3BootScriptInitialized) {
      //
      // Close event notification
      //
      gBS->CloseEvent (gEventDxeSmmReadyToLock);

      //
      // Lock the boot script table
      //
      gBootScriptLocked = 1;

      //
      // Save the current boot script data to LockBox
      //
      SaveBootScriptToLockBox (
        (VOID *)&gBootScriptContextGuid,
        gBootScriptTable,
        (UINT32)(*(UINT32 *)(UINTN)gBootScriptTable + 3)
        );

      //
      // Set LockBox attributes
      //
      SetBootScriptLockBoxAttributes ();

      //
      // Register for subsequent boot script close events
      //
      if (gSmmCommunicationProtocol != NULL) {
        //
        // Register close event callbacks for S3 resume paths
        //
        ((EFI_SMM_COMMUNICATION_PROTOCOL *)gSmmCommunicationProtocol)->RegisterProtocolNotify (
          &gBootScriptExecutorGuid,
          BootScriptCloseNotify,
          &gEventBootScriptClose
          );
        ((EFI_SMM_COMMUNICATION_PROTOCOL *)gSmmCommunicationProtocol)->RegisterProtocolNotify (
          &gBootScriptContextGuid,
          BootScriptCloseNotify,
          &gEventBootScriptContext
          );
      }

      //
      // Additional cleanup callbacks
      //
      ((EFI_SMM_COMMUNICATION_PROTOCOL *)gSmmCommunicationProtocol)->RegisterProtocolNotify (
        &gSmmCommRegionGuid,
        BootScriptContextCloseNotify,
        &gEventBootScriptContextClose
        );
    }
  }
}

/**
  Boot script close notification callback.

  Handles the case where the boot script context is being updated
  after the initial save.  This callback is registered to run at
  EndOfDxe to finalize the boot script data.

  @param[in] Event   Event that triggered this notification.
  @param[in] Context Not used.
**/
VOID
EFIAPI
BootScriptCloseNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  if (gBootScriptTable != gBootScriptTable2) {
    //
    // Copy the new table to the LockBox
    //
    CloseBootScriptTable ();
    if (*(UINT64 *)(UINTN)gBootScriptTable2 == 0) {
      CopyMem (
        (VOID *)(UINTN)gBootScriptTable2,
        (VOID *)(UINTN)gBootScriptTable,
        32
        );
      *(UINT8 *)(UINTN)(gBootScriptTable2 + 14) = 1;
    }
    gBootScriptTable = gBootScriptTable2;
  }
}

/**
  Close and save the current boot script table to the LockBox.

  Calculates the final size of the boot script table entry and
  invokes SaveBootScriptToLockBox, then calls
  SetBootScriptLockBoxAttributes for the new copy.

  @return EFI_SUCCESS on completion.
**/
UINT64
CloseBootScriptTable (
  VOID
  )
{
  UINT32  Size;

  if (gBootScriptTable != gBootScriptTable2) {
    CloseBootScriptTableWorker (0, 0);
    if (*(UINT64 *)(UINTN)gBootScriptTable2 == 0) {
      CopyMem (
        (VOID *)(UINTN)gBootScriptTable2,
        (VOID *)(UINTN)gBootScriptTable,
        32
        );
      *(UINT8 *)(UINTN)(gBootScriptTable2 + 14) = 1;
    }
    gBootScriptTable = gBootScriptTable2;
  }

  return 0;
}

/**
  Boot script context close notification.

  Registered on the PiSmmCommunicationRegionTable protocol.
  Saves the boot script context and updates the boot script
  table pointer.

  @param[in] Event   Event that triggered this notification.
  @param[in] Context Not used.
**/
VOID
EFIAPI
BootScriptContextCloseNotify (
  IN EFI_EVENT  Event,
  IN VOID      *Context
  )
{
  EFI_STATUS  Status;
  UINT64      BootScriptPcd;

  if (gSmmCommunicationProtocol != NULL && gBootScriptLocked) {
    Status = ((EFI_SMM_COMMUNICATION_PROTOCOL *)gSmmCommunicationProtocol)->Communicate (
      gSmmCommunicationProtocol,
      (VOID *)(UINTN)gBootScriptTable,
      &BootScriptPcd
      );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "BootScript context close communicate failed: %r\n", Status));
    }

    //
    // Restore the PCD to the locked value
    //
    PcdSet64S (PcdBootScriptTableAddress, gBootScriptTable);
    gBootScriptLocked = 0;
  }
}

// ============================================================================
// PCIe Segment Bus Table Setup
// ============================================================================

/**
  Initialize and install the PCIe Segment/Bus routing table.

  Reads the number of PCIe segments from the PCD and allocates
  the bus-to-bus routing table.  This allows the PCI enumerator
  to correctly assign bus numbers across multiple PCIe root ports.
**/
STATIC
VOID
SbdInstallPcieSegBusTable (
  VOID
  )
{
  UINTN       NumSegments;
  UINTN       TableSize;
  VOID       *PcdProtocol;
  VOID       *PcieSegBusTable;

  //
  // Get the number of PCIe segments from PCD
  //
  PcdProtocol = GetPcdProtocolPtr ();
  NumSegments = PcdGetSize (PcdPcieSegBusConfig);
  if (NumSegments > sizeof (PCIE_SEG_BUS_TABLE)) {
    DEBUG ((DEBUG_ERROR, "PCIE_SEG_BUS_TABLE too small!\n"));
    ASSERT (FALSE);
  }

  //
  // Allocate and initialize the bus table
  //
  PcieSegBusTable = AllocateZeroPool (NumSegments);

  //
  // Call the PCH-specific installation routine
  //
  PchInstallPcieSegBusTable (
    PcieSegBusTable,
    PciExpressRead32 (
      PCI_EXPRESS_LIB_ADDRESS (0, 31, 0, 0x54)  // PCIe config base
      ),
    NumSegments
    );
}

// ============================================================================
// PCI Express Base Address Initialization
// ============================================================================

/**
  Locate and cache the PCD protocol pointer.

  @return EFI_SUCCESS if found, EFI_NOT_FOUND otherwise.
**/
STATIC
EFI_STATUS
GetPcdProtocol (
  VOID
  )
{
  EFI_STATUS  Status;

  if (gPcdProtocol == NULL) {
    Status = gBS->LocateProtocol (
                    &gEfiPcdProtocolGuid,
                    NULL,
                    &gPcdProtocol
                    );
    if (EFI_ERROR (Status)) {
      gPcdProtocol = NULL;
    }
    gPciExpressBaseAddr = PcdGet64 (PcdPciExpressBaseAddress);
  }

  return (gPcdProtocol != NULL) ? EFI_SUCCESS : EFI_NOT_FOUND;
}

// ============================================================================
// DXE Service Table and HOB List Discovery
// ============================================================================

/**
  Locate the DXE Services Table (gDS) and HOB list via the configuration table.
**/
STATIC
VOID
InitializeDxeServices (
  VOID
  )
{
  EFI_STATUS  Status;
  VOID       *HobList;

  Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **)&gDS);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to locate DXE Services Table\n"));
  }

  Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
  if (!EFI_ERROR (Status)) {
    gHobList = HobList;
  }
}

// ============================================================================
// SMM Communication Protocol Discovery
// ============================================================================

/**
  Locate the SMM Communication protocol (DXE phase).
  This is needed for LockBox operations and PCIe base access.
**/
STATIC
EFI_STATUS
LocateSmmCommunicationProtocol (
  VOID
  )
{
  EFI_STATUS  Status;

  if (gSmmCommunicationProtocol == NULL) {
    Status = gBS->LocateProtocol (
                    &gEfiSmmCommunicationProtocolGuid,
                    NULL,
                    &gSmmCommunicationProtocol
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}

// ============================================================================
// Library Constructor-Style Init
// ============================================================================

/**
  Initialize the library globals (gImageHandle, gST, gBS, gRT, gDS) from
  the EFI System Table.

  This is called early in SBDxeInitialize before any protocol lookups.
**/
STATIC
VOID
InitializeLibGlobals (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  )
{
  //
  // Cache UEFI core services
  //
  gImageHandle = ImageHandle;
  gST          = SystemTable;
  gBS          = SystemTable->BootServices;
  gRT          = SystemTable->RuntimeServices;

  //
  // Initialize DXE services table and HOB list from configuration table
  //
  InitializeDxeServices ();
}

// ============================================================================
// Main Driver Initialization
// ============================================================================

/**
  Main driver initialization for the SB DXE driver.

  Called from _ModuleEntryPoint after library dependencies are resolved.
  Performs:
    - Caching of global service pointers
    - DXE Services Table and HOB list discovery
    - SMM PCI base protocol retrieval
    - PCH stepping detection and PCIe segment bus table setup
    - I/O port timing delays for chipset workarounds
    - XHCI USB port disable event registration
    - S3 boot script initialization

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

  @return EFI_SUCCESS on success, or an error code on failure.
**/
EFI_STATUS
SBDxeInitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  )
{
  EFI_STATUS  Status;
  UINT16      AcpiBase;
  UINTN       SegCount;
  UINT8       PcieSegBase;
  BOOLEAN     IsPchLp;
  UINT32      Stepping;
  UINT32      PdoValue;
  UINT32      TimeoutValue;

  //
  // 1. Initialize library globals
  //
  InitializeLibGlobals (ImageHandle, SystemTable);

  //
  // 2. Register Driver Binding Protocol (simplified: install protocols)
  //    This driver uses the simpler callback registration model.
  //

  //
  // 3. Locate SMM PCI base protocol (PciUsra) for MM PCI config access
  //
  Status = gBS->LocateProtocol (
                  &gEfiSmmCommunicationProtocolGuid,
                  NULL,
                  &gPciUsra
                  );
  if (EFI_ERROR (Status)) {
    //
    // SMM protocol may not be available yet; we try again in callbacks.
    //
    gPciUsra = NULL;
  }

  //
  // 4. Initialize PCH stepping detection
  //
  Stepping = GetPchStepping ();
  PcieSegBase = PciExpressRead32 (
                  PCI_EXPRESS_LIB_ADDRESS (0, 31, 0, 0x54)
                  );
  SegCount = PcdGetSize (PcdPcieSegBusConfig);
  PchInstallPcieSegBusTable (&gPcieSegBusTable, PcieSegBase, SegCount);

  //
  // 5. PCI express memory-mapped I/O base setup
  //    Also used to enable write-combining for PCIe MMIO range
  //
  {
    UINT8  *PciMmCfg;
    PciMmCfg = (UINT8 *)(UINTN)PcdGet64 (PcdPciExpressBaseAddress);
    if (*PciMmCfg >= 0) {
      //
      // Enable PCIe ECAM (enhanced configuration access mechanism)
      //
      IoWrite16 (PcdGet16 (PcdPciExpressBaseAddress), 0x500);
      PciMmCfg = (UINT8 *)(UINTN)PcdGet16 (PcdPciExpressBaseAddress + 4);
      *PciMmCfg |= 0x80;
    }
  }

  //
  // 6. Chipset timing workaround: read ACPI base, compute delay
  //
  IsPchLp = (GetPchSku () == 2);
  AcpiBase = IoRead16 (PcdGet16 (PcdAcpiBaseAddress));
  TimeoutValue = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + 4) & 0x00FFFFFF;
  IoRead32 (PcdGet16 (PcdAcpiBaseAddress));

  //
  // Busy-wait for chipset stabilization
  //
  while (((TimeoutValue + 357 - IoRead32 (PcdGet16 (PcdAcpiBaseAddress))) & 0x800000) == 0) {
    IoRead32 (PcdGet16 (PcdAcpiBaseAddress));
  }

  //
  // 7. Enable/disable SMI based on PCH LP vs H
  //
  if (IsPchLp) {
    IoWrite8 (RTC_INDEX_PORT, 0x00);
  } else {
    IoRead8 (RTC_DATA_PORT);
  }

  //
  // 8. Initialize S3 boot script support
  //
  Status = InitBootScriptTable (&gBootScriptTable);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to initialize boot script table: %r\n", Status));
    return Status;
  }

  //
  // 9. Register USB per-port disable callback via event
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  UsbPerPortDisableCallback,
                  NULL,
                  &gXhciPortDisableEvent
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_WARN, "Failed to create XHCI port disable event: %r\n", Status));
  }

  return EFI_SUCCESS;
}

// ============================================================================
// Module Entry Point
// ============================================================================

/**
  Entry point for the SBDXE driver.  Called by the DXE dispatcher
  after all dependencies are resolved.

  Calls SBDxeInitialize() to perform all initialization.  If the
  initialization succeeds, registers the driver unload handler and
  installs the driver binding protocol.

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

  @return EFI_SUCCESS           The driver was initialized successfully.
  @return EFI_UNSUPPORTED       The driver initialization failed.
  @return EFI_INVALID_PARAMETER SystemTable is NULL.
**/
EFI_STATUS
EFIAPI
SBDxeEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Invoke the main initialization routine
  //
  Status = SBDxeInitialize (ImageHandle, SystemTable);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "SBDxe initialization failed: %r\n", Status));
  }

  return Status;
}

// ============================================================================
// Assertion / Debug Helpers
// ============================================================================

/**
  Internal assertion helper.  Logs an assertion failure to the debug console.

  In DEBUG builds this will trigger a breakpoint.  In RELEASE builds
  the assertion is compiled out.

  @param[in] FileName    Source file name of the assertion.
  @param[in] LineNumber  Line number of the assertion.
  @param[in] Description Null-terminated ASCII description string.
**/
#pragma optimize("", off)
VOID
SbdAssert (
  IN CONST CHAR8  *FileName,
  IN UINTN         LineNumber,
  IN CONST CHAR8  *Description
  )
{
  DEBUG ((DEBUG_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
  DEBUG ((
    DEBUG_ERROR,
    "%a(%d): %a\n",
    FileName,
    LineNumber,
    Description
    ));
  CpuDeadLoop ();
}
#pragma optimize("", on)

/**
  Debug print helper.  Wrapper around the UEFI DebugLib DEBUG macro.

  @param[in] ErrorLevel  Debug error level (DEBUG_INFO, DEBUG_ERROR, etc.).
  @param[in] Format      Print format string.
  @param[in] ...         Variable arguments for the format string.
**/
VOID
SbdDebugPrint (
  IN UINTN        ErrorLevel,
  IN CONST CHAR8 *Format,
  ...
  )
{
  VA_LIST  Marker;

  VA_START (Marker, Format);
  DebugVPrint (ErrorLevel, Format, Marker);
  VA_END (Marker);
}

// ============================================================================
// PCI Express MMIO Read/Write Helpers (used for chipset access)
// ============================================================================

/**
  Read a 32-bit value from PCI Express config space.

  @param[in] Address  PCI Express address (format per PCI_EXPRESS_LIB_ADDRESS).

  @return 32-bit configuration value.
**/
UINT32
PciExpressRead32 (
  IN UINT64  Address
  )
{
  ASSERT (((Address) & ~0xFFFFFFF) == 0);
  return MmioRead32 ((UINTN)(gPciExpressBaseAddr + Address));
}

/**
  Write a 32-bit value to PCI Express config space.

  @param[in] Address  PCI Express address (format per PCI_EXPRESS_LIB_ADDRESS).
  @param[in] Data     32-bit value to write.
**/
VOID
PciExpressWrite32 (
  IN UINT64  Address,
  IN UINT32  Data
  )
{
  ASSERT (((Address) & ~0xFFFFFFF) == 0);
  MmioWrite32 ((UINTN)(gPciExpressBaseAddr + Address), Data);
}

// ============================================================================
// IO Port Helpers
// ============================================================================

/**
  Read a 16-bit value from an I/O port.

  @param[in] Port  I/O port address.  Must be 16-bit aligned.

  @return 16-bit value read from the port.
**/
UINT16
IoRead16 (
  IN UINT16  Port
  )
{
  ASSERT ((Port & 1) == 0);
  return __inword (Port);
}

/**
  Write a 16-bit value to an I/O port.

  @param[in] Port   I/O port address.  Must be 16-bit aligned.
  @param[in] Value  16-bit value to write.
**/
VOID
IoWrite16 (
  IN UINT16  Port,
  IN UINT16  Value
  )
{
  ASSERT ((Port & 1) == 0);
  __outword (Port, Value);
}

/**
  Read a 32-bit value from an I/O port.

  @param[in] Port  I/O port address.  Must be 32-bit aligned.

  @return 32-bit value read from the port.
**/
UINT32
IoRead32 (
  IN UINT16  Port
  )
{
  ASSERT ((Port & 3) == 0);
  __indword (Port);
}

/**
  Write a 32-bit value to an I/O port.

  @param[in] Port   I/O port address.  Must be 32-bit aligned.
  @param[in] Value  32-bit value to write.
**/
VOID
IoWrite32 (
  IN UINT16  Port,
  IN UINT32  Value
  )
{
  ASSERT ((Port & 3) == 0);
  __outdword (Port, Value);
}

/**
  Read an 8-bit value from an I/O port.

  @param[in] Port  I/O port address.

  @return 8-bit value read from the port.
**/
UINT8
IoRead8 (
  IN UINT16  Port
  )
{
  return __inbyte (Port);
}

/**
  Write an 8-bit value to an I/O port.

  @param[in] Port   I/O port address.
  @param[in] Value  8-bit value to write.
**/
VOID
IoWrite8 (
  IN UINT16  Port,
  IN UINT8   Value
  )
{
  __outbyte (Port, Value);
}

/**
  Copy a block of memory.  Handles overlapping buffers correctly.

  @param[out] Dest     Pointer to the destination buffer.
  @param[in]  Src      Pointer to the source buffer.
  @param[in]  Count    Number of bytes to copy.

  @return Pointer to the destination buffer (Dest).
**/
VOID *
MemCopy (
  OUT VOID       *Dest,
  IN  CONST VOID *Src,
  IN  UINTN       Count
  )
{
  //
  // Use aligned copy for speed when possible.
  // Fall back to byte copy for tail bytes.
  //
  if ((Src < Dest) && ((UINT8 *)Src + Count - 1 >= (UINT8 *)Dest)) {
    //
    // Overlapping: copy from end to start
    //
    CopyMemBackwards (Dest, Src, Count);
  } else {
    //
    // Non-overlapping or forward overlap: copy from start to end
    //
    CopyMemForward (Dest, Src, Count);
  }

  return Dest;
}

/**
  Zero a block of memory.

  @param[out] Buf   Pointer to the buffer to zero.
  @param[in]  Len   Number of bytes to zero.
**/
VOID
MemZero (
  OUT VOID   *Buf,
  IN  UINTN   Len
  )
{
  SetMem (Buf, Len, 0);
}