Newer
Older
AMI-Aptio-BIOS-Reversed / AddressTranslationDsmMemRas / AddressTranslationDsmMemRas.c
@Ajax Dong Ajax Dong 2 days ago 22 KB Init
/** @file
  AddressTranslationDsmMemRas - Purley Platform RAS Address Translation DSM Driver (SMM)

  This driver is an SMM driver that provides Address Translation DSM (Direct Memory Store)
  error reporting functionality. It registers an SMI handler to handle memory error
  log queries from the OS, and installs a patched SSDT to expose the ACPI
  interface for Address Translation DSM.

  Source: PurleyPlatPkg\Ras\AddressTranslationDsm\AddressTranslationDsm.c

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

#include "AddressTranslationDsmMemRas.h"

//
// Global variables
//
EFI_HANDLE                 *gImageHandle       = NULL;
EFI_SYSTEM_TABLE           *gSystemTable       = NULL;
EFI_BOOT_SERVICES          *gBootServices      = NULL;
EFI_RUNTIME_SERVICES       *gRuntimeServices   = NULL;
EFI_SMM_SYSTEM_TABLE2      *gSmst              = NULL;
EFI_SMM_CPU_PROTOCOL       *mSmmCpu            = NULL;

MEMRAS_PROTOCOL            *mMemRas            = NULL;

//
// SMI communication buffer (0x100 bytes allocated via AllocatePool)
//
ADDRESS_TRANSLATION_DSM_COMMUNICATION_BUFFER *mCommunicationBuffer = NULL;

//
// SMRAM ranges for memory allocation tracking
//
EFI_SMRAM_DESCRIPTOR       *mSmramRanges       = NULL;
UINTN                      mSmramRangeCount    = 0;

//
// Module status tracking
//
EFI_STATUS                 mModuleStatus       = EFI_SUCCESS;

//
// Protocol GUIDs (platform-specific)
//
EFI_GUID gMemRasProtocolGuid  = { 0x6D7E4A32, 0x9A73, 0x46BA, { 0x94, 0xA1, 0x5F, 0x2F, 0x25, 0xEF, 0x3E, 0x29 } };
EFI_GUID gAddressTranslationDsmSsdtFileGuid = { 0xFFE06BDD, 0x6107, 0x46A6, { 0x7B, 0xB2, 0x5A, 0x9C, 0x7E, 0xC5, 0x27, 0x5C } };

/**
  Initialize UEFI Boot Services Library globals and locate SMM protocols.

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

  @return The number of SMRAM ranges.
**/
UINTN
EFIAPI
UefiBootServicesTableLibConstructor (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS               Status;
  EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
  UINTN                    SmramSize;

  gImageHandle = ImageHandle;
  ASSERT (ImageHandle != NULL);

  gSystemTable = SystemTable;
  ASSERT (SystemTable != NULL);

  gBootServices = SystemTable->BootServices;
  ASSERT (gBootServices != NULL);

  gRuntimeServices = SystemTable->RuntimeServices;
  ASSERT (gRuntimeServices != NULL);

  //
  // Locate SMM Base2 protocol to get SMM System Table
  //
  Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **)&gSmst);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
  }
  ASSERT (gSmst != NULL);

  //
  // Get SMM Access2 protocol for SMRAM discovery
  //
  Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Query SMRAM capabilities (expected to return EFI_BUFFER_TOO_SMALL initially)
  //
  Status = SmmAccess->GetCapabilities (SmmAccess, &SmramSize, NULL);
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

  //
  // Allocate SMRAM ranges descriptor
  //
  mSmramRanges = (EFI_SMRAM_DESCRIPTOR *)SmramAllocatePool (SmramSize);
  ASSERT (mSmramRanges != NULL);

  Status = SmmAccess->GetCapabilities (SmmAccess, &SmramSize, mSmramRanges);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Each descriptor is 0x20 (32) bytes
  //
  mSmramRangeCount = SmramSize >> 5;
  return mSmramRangeCount;
}

/**
  DEBUG print wrapper. Checks CMOS debug level to determine whether
  to output the debug message.

  @param  ErrorLevel  The error level mask.
  @param  Format      Format string.
  @param  ...         Variable arguments.
**/
VOID
EFIAPI
DebugPrint (
  IN UINTN            ErrorLevel,
  IN CONST CHAR8      *Format,
  ...
  )
{
  EFI_SMM_CPU_PROTOCOL *SmmCpu;
  UINT8                DebugLevel;
  UINTN                DebugMask;

  SmmCpu = GetSmmCpuProtocol ();
  if (SmmCpu == NULL) {
    return;
  }

  //
  // Check CMOS debug level at offset 0x4C
  //
  DebugLevel = IoRead8 (0x70);
  IoWrite8 (0x70, DebugLevel & 0x80 | 0x4C);
  DebugLevel = IoRead8 (0x71);

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

  switch (DebugLevel) {
  case 1:
    DebugMask = EFI_D_ERROR;
    break;
  case 2:
    DebugMask = EFI_D_WARN;
    break;
  case 3:
  default:
    DebugMask = EFI_D_INFO;
    break;
  }

  if ((DebugMask & ErrorLevel) != 0) {
    SmmCpu->DebugPrint (ErrorLevel, Format, VA_LIST);
  }
}

/**
  Debug ASSERT wrapper that calls SMM_CPU_PROTOCOL for assertion handling.

  @param  FileName      The file name of the assertion.
  @param  LineNumber    The line number of the assertion.
  @param  Description   The assertion description.
**/
VOID
EFIAPI
DebugAssert (
  IN CONST CHAR8   *FileName,
  IN UINTN         LineNumber,
  IN CONST CHAR8   *Description
  )
{
  EFI_SMM_CPU_PROTOCOL *SmmCpu;

  SmmCpu = GetSmmCpuProtocol ();
  if (SmmCpu != NULL) {
    SmmCpu->DebugAssert (FileName, LineNumber, Description);
  }
}

/**
  Retrieve the EFI_SMM_CPU_PROTOCOL via SMM Services Table.
  Uses a cached pointer after first lookup.

  @return The SMM_CPU_PROTOCOL interface, or NULL if not found.
**/
EFI_SMM_CPU_PROTOCOL *
GetSmmCpuProtocol (
  VOID
  )
{
  if (mSmmCpu == NULL) {
    if (EFI_ERROR (gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **)&mSmmCpu))) {
      mSmmCpu = NULL;
    }
  }
  return mSmmCpu;
}

/**
  Check if an address falls within any known SMRAM range.

  @param  Address   The address to check.

  @return TRUE if the address is in SMRAM. FALSE otherwise.
**/
BOOLEAN
IsAddressInSmram (
  IN EFI_PHYSICAL_ADDRESS  Address
  )
{
  UINTN Index;

  if (mSmramRangeCount == 0) {
    return FALSE;
  }

  for (Index = 0; Index < mSmramRangeCount; Index++) {
    if (Address >= mSmramRanges[Index].CpuStart &&
        Address <  mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Free memory allocated from either SMRAM or boot services,
  selecting the appropriate free function based on address location.

  @param  Buffer   Pointer to the buffer to free.
**/
VOID
FreeMemory (
  IN VOID  *Buffer
  )
{
  EFI_STATUS Status;

  if (Buffer == NULL) {
    return;
  }

  if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer)) {
    Status = gSmst->SmmFreePool (Buffer);
  } else {
    Status = gBootServices->FreePool (Buffer);
  }

  ASSERT_EFI_ERROR (Status);
}

/**
  Save execution context to a jump buffer (SetJump equivalent).
  Preserves non-volatile general-purpose registers, MXCSR, and XMM6-XMM15.

  @param  JumpBuffer  The jump buffer to save context to.
  @return 0 when called directly.
**/
UINTN
EFIAPI
SetJump (
  IN BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer
  )
{
  ASSERT (JumpBuffer != NULL);
  ASSERT (((UINTN)JumpBuffer & (8 - 1)) == 0);

  SaveContext (JumpBuffer);

  //
  // Save non-volatile GPRs
  //
  JumpBuffer->Rbx = (UINT64)__Rbx;
  JumpBuffer->Rbp = (UINT64)__Rbp;
  JumpBuffer->Rdi = (UINT64)__Rdi;
  JumpBuffer->Rsi = (UINT64)__Rsi;
  JumpBuffer->R12 = (UINT64)__R12;
  JumpBuffer->R13 = (UINT64)__R13;
  JumpBuffer->R14 = (UINT64)__R14;
  JumpBuffer->R15 = (UINT64)__R15;
  JumpBuffer->Rip = (UINT64)__Rip;

  JumpBuffer->MxCsr = _mm_getcsr ();

  JumpBuffer->Xmm6  = __Xmm6;
  JumpBuffer->Xmm7  = __Xmm7;
  JumpBuffer->Xmm8  = __Xmm8;
  JumpBuffer->Xmm9  = __Xmm9;
  JumpBuffer->Xmm10 = __Xmm10;
  JumpBuffer->Xmm11 = __Xmm11;
  JumpBuffer->Xmm12 = __Xmm12;
  JumpBuffer->Xmm13 = __Xmm13;
  JumpBuffer->Xmm14 = __Xmm14;
  JumpBuffer->Xmm15 = __Xmm15;

  return JumpBuffer->Rip ();
}

/**
  Restore execution context from a jump buffer (LongJump equivalent).
  Restores non-volatile registers and jumps to the saved RIP.

  @param  JumpBuffer  The jump buffer to restore context from.
  @param  Value       The value to return from SetJump.
**/
VOID
EFIAPI
LongJump (
  IN BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,
  IN UINTN                     Value
  )
{
  _mm_setcsr (JumpBuffer->MxCsr);
  __ReturnFromJumpBuffer (JumpBuffer, Value);
}

/**
  Entry point for Address Translation DSM. This function:
  1. Locates the MemRas protocol
  2. Allocates a communication buffer for OS/SMM data exchange
  3. Registers the SW SMI handler
  4. Installs the SSDT ACPI table

  @return EFI_STATUS indicating success or failure.
**/
EFI_STATUS
AddressTranslationDsmEntry (
  VOID
  )
{
  EFI_STATUS Status;

  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Enter AddressTranslationDsmEntry\n"));

  //
  // Locate MemRas protocol
  //
  Status = gSmst->SmmLocateProtocol (&gMemRasProtocolGuid, NULL, (VOID **)&mMemRas);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
    goto Exit;
  }

  //
  // Allocate communication buffer (sizeof = 0x100 bytes)
  //
  Status = gBootServices->AllocatePool (
                            EfiBootServicesData,
                            sizeof (ADDRESS_TRANSLATION_DSM_COMMUNICATION_BUFFER),
                            (VOID **)&mCommunicationBuffer
                            );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
    goto Exit;
  }

  //
  // Register SW SMI handler
  //
  Status = RegisterSwSmi ();
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Install patched SSDT
  //
  Status = InstallSsdt ();

Exit:
  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Exit AddressTranslationDsmEntry: %r\n", Status));
  return Status;
}

/**
  Register a Software SMI handler that dispatches Address Translation DSM commands.
  The handler is triggered by SW_SMI_COMMAND_VALUE (0x97).

  @return EFI_STATUS.
**/
EFI_STATUS
RegisterSwSmi (
  VOID
  )
{
  EFI_STATUS                    Status;
  EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
  EFI_SMM_SW_REGISTER_CONTEXT   SwContext;
  EFI_HANDLE                    SwHandle;

  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Enter RegisterSwSmi\n"));

  //
  // Locate SMM SW Dispatch2 protocol
  //
  Status = gSmst->SmmLocateProtocol (
                    &gEfiSmmSwDispatch2ProtocolGuid,
                    NULL,
                    (VOID **)&SwDispatch
                    );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
    goto Exit;
  }

  //
  // Register SMI handler with input value 0x97 (151)
  //
  SwContext.SwSmiInputValue = SW_SMI_COMMAND_VALUE;
  ASSERT (SwContext.SwSmiInputValue < SwDispatch->MaximumSwiValue);

  Status = SwDispatch->Register (SwDispatch, SwSmiHandler, &SwContext, &SwHandle);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
  }

  ASSERT (SwDispatch->MaximumSwiValue <= MAX_UINT32);

  //
  // Store the SW SMI input value in the communication header
  //
  mCommunicationBuffer->SwSmiInputValue = SwContext.SwSmiInputValue;

  //
  // If already registered, treat as unsupported
  //
  if (Status == EFI_ALREADY_STARTED) {
    Status = EFI_UNSUPPORTED;
  }

Exit:
  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Exit RegisterSwSmi: %r\n", Status));
  return Status;
}

/**
  SMI handler for Address Translation DSM.
  Dispatches GET_ERROR_LOG and CLEAR_ERROR_LOG commands from the OS.

  Command 2 (GET_ERROR_LOG): Calls mMemRas->GetErrorLog() to retrieve
    memory error information and stores it in the communication buffer.

  Command 3 (CLEAR_ERROR_LOG): Calls mMemRas->ClearErrorLog() to
    clear memory error records.

  @param  DispatchHandle   SMI dispatch handle.
  @param  Context          Optional SMI context.

  @return EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
SwSmiHandler (
  IN EFI_HANDLE  DispatchHandle,
  IN CONST VOID  *Context OPTIONAL
  )
{
  ADDRESS_TRANSLATION_DSM_COMMUNICATION_BUFFER Buffer;
  ADDRESS_TRANSLATION_DSM_COMMUNICATION_BUFFER *CommBuffer;
  EFI_STATUS                                   Status;

  //
  // Check MemRas protocol availability
  //
  if (mMemRas == NULL) {
    ASSERT (mMemRas != NULL);
    if (mMemRas == NULL) {
      return EFI_UNSUPPORTED;
    }
  }

  //
  // Clear stack buffer
  //
  ZeroMem (&Buffer, sizeof (Buffer));
  CommBuffer = mCommunicationBuffer;

  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Enter SwSmiHandler\n"));

  //
  // Set status to "in progress" (2)
  //
  CommBuffer->Status = COMMAND_STATUS_IN_PROGRESS;

  //
  // Command: GET_ERROR_LOG (2)
  //
  if (CommBuffer->Command == COMMAND_GET_ERROR_LOG) {
    Status = mMemRas->GetErrorLog (
                        (VOID *)(UINTN)CommBuffer->Address0,
                        &Buffer
                        );
    CommBuffer->Status = (Status < 0) ? COMMAND_STATUS_ERROR : COMMAND_STATUS_SUCCESS;
  }

  //
  // Command: CLEAR_ERROR_LOG (3)
  //
  if (CommBuffer->Command == COMMAND_CLEAR_ERROR_LOG) {
    //
    // Copy input data from communication buffer
    //
    CopyMem (&Buffer, (VOID *)(UINTN)CommBuffer->Address0, sizeof (Buffer));

    Status = mMemRas->ClearErrorLog (&Buffer);
    CommBuffer->Status = (Status < 0) ? COMMAND_STATUS_ERROR : COMMAND_STATUS_SUCCESS;
  }

  //
  // If command succeeded, copy results back with sentinel handling.
  // Fields are conditionally written: if the output field value equals the
  // sentinel (-1 for QWORD/DWORD, 0xFF for BYTE), the original value is preserved.
  //
  if (CommBuffer->Status == COMMAND_STATUS_SUCCESS) {
    CommBuffer->Address0  = (Buffer.Address0  != (UINT64)-1)  ? Buffer.Address0  : (UINT64)-1;
    CommBuffer->Address1  = (Buffer.Address1  != (UINT64)-1)  ? Buffer.Address1  : (UINT64)-1;
    CommBuffer->Address2  = (Buffer.Address2  != (UINT64)-1)  ? Buffer.Address2  : (UINT64)-1;
    CommBuffer->Address3  = (Buffer.Address3  != (UINT64)-1)  ? Buffer.Address3  : (UINT64)-1;

    CommBuffer->Byte0     = (Buffer.Byte0     != 0xFF)         ? Buffer.Byte0     : (UINT8)-1;
    CommBuffer->Byte1     = (Buffer.Byte1     != 0xFF)         ? Buffer.Byte1     : (UINT8)-1;
    CommBuffer->Byte2     = (Buffer.Byte2     != 0xFF)         ? Buffer.Byte2     : (UINT8)-1;
    CommBuffer->Byte3     = (Buffer.Byte3     != 0xFF)         ? Buffer.Byte3     : (UINT8)-1;

    CommBuffer->Byte4     = (Buffer.Byte4     != 0xFF)         ? Buffer.Byte4     : (UINT8)-1;
    CommBuffer->Byte5     = (Buffer.Byte5     != 0xFF)         ? Buffer.Byte5     : (UINT8)-1;
    CommBuffer->Byte6     = (Buffer.Byte6     != 0xFF)         ? Buffer.Byte6     : (UINT8)-1;
    CommBuffer->Byte7     = (Buffer.Byte7     != 0xFF)         ? Buffer.Byte7     : (UINT8)-1;
    CommBuffer->Byte8     = (Buffer.Byte8     != 0xFF)         ? Buffer.Byte8     : (UINT8)-1;
    CommBuffer->Byte9     = (Buffer.Byte9     != 0xFF)         ? Buffer.Byte9     : (UINT8)-1;
    CommBuffer->Byte10    = (Buffer.Byte10    != 0xFF)         ? Buffer.Byte10    : (UINT8)-1;
    CommBuffer->Byte11    = (Buffer.Byte11    != 0xFF)         ? Buffer.Byte11    : (UINT8)-1;
    CommBuffer->Byte12    = (Buffer.Byte12    != 0xFF)         ? Buffer.Byte12    : (UINT8)-1;
    CommBuffer->Byte13    = (Buffer.Byte13    != 0xFF)         ? Buffer.Byte13    : (UINT8)-1;
    CommBuffer->Byte14    = (Buffer.Byte14    != 0xFF)         ? Buffer.Byte14    : (UINT8)-1;
    CommBuffer->Byte15    = (Buffer.Byte15    != 0xFF)         ? Buffer.Byte15    : (UINT8)-1;
    CommBuffer->Byte16    = (Buffer.Byte16    != 0xFF)         ? Buffer.Byte16    : (UINT8)-1;
    CommBuffer->Byte17    = (Buffer.Byte17    != 0xFF)         ? Buffer.Byte17    : (UINT8)-1;
    CommBuffer->Byte18    = (Buffer.Byte18    != 0xFF)         ? Buffer.Byte18    : (UINT8)-1;
    CommBuffer->Byte19    = (Buffer.Byte19    != 0xFF)         ? Buffer.Byte19    : (UINT8)-1;
    CommBuffer->Byte20    = (Buffer.Byte20    != 0xFF)         ? Buffer.Byte20    : (UINT8)-1;

    CommBuffer->Qword5    = (Buffer.Qword5    != (UINT64)-1)   ? Buffer.Qword5    : (UINT64)-1;
    CommBuffer->Qword6    = (Buffer.Qword6    != (UINT64)-1)   ? Buffer.Qword6    : (UINT64)-1;
    CommBuffer->Qword7    = (Buffer.Qword7    != (UINT64)-1)   ? Buffer.Qword7    : (UINT64)-1;
    CommBuffer->Qword8    = (Buffer.Qword8    != (UINT64)-1)   ? Buffer.Qword8    : (UINT64)-1;

    CommBuffer->Dword3    = (Buffer.Dword3    != (UINT32)-1)   ? Buffer.Dword3    : (UINT32)-1;
    CommBuffer->Dword4    = (Buffer.Dword4    != (UINT32)-1)   ? Buffer.Dword4    : (UINT32)-1;
  }

  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Exit SwSmiHandler\n"));
  return EFI_SUCCESS;
}

/**
  Install a patched SSDT ACPI table for Address Translation DSM.
  Reads the SSDT raw data from firmware volume and patches the
  ADDRESS_TRANSLATION_DSM_SSDT_SIGNATURE signature offset with
  the communication buffer address.

  @return EFI_STATUS.
**/
EFI_STATUS
InstallSsdt (
  VOID
  )
{
  EFI_STATUS              Status;
  EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  VOID                    *SsdtData;
  UINTN                   SsdtSize;
  UINT8                   *Data;
  UINTN                   Offset;
  UINTN                   EndOffset;

  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Enter InstallSsdt\n"));

  //
  // Locate ACPI Table protocol
  //
  Status = gBootServices->LocateProtocol (
                            &gEfiAcpiTableProtocolGuid,
                            NULL,
                            (VOID **)&AcpiTable
                            );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
    goto Exit;
  }

  //
  // Read SSDT firmware file by GUID from Firmware Volume
  //
  Status = GetSectionFromFv (
             &gAddressTranslationDsmSsdtFileGuid,
             &SsdtData,
             &SsdtSize
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
    goto Exit;
  }

  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Enter PatchSsdt\n"));

  //
  // Search for the SSDT signature pattern to patch.
  // Pattern: ExtOpPrefix (0x5B), OpRegion/CreateField (0x80), "BUFF" signature,
  //          0x00, 0x0C (DWordConst), <4-byte address>, 0x0C (DWordConst)
  //
  Offset = (UINTN)SsdtData + 36;
  EndOffset = (UINTN)SsdtData + *(UINT32 *)((UINTN)SsdtData + 4) + (UINTN)SsdtData - 16;

  while (Offset < EndOffset) {
    Data = (UINT8 *)Offset;
    if (Data[0] == 0x5B &&          // ExtOpPrefix
        Data[1] == 0x80 &&          // CreateField/OpRegion
        *(UINT32 *)&Data[2] == 0x46465542 && // "BUFF"
        Data[6] == 0x00 &&
        Data[7] == 0x0C &&          // DWordConst
        Data[12] == 0x0C) {         // DWordConst
      //
      // Patch the buffer address to point to the communication buffer
      //
      *(UINT32 *)&Data[8] = (UINT32)(UINTN)mCommunicationBuffer;
      *(UINT32 *)&Data[13] = sizeof (ADDRESS_TRANSLATION_DSM_COMMUNICATION_BUFFER);
      break;
    }
    Offset++;
  }

  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Exit PatchSsdt: %r\n", Status));

  if (Status < 0) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  //
  // Install the SSDT ACPI table
  //
  {
    UINTN TableKey = 0;
    Status = AcpiTable->InstallAcpiTable (
                          AcpiTable,
                          SsdtData,
                          SsdtSize,
                          &TableKey
                          );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
      ASSERT_EFI_ERROR (Status);
    }
  }

  DEBUG ((EFI_D_INFO, "[AddressTranslationDsm] Exit InstallSsdt: %r\n", Status));

Exit:
  return Status;
}

/**
  Read a section from Firmware Volume by GUID.

  @param[in]  FileGuid      The GUID identifying the file in FV.
  @param[out] Buffer        Pointer to receive the buffer.
  @param[out] Size          Pointer to receive the size.

  @return EFI_STATUS.
**/
EFI_STATUS
GetSectionFromFv (
  IN  EFI_GUID  *FileGuid,
  OUT VOID      **Buffer,
  OUT UINTN     *Size
  )
{
  EFI_STATUS                  Status;
  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
  VOID                        *FvInstance;

  //
  // Locate firmware volume protocol by image handle
  //
  if (gImageHandle == NULL) {
    ASSERT (gImageHandle != NULL);
    return EFI_UNSUPPORTED;
  }

  Status = gBS->OpenProtocol (
                  gImageHandle,
                  &gEfiFirmwareVolume2ProtocolGuid,
                  &FvInstance,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  *Buffer = 0;
  *Size = 0;

  //
  // Read the raw file section
  //
  Status = FvProtocol->ReadSection (
                         FvInstance,
                         FileGuid,
                         EFI_SECTION_RAW,
                         0,
                         Buffer,
                         Size
                         );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (*Buffer != NULL);
  ASSERT (*Size != 0);

  return EFI_SUCCESS;
}

/**
  Module entry point.
  Attempts to initialize and start the Address Translation DSM driver.

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

  @return EFI_STATUS.
**/
EFI_STATUS
EFIAPI
ModuleEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                Status;
  BASE_LIBRARY_JUMP_BUFFER  JumpBuffer;

  //
  // Initialize boot services and SMM globals
  //
  UefiBootServicesTableLibConstructor (ImageHandle, SystemTable);

  //
  // Set module status to EFI_SUCCESS initially
  //
  mModuleStatus = 0x8000000000000001uLL;

  //
  // Attempt to initialize with SetJump for error recovery
  //
  if (SetJump (&JumpBuffer) == 0) {
    Status = AddressTranslationDsmEntry ();

    //
    // Update module status if needed
    //
    if (Status >= 0 || mModuleStatus < 0) {
      mModuleStatus = Status;
    }
  }

  LongJump (&JumpBuffer, -1);

  //
  // Check final status and free memory if failed
  //
  Status = mModuleStatus;
  if (Status < 0) {
    FreeMemory (mCommunicationBuffer);
  }

  return Status;
}