/** @file
  ACPI Table Protocol Implementation

  Copyright (c) 2006 - 2025, Intel Corporation. All rights reserved.<BR>
  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

//
// Includes
//
#include "AcpiTable.h"
//
// The maximum number of tables that pre-allocated.
//
UINTN  mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES;

//
// Allocation strategy to use for AllocatePages ().
// Runtime value depends on PcdExposedAcpiTableVersions.
//
STATIC EFI_ALLOCATE_TYPE  mAcpiTableAllocType;

/**
  This function adds an ACPI table to the table list.  It will detect FACS and
  allocate the correct type of memory and properly align the table.

  @param  AcpiTableInstance         Instance of the protocol.
  @param  Table                     Table to add.
  @param  Checksum                  Does the table require checksumming.
  @param  Version                   The version of the list to add the table to.
  @param  IsFromHob                 True, if add Apci Table from Hob List.
  @param  Handle                    Pointer for returning the handle.

  @return EFI_SUCCESS               The function completed successfully.
  @return EFI_OUT_OF_RESOURCES      Could not allocate a required resource.
  @return EFI_ABORTED               The table is a duplicate of a table that is required
                                    to be unique.

**/
EFI_STATUS
AddTableToList (
  IN EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance,
  IN VOID                     *Table,
  IN BOOLEAN                  Checksum,
  IN EFI_ACPI_TABLE_VERSION   Version,
  IN BOOLEAN                  IsFromHob,
  OUT UINTN                   *Handle
  );

/**
  This function finds and removes the table specified by the handle.

  @param  AcpiTableInstance  Instance of the protocol.
  @param  Version            Bitmask of which versions to remove.
  @param  Handle             Table to remove.

  @return EFI_SUCCESS    The function completed successfully.
  @return EFI_ABORTED    An error occurred.
  @return EFI_NOT_FOUND  Handle not found in table list.

**/
EFI_STATUS
RemoveTableFromList (
  IN EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance,
  IN EFI_ACPI_TABLE_VERSION   Version,
  IN UINTN                    Handle
  );

/**
  This function calculates and updates an UINT8 checksum.

  @param  Buffer          Pointer to buffer to checksum
  @param  Size            Number of bytes to checksum
  @param  ChecksumOffset  Offset to place the checksum result in

  @return EFI_SUCCESS             The function completed successfully.
**/
EFI_STATUS
AcpiPlatformChecksum (
  IN VOID   *Buffer,
  IN UINTN  Size,
  IN UINTN  ChecksumOffset
  );

/**
  Checksum all versions of the common tables, RSDP, RSDT, XSDT.

  @param  AcpiTableInstance  Protocol instance private data.

  @return EFI_SUCCESS        The function completed successfully.

**/
EFI_STATUS
ChecksumCommonTables (
  IN OUT EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance
  );

//
// Protocol function implementations.
//

/**
  This function publishes the specified versions of the ACPI tables by
  installing EFI configuration table entries for them.  Any combination of
  table versions can be published.

  @param  AcpiTableInstance  Instance of the protocol.
  @param  Version            Version(s) to publish.

  @return EFI_SUCCESS  The function completed successfully.
  @return EFI_ABORTED  The function could not complete successfully.

**/
EFI_STATUS
EFIAPI
PublishTables (
  IN EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance,
  IN EFI_ACPI_TABLE_VERSION   Version
  )
{
  EFI_STATUS  Status;
  UINT32      *CurrentRsdtEntry;
  VOID        *CurrentXsdtEntry;
  UINT64      Buffer64;

  //
  // Reorder tables as some operating systems don't seem to find the
  // FADT correctly if it is not in the first few entries
  //

  //
  // Add FADT as the first entry
  //
  if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    CurrentRsdtEntry  = (UINT32 *)((UINT8 *)AcpiTableInstance->Rsdt1 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
    *CurrentRsdtEntry = (UINT32)(UINTN)AcpiTableInstance->Fadt1;

    CurrentRsdtEntry  = (UINT32 *)((UINT8 *)AcpiTableInstance->Rsdt3 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
    *CurrentRsdtEntry = (UINT32)(UINTN)AcpiTableInstance->Fadt3;
  }

  if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
    CurrentXsdtEntry = (VOID *)((UINT8 *)AcpiTableInstance->Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
    //
    // Add entry to XSDT, XSDT expects 64 bit pointers, but
    // the table pointers in XSDT are not aligned on 8 byte boundary.
    //
    Buffer64 = (UINT64)(UINTN)AcpiTableInstance->Fadt3;
    CopyMem (
      CurrentXsdtEntry,
      &Buffer64,
      sizeof (UINT64)
      );
  }

  //
  // Do checksum again because Dsdt/Xsdt is updated.
  //
  ChecksumCommonTables (AcpiTableInstance);

  //
  // Add the RSD_PTR to the system table and store that we have installed the
  // tables.
  //
  if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    Status = gBS->InstallConfigurationTable (&gEfiAcpi10TableGuid, AcpiTableInstance->Rsdp1);
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }
  }

  if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
    Status = gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, AcpiTableInstance->Rsdp3);
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }
  }

  return EFI_SUCCESS;
}

/**
  Installs an ACPI table into the RSDT/XSDT.
  Note that the ACPI table should be checksumed before installing it.
  Otherwise it will assert.

  @param  This                 Protocol instance pointer.
  @param  AcpiTableBuffer      A pointer to a buffer containing the ACPI table to be installed.
  @param  AcpiTableBufferSize  Specifies the size, in bytes, of the AcpiTableBuffer buffer.
  @param  TableKey             Reurns a key to refer to the ACPI table.

  @return EFI_SUCCESS            The table was successfully inserted.
  @return EFI_INVALID_PARAMETER  Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize
                                 and the size field embedded in the ACPI table pointed to by AcpiTableBuffer
                                 are not in sync.
  @return EFI_OUT_OF_RESOURCES   Insufficient resources exist to complete the request.
  @retval EFI_ACCESS_DENIED      The table signature matches a table already
                                 present in the system and platform policy
                                 does not allow duplicate tables of this type.

**/
EFI_STATUS
EFIAPI
InstallAcpiTable (
  IN   EFI_ACPI_TABLE_PROTOCOL  *This,
  IN   VOID                     *AcpiTableBuffer,
  IN   UINTN                    AcpiTableBufferSize,
  OUT  UINTN                    *TableKey
  )
{
  EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance;
  EFI_STATUS               Status;
  VOID                     *AcpiTableBufferConst;
  EFI_ACPI_TABLE_VERSION   Version;

  //
  // Check for invalid input parameters
  //
  if (  (AcpiTableBuffer == NULL) || (TableKey == NULL)
     || (((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTableBuffer)->Length != AcpiTableBufferSize))
  {
    return EFI_INVALID_PARAMETER;
  }

  Version = PcdGet32 (PcdAcpiExposedTableVersions);

  //
  // Get the instance of the ACPI table protocol
  //
  AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);

  //
  // Install the ACPI table
  //
  AcpiTableBufferConst = AllocateCopyPool (AcpiTableBufferSize, AcpiTableBuffer);
  *TableKey            = 0;
  Status               = AddTableToList (
                           AcpiTableInstance,
                           AcpiTableBufferConst,
                           TRUE,
                           Version,
                           FALSE,
                           TableKey
                           );
  if (!EFI_ERROR (Status)) {
    Status = PublishTables (
               AcpiTableInstance,
               Version
               );
  }

  FreePool (AcpiTableBufferConst);

  //
  // Add a new table successfully, notify registed callback
  //
  if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
    if (!EFI_ERROR (Status)) {
      SdtNotifyAcpiList (
        AcpiTableInstance,
        Version,
        *TableKey
        );
    }
  }

  return Status;
}

/**
  Removes an ACPI table from the RSDT/XSDT.

  @param  This      Protocol instance pointer.
  @param  TableKey  Specifies the table to uninstall.  The key was returned from InstallAcpiTable().

  @return EFI_SUCCESS    The table was successfully uninstalled.
  @return EFI_NOT_FOUND  TableKey does not refer to a valid key for a table entry.

**/
EFI_STATUS
EFIAPI
UninstallAcpiTable (
  IN  EFI_ACPI_TABLE_PROTOCOL  *This,
  IN  UINTN                    TableKey
  )
{
  EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance;
  EFI_STATUS               Status;
  EFI_ACPI_TABLE_VERSION   Version;

  //
  // Get the instance of the ACPI table protocol
  //
  AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);

  Version = PcdGet32 (PcdAcpiExposedTableVersions);

  //
  // Uninstall the ACPI table
  //
  Status = RemoveTableFromList (
             AcpiTableInstance,
             Version,
             TableKey
             );
  if (!EFI_ERROR (Status)) {
    Status = PublishTables (
               AcpiTableInstance,
               Version
               );
  }

  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  } else {
    return EFI_SUCCESS;
  }
}

/**
  If the number of APCI tables exceeds the preallocated max table number, enlarge the table buffer.

  @param  AcpiTableInstance       ACPI table protocol instance data structure.

  @return EFI_SUCCESS             reallocate the table beffer successfully.
  @return EFI_OUT_OF_RESOURCES    Unable to allocate required resources.

**/
EFI_STATUS
ReallocateAcpiTableBuffer (
  IN EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance
  )
{
  UINTN                    NewMaxTableNumber;
  UINTN                    TotalSize;
  UINT8                    *Pointer;
  EFI_PHYSICAL_ADDRESS     PageAddress;
  EFI_ACPI_TABLE_INSTANCE  TempPrivateData;
  EFI_STATUS               Status;
  UINT64                   CurrentData;
  EFI_MEMORY_TYPE          AcpiAllocateMemoryType;

  CopyMem (&TempPrivateData, AcpiTableInstance, sizeof (EFI_ACPI_TABLE_INSTANCE));
  //
  // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES
  //
  NewMaxTableNumber = mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES;
  //
  // Create RSDT, XSDT structures and allocate buffers.
  //
  TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT
              NewMaxTableNumber * sizeof (UINT64);

  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) +      // for ACPI 1.0 RSDT
                 NewMaxTableNumber * sizeof (UINT32) +
                 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +      // for ACPI 2.0/3.0 RSDT
                 NewMaxTableNumber * sizeof (UINT32);
  }

  if (PcdGetBool (PcdNoACPIReclaimMemory)) {
    AcpiAllocateMemoryType = EfiACPIMemoryNVS;
  } else {
    AcpiAllocateMemoryType = EfiACPIReclaimMemory;
  }

  if (mAcpiTableAllocType != AllocateAnyPages) {
    //
    // Allocate memory in the lower 32 bit of address range for
    // compatibility with ACPI 1.0 OS.
    //
    // This is done because ACPI 1.0 pointers are 32 bit values.
    // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
    // There is no architectural reason these should be below 4GB, it is purely
    // for convenience of implementation that we force memory below 4GB.
    //
    PageAddress = 0xFFFFFFFF;
    Status      = gBS->AllocatePages (
                         mAcpiTableAllocType,
                         AcpiAllocateMemoryType,
                         EFI_SIZE_TO_PAGES (TotalSize),
                         &PageAddress
                         );
  } else {
    Status = gBS->AllocatePool (
                    AcpiAllocateMemoryType,
                    TotalSize,
                    (VOID **)&Pointer
                    );
  }

  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (mAcpiTableAllocType != AllocateAnyPages) {
    Pointer = (UINT8 *)(UINTN)PageAddress;
  }

  ZeroMem (Pointer, TotalSize);

  AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    Pointer                 += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));
    AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
    Pointer                 += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));
  }

  AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;

  //
  // Update RSDP to point to the new Rsdt and Xsdt address.
  //
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32)(UINTN)AcpiTableInstance->Rsdt1;
    AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32)(UINTN)AcpiTableInstance->Rsdt3;
  }

  CurrentData = (UINT64)(UINTN)AcpiTableInstance->Xsdt;
  CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));

  //
  // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer
  //
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    CopyMem (AcpiTableInstance->Rsdt1, TempPrivateData.Rsdt1, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));
    CopyMem (AcpiTableInstance->Rsdt3, TempPrivateData.Rsdt3, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));
  }

  CopyMem (AcpiTableInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64)));

  if (mAcpiTableAllocType != AllocateAnyPages) {
    //
    // Calculate orignal ACPI table buffer size
    //
    TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT
                mEfiAcpiMaxNumTables * sizeof (UINT64);

    if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
      TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 1.0 RSDT
                   mEfiAcpiMaxNumTables * sizeof (UINT32) +
                   sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 RSDT
                   mEfiAcpiMaxNumTables * sizeof (UINT32);
    }

    gBS->FreePages (
           (EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1,
           EFI_SIZE_TO_PAGES (TotalSize)
           );
  } else {
    gBS->FreePool (TempPrivateData.Rsdt1);
  }

  //
  // Update the Max ACPI table number
  //
  mEfiAcpiMaxNumTables = NewMaxTableNumber;
  return EFI_SUCCESS;
}

/**
  Free the memory associated with the provided EFI_ACPI_TABLE_LIST instance.

  @param  TableEntry                EFI_ACPI_TABLE_LIST instance pointer

**/
STATIC
VOID
FreeTableMemory (
  EFI_ACPI_TABLE_LIST  *TableEntry
  )
{
  if (TableEntry->PoolAllocation) {
    gBS->FreePool (TableEntry->Table);
  } else {
    gBS->FreePages (
           (EFI_PHYSICAL_ADDRESS)(UINTN)TableEntry->Table,
           EFI_SIZE_TO_PAGES (TableEntry->TableSize)
           );
  }
}

/**
  This function adds an ACPI table to the table list.  It will detect FACS and
  allocate the correct type of memory and properly align the table.

  @param  AcpiTableInstance         Instance of the protocol.
  @param  Table                     Table to add.
  @param  Checksum                  Does the table require checksumming.
  @param  Version                   The version of the list to add the table to.
  @param  IsFromHob                 True, if add Apci Table from Hob List.
  @param  Handle                    Pointer for returning the handle.

  @return EFI_SUCCESS               The function completed successfully.
  @return EFI_OUT_OF_RESOURCES      Could not allocate a required resource.
  @retval EFI_ACCESS_DENIED         The table signature matches a table already
                                    present in the system and platform policy
                                    does not allow duplicate tables of this type.

**/
EFI_STATUS
AddTableToList (
  IN EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance,
  IN VOID                     *Table,
  IN BOOLEAN                  Checksum,
  IN EFI_ACPI_TABLE_VERSION   Version,
  IN BOOLEAN                  IsFromHob,
  OUT UINTN                   *Handle
  )
{
  EFI_STATUS            Status;
  EFI_ACPI_TABLE_LIST   *CurrentTableList;
  UINT32                CurrentTableSignature;
  UINT32                CurrentTableSize;
  UINT32                *CurrentRsdtEntry;
  VOID                  *CurrentXsdtEntry;
  EFI_PHYSICAL_ADDRESS  AllocPhysAddress;
  UINT64                Buffer64;
  BOOLEAN               AddToRsdt;
  EFI_MEMORY_TYPE       AcpiAllocateMemoryType;

  //
  // Check for invalid input parameters
  //
  ASSERT (AcpiTableInstance);
  ASSERT (Table);
  ASSERT (Handle);

  //
  // Init locals
  //
  AddToRsdt = TRUE;

  //
  // Create a new list entry
  //
  CurrentTableList = AllocatePool (sizeof (EFI_ACPI_TABLE_LIST));

  if (CurrentTableList == NULL) {
    ASSERT (CurrentTableList);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Determine table type and size
  //
  CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *)Table)->Signature;
  CurrentTableSize      = ((EFI_ACPI_COMMON_HEADER *)Table)->Length;

  //
  // Allocate a buffer for the table.  All tables are allocated in the lower 32 bits of address space
  // for backwards compatibility with ACPI 1.0 OS.
  //
  // This is done because ACPI 1.0 pointers are 32 bit values.
  // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
  // There is no architectural reason these should be below 4GB, it is purely
  // for convenience of implementation that we force memory below 4GB.
  //
  AllocPhysAddress                 = 0xFFFFFFFF;
  CurrentTableList->TableSize      = CurrentTableSize;
  CurrentTableList->PoolAllocation = FALSE;

  if (PcdGetBool (PcdNoACPIReclaimMemory)) {
    AcpiAllocateMemoryType = EfiACPIMemoryNVS;
  } else {
    AcpiAllocateMemoryType = EfiACPIReclaimMemory;
  }

  //
  // Allocation memory type depends on the type of the table
  //
  if ((CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
      (CurrentTableSignature == EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE))
  {
    //
    // Allocate memory for the FACS.  This structure must be aligned
    // on a 64 byte boundary and must be ACPI NVS memory.
    // Using AllocatePages should ensure that it is always aligned.
    // Do not change signature for new ACPI version because they are same.
    //
    // UEFI table also need to be in ACPI NVS memory, because some data field
    // could be updated by OS present agent. For example, BufferPtrAddress in
    // SMM communication ACPI table.
    //
    ASSERT ((EFI_PAGE_SIZE % 64) == 0);
    if (IsFromHob) {
      AllocPhysAddress = (UINTN)Table;
      Status           = EFI_SUCCESS;
    } else {
      Status = gBS->AllocatePages (
                      AllocateMaxAddress,
                      EfiACPIMemoryNVS,
                      EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),
                      &AllocPhysAddress
                      );
    }
  } else if (mAcpiTableAllocType == AllocateAnyPages) {
    //
    // If there is no allocation limit, there is also no need to use page
    // based allocations for ACPI tables, which may be wasteful on platforms
    // such as AArch64 that allocate multiples of 64 KB
    //
    Status = gBS->AllocatePool (
                    AcpiAllocateMemoryType,
                    CurrentTableList->TableSize,
                    (VOID **)&CurrentTableList->Table
                    );
    CurrentTableList->PoolAllocation = TRUE;
  } else {
    //
    // All other tables are ACPI reclaim memory, no alignment requirements.
    //
    Status = gBS->AllocatePages (
                    mAcpiTableAllocType,
                    AcpiAllocateMemoryType,
                    EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),
                    &AllocPhysAddress
                    );
    CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *)(UINTN)AllocPhysAddress;
  }

  //
  // Check return value from memory alloc.
  //
  if (EFI_ERROR (Status)) {
    gBS->FreePool (CurrentTableList);
    return EFI_OUT_OF_RESOURCES;
  }

  if (!CurrentTableList->PoolAllocation) {
    CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *)(UINTN)AllocPhysAddress;
  }

  //
  // Initialize the table contents
  //
  CurrentTableList->Signature = EFI_ACPI_TABLE_LIST_SIGNATURE;
  CopyMem (CurrentTableList->Table, Table, CurrentTableSize);
  CurrentTableList->Handle  = AcpiTableInstance->CurrentHandle++;
  *Handle                   = CurrentTableList->Handle;
  CurrentTableList->Version = Version;

  //
  // Update internal pointers if this is a required table.  If it is a required
  // table and a table of that type already exists, return an error.
  //
  // Calculate the checksum if the table is not FACS.
  //
  switch (CurrentTableSignature) {
    case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
      //
      // We don't add the FADT in the standard way because some
      // OS expect the FADT to be early in the table list.
      // So we always add it as the first element in the list.
      //
      AddToRsdt = FALSE;

      //
      // Check that the table has not been previously added.
      //
      if ((((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) && (AcpiTableInstance->Fadt1 != NULL)) ||
          (((Version & ACPI_TABLE_VERSION_GTE_2_0)  != 0) && (AcpiTableInstance->Fadt3 != NULL))
          )
      {
        FreeTableMemory (CurrentTableList);
        gBS->FreePool (CurrentTableList);
        return EFI_ACCESS_DENIED;
      }

      //
      // Add the table to the appropriate table version
      //
      if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
        //
        // Save a pointer to the table
        //
        AcpiTableInstance->Fadt1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)CurrentTableList->Table;

        //
        // Update pointers in FADT.  If tables don't exist this will put NULL pointers there.
        //
        AcpiTableInstance->Fadt1->FirmwareCtrl = (UINT32)(UINTN)AcpiTableInstance->Facs1;
        AcpiTableInstance->Fadt1->Dsdt         = (UINT32)(UINTN)AcpiTableInstance->Dsdt1;

        //
        // RSDP OEM information is updated to match the FADT OEM information
        //
        CopyMem (
          &AcpiTableInstance->Rsdp1->OemId,
          &AcpiTableInstance->Fadt1->Header.OemId,
          6
          );

        //
        // RSDT OEM information is updated to match the FADT OEM information.
        //
        CopyMem (
          &AcpiTableInstance->Rsdt1->OemId,
          &AcpiTableInstance->Fadt1->Header.OemId,
          6
          );

        CopyMem (
          &AcpiTableInstance->Rsdt1->OemTableId,
          &AcpiTableInstance->Fadt1->Header.OemTableId,
          sizeof (UINT64)
          );
        AcpiTableInstance->Rsdt1->OemRevision = AcpiTableInstance->Fadt1->Header.OemRevision;
      }

      if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
        //
        // Save a pointer to the table
        //
        AcpiTableInstance->Fadt3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)CurrentTableList->Table;

        //
        // Update pointers in FADT.  If tables don't exist this will put NULL pointers there.
        // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
        // vice-versa.
        //
        if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
          AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32)(UINTN)AcpiTableInstance->Facs3;
          ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
        } else {
          Buffer64 = (UINT64)(UINTN)AcpiTableInstance->Facs3;
          CopyMem (
            &AcpiTableInstance->Fadt3->XFirmwareCtrl,
            &Buffer64,
            sizeof (UINT64)
            );
          AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
        }

        if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {
          AcpiTableInstance->Fadt3->Dsdt = (UINT32)(UINTN)AcpiTableInstance->Dsdt3;
          //
          // Comment block "the caller installs the tables in "DSDT, FADT" order"
          // The below comments are also in "the caller installs the tables in "FADT, DSDT" order" comment block.
          //
          // The ACPI specification, up to and including revision 5.1 Errata A,
          // allows the DSDT and X_DSDT fields to be both set in the FADT.
          // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)
          // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,
          // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,
          // but strangely an exception is 6.0 that has no this requirement.
          //
          // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally
          // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT
          // to have better compatibility as some OS may have assumption to only consume X_DSDT
          // field even the DSDT address is < 4G.
          //
          Buffer64 = AcpiTableInstance->Fadt3->Dsdt;
        } else {
          AcpiTableInstance->Fadt3->Dsdt = 0;
          Buffer64                       = (UINT64)(UINTN)AcpiTableInstance->Dsdt3;
        }

        CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));

        //
        // RSDP OEM information is updated to match the FADT OEM information
        //
        CopyMem (
          &AcpiTableInstance->Rsdp3->OemId,
          &AcpiTableInstance->Fadt3->Header.OemId,
          6
          );

        if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
          //
          // RSDT OEM information is updated to match FADT OEM information.
          //
          CopyMem (
            &AcpiTableInstance->Rsdt3->OemId,
            &AcpiTableInstance->Fadt3->Header.OemId,
            6
            );
          CopyMem (
            &AcpiTableInstance->Rsdt3->OemTableId,
            &AcpiTableInstance->Fadt3->Header.OemTableId,
            sizeof (UINT64)
            );
          AcpiTableInstance->Rsdt3->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;
        }

        //
        // XSDT OEM information is updated to match FADT OEM information.
        //
        CopyMem (
          &AcpiTableInstance->Xsdt->OemId,
          &AcpiTableInstance->Fadt3->Header.OemId,
          6
          );
        CopyMem (
          &AcpiTableInstance->Xsdt->OemTableId,
          &AcpiTableInstance->Fadt3->Header.OemTableId,
          sizeof (UINT64)
          );
        AcpiTableInstance->Xsdt->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;
      }

      //
      // Checksum the table
      //
      if (Checksum) {
        AcpiPlatformChecksum (
          CurrentTableList->Table,
          CurrentTableList->Table->Length,
          OFFSET_OF (
            EFI_ACPI_DESCRIPTION_HEADER,
            Checksum
            )
          );
      }

      break;

    case EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
      //
      // Check that the table has not been previously added.
      //
      if ((((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) && (AcpiTableInstance->Facs1 != NULL)) ||
          (((Version & ACPI_TABLE_VERSION_GTE_2_0)  != 0) && (AcpiTableInstance->Facs3 != NULL))
          )
      {
        FreeTableMemory (CurrentTableList);
        gBS->FreePool (CurrentTableList);
        return EFI_ACCESS_DENIED;
      }

      //
      // FACS is referenced by FADT and is not part of RSDT
      //
      AddToRsdt = FALSE;

      //
      // Add the table to the appropriate table version
      //
      if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
        //
        // Save a pointer to the table
        //
        AcpiTableInstance->Facs1 = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)CurrentTableList->Table;

        //
        // If FADT already exists, update table pointers.
        //
        if (AcpiTableInstance->Fadt1 != NULL) {
          AcpiTableInstance->Fadt1->FirmwareCtrl = (UINT32)(UINTN)AcpiTableInstance->Facs1;

          //
          // Checksum FADT table
          //
          AcpiPlatformChecksum (
            AcpiTableInstance->Fadt1,
            AcpiTableInstance->Fadt1->Header.Length,
            OFFSET_OF (
              EFI_ACPI_DESCRIPTION_HEADER,
              Checksum
              )
            );
        }
      }

      if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
        //
        // Save a pointer to the table
        //
        AcpiTableInstance->Facs3 = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)CurrentTableList->Table;

        //
        // If FADT already exists, update table pointers.
        //
        if (AcpiTableInstance->Fadt3 != NULL) {
          //
          // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
          // vice-versa.
          //
          if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
            AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32)(UINTN)AcpiTableInstance->Facs3;
            ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
          } else {
            Buffer64 = (UINT64)(UINTN)AcpiTableInstance->Facs3;
            CopyMem (
              &AcpiTableInstance->Fadt3->XFirmwareCtrl,
              &Buffer64,
              sizeof (UINT64)
              );
            AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
          }

          //
          // Checksum FADT table
          //
          AcpiPlatformChecksum (
            AcpiTableInstance->Fadt3,
            AcpiTableInstance->Fadt3->Header.Length,
            OFFSET_OF (
              EFI_ACPI_DESCRIPTION_HEADER,
              Checksum
              )
            );
        }
      }

      break;

    case EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Check that the table has not been previously added.
      //
      if ((((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) && (AcpiTableInstance->Dsdt1 != NULL)) ||
          (((Version & ACPI_TABLE_VERSION_GTE_2_0)  != 0) && (AcpiTableInstance->Dsdt3 != NULL))
          )
      {
        FreeTableMemory (CurrentTableList);
        gBS->FreePool (CurrentTableList);
        return EFI_ACCESS_DENIED;
      }

      //
      // DSDT is referenced by FADT and is not part of RSDT
      //
      AddToRsdt = FALSE;

      //
      // Add the table to the appropriate table version
      //
      if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
        //
        // Save a pointer to the table
        //
        AcpiTableInstance->Dsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTableList->Table;

        //
        // If FADT already exists, update table pointers.
        //
        if (AcpiTableInstance->Fadt1 != NULL) {
          AcpiTableInstance->Fadt1->Dsdt = (UINT32)(UINTN)AcpiTableInstance->Dsdt1;

          //
          // Checksum FADT table
          //
          AcpiPlatformChecksum (
            AcpiTableInstance->Fadt1,
            AcpiTableInstance->Fadt1->Header.Length,
            OFFSET_OF (
              EFI_ACPI_DESCRIPTION_HEADER,
              Checksum
              )
            );
        }
      }

      if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
        //
        // Save a pointer to the table
        //
        AcpiTableInstance->Dsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTableList->Table;

        //
        // If FADT already exists, update table pointers.
        //
        if (AcpiTableInstance->Fadt3 != NULL) {
          if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {
            AcpiTableInstance->Fadt3->Dsdt = (UINT32)(UINTN)AcpiTableInstance->Dsdt3;
            //
            // Comment block "the caller installs the tables in "FADT, DSDT" order"
            // The below comments are also in "the caller installs the tables in "DSDT, FADT" order" comment block.
            //
            // The ACPI specification, up to and including revision 5.1 Errata A,
            // allows the DSDT and X_DSDT fields to be both set in the FADT.
            // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)
            // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,
            // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,
            // but strangely an exception is 6.0 that has no this requirement.
            //
            // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally
            // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT
            // to have better compatibility as some OS may have assumption to only consume X_DSDT
            // field even the DSDT address is < 4G.
            //
            Buffer64 = AcpiTableInstance->Fadt3->Dsdt;
          } else {
            AcpiTableInstance->Fadt3->Dsdt = 0;
            Buffer64                       = (UINT64)(UINTN)AcpiTableInstance->Dsdt3;
          }

          CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));

          //
          // Checksum FADT table
          //
          AcpiPlatformChecksum (
            AcpiTableInstance->Fadt3,
            AcpiTableInstance->Fadt3->Header.Length,
            OFFSET_OF (
              EFI_ACPI_DESCRIPTION_HEADER,
              Checksum
              )
            );
        }
      }

      //
      // Checksum the table
      //
      if (Checksum) {
        AcpiPlatformChecksum (
          CurrentTableList->Table,
          CurrentTableList->Table->Length,
          OFFSET_OF (
            EFI_ACPI_DESCRIPTION_HEADER,
            Checksum
            )
          );
      }

      break;

    default:
      //
      // Checksum the table
      //
      if (Checksum) {
        AcpiPlatformChecksum (
          CurrentTableList->Table,
          CurrentTableList->Table->Length,
          OFFSET_OF (
            EFI_ACPI_DESCRIPTION_HEADER,
            Checksum
            )
          );
      }

      break;
  }

  //
  // Add the table to the current list of tables
  //
  InsertTailList (&AcpiTableInstance->TableList, &CurrentTableList->Link);

  //
  // Add the table to RSDT and/or XSDT table entry lists.
  //
  //
  // Add to ACPI 1.0b table tree
  //
  if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    if (AddToRsdt) {
      //
      // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
      //
      if (AcpiTableInstance->NumberOfTableEntries1 >= mEfiAcpiMaxNumTables) {
        Status = ReallocateAcpiTableBuffer (AcpiTableInstance);
        ASSERT_EFI_ERROR (Status);
      }

      CurrentRsdtEntry = (UINT32 *)
                         (
                          (UINT8 *)AcpiTableInstance->Rsdt1 +
                          sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
                          AcpiTableInstance->NumberOfTableEntries1 *
                          sizeof (UINT32)
                         );

      //
      // Add entry to the RSDT unless its the FACS or DSDT
      //
      *CurrentRsdtEntry = (UINT32)(UINTN)CurrentTableList->Table;

      //
      // Update RSDT length
      //
      AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof (UINT32);

      AcpiTableInstance->NumberOfTableEntries1++;
    }
  }

  //
  // Add to ACPI 2.0/3.0  table tree
  //
  if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
    if (AddToRsdt) {
      //
      // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
      //
      if (AcpiTableInstance->NumberOfTableEntries3 >= mEfiAcpiMaxNumTables) {
        Status = ReallocateAcpiTableBuffer (AcpiTableInstance);
        ASSERT_EFI_ERROR (Status);
      }

      if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
        //
        // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
        // If it becomes necessary to maintain separate table lists, changes will be required.
        //
        CurrentRsdtEntry = (UINT32 *)
                           (
                            (UINT8 *)AcpiTableInstance->Rsdt3 +
                            sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
                            AcpiTableInstance->NumberOfTableEntries3 *
                            sizeof (UINT32)
                           );

        //
        // Add entry to the RSDT
        //
        *CurrentRsdtEntry = (UINT32)(UINTN)CurrentTableList->Table;

        //
        // Update RSDT length
        //
        AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);
      }

      //
      // This pointer must not be directly dereferenced as the XSDT entries may not
      // be 64 bit aligned resulting in a possible fault.  Use CopyMem to update.
      //
      CurrentXsdtEntry = (VOID *)
                         (
                          (UINT8 *)AcpiTableInstance->Xsdt +
                          sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
                          AcpiTableInstance->NumberOfTableEntries3 *
                          sizeof (UINT64)
                         );

      //
      // Add entry to XSDT, XSDT expects 64 bit pointers, but
      // the table pointers in XSDT are not aligned on 8 byte boundary.
      //
      Buffer64 = (UINT64)(UINTN)CurrentTableList->Table;
      CopyMem (
        CurrentXsdtEntry,
        &Buffer64,
        sizeof (UINT64)
        );

      //
      // Update length
      //
      AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);

      AcpiTableInstance->NumberOfTableEntries3++;
    }
  }

  ChecksumCommonTables (AcpiTableInstance);
  return EFI_SUCCESS;
}

/**
  This function finds the table specified by the handle and returns a pointer to it.
  If the handle is not found, EFI_NOT_FOUND is returned and the contents of Table are
  undefined.

  @param  Handle      Table to find.
  @param  TableList   Table list to search
  @param  Table       Pointer to table found.

  @return EFI_SUCCESS    The function completed successfully.
  @return EFI_NOT_FOUND  No table found matching the handle specified.

**/
EFI_STATUS
FindTableByHandle (
  IN UINTN                 Handle,
  IN LIST_ENTRY            *TableList,
  OUT EFI_ACPI_TABLE_LIST  **Table
  )
{
  LIST_ENTRY           *CurrentLink;
  EFI_ACPI_TABLE_LIST  *CurrentTable;

  //
  // Check for invalid input parameters
  //
  ASSERT (Table);

  //
  // Find the table
  //
  CurrentLink = TableList->ForwardLink;

  while (CurrentLink != TableList) {
    CurrentTable = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);
    if (CurrentTable->Handle == Handle) {
      //
      // Found handle, so return this table.
      //
      *Table = CurrentTable;
      return EFI_SUCCESS;
    }

    CurrentLink = CurrentLink->ForwardLink;
  }

  //
  // Table not found
  //
  return EFI_NOT_FOUND;
}

/**
  This function removes a basic table from the RSDT and/or XSDT.
  For Acpi 1.0 tables, pass in the Rsdt.
  For Acpi 2.0 tables, pass in both Rsdt and Xsdt.

  @param  Table                 Pointer to table found.
  @param  NumberOfTableEntries  Current number of table entries in the RSDT/XSDT
  @param  Rsdt                  Pointer to the RSDT to remove from
  @param  Xsdt                  Pointer to the Xsdt to remove from

  @return EFI_SUCCESS            The function completed successfully.
  @return EFI_INVALID_PARAMETER  The table was not found in both Rsdt and Xsdt.

**/
EFI_STATUS
RemoveTableFromRsdt (
  IN OUT EFI_ACPI_TABLE_LIST          *Table,
  IN OUT UINTN                        *NumberOfTableEntries,
  IN OUT EFI_ACPI_DESCRIPTION_HEADER  *Rsdt OPTIONAL,
  IN OUT EFI_ACPI_DESCRIPTION_HEADER  *Xsdt OPTIONAL
  )
{
  UINT32  *CurrentRsdtEntry;
  VOID    *CurrentXsdtEntry;
  UINT64  CurrentTablePointer64;
  UINTN   Index;

  //
  // Check for invalid input parameters
  //
  ASSERT (Table);
  ASSERT (NumberOfTableEntries);
  ASSERT (Rsdt || Xsdt);

  //
  // Find the table entry in the RSDT and XSDT
  //
  for (Index = 0; Index < *NumberOfTableEntries; Index++) {
    //
    // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
    // If it becomes necessary to maintain separate table lists, changes will be required.
    //
    if (Rsdt != NULL) {
      CurrentRsdtEntry = (UINT32 *)((UINT8 *)Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));
    } else {
      CurrentRsdtEntry = NULL;
    }

    if (Xsdt != NULL) {
      //
      // This pointer must not be directly dereferenced as the XSDT entries may not
      // be 64 bit aligned resulting in a possible fault.  Use CopyMem to update.
      //
      CurrentXsdtEntry = (VOID *)((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT64));

      //
      // Read the entry value out of the XSDT
      //
      CopyMem (&CurrentTablePointer64, CurrentXsdtEntry, sizeof (UINT64));
    } else {
      //
      // Initialize to NULL
      //
      CurrentXsdtEntry      = 0;
      CurrentTablePointer64 = 0;
    }

    //
    // Check if we have found the corresponding entry in both RSDT and XSDT
    //
    if (((Rsdt == NULL) || ((CurrentRsdtEntry != NULL) && (*CurrentRsdtEntry == (UINT32)(UINTN)Table->Table))) &&
        ((Xsdt == NULL) || (CurrentTablePointer64 == (UINT64)(UINTN)Table->Table))
        )
    {
      //
      // Found entry, so copy all following entries and shrink table
      //
      if (Rsdt != NULL) {
        CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index - 1) * sizeof (UINT32));
        ZeroMem ((UINT8 *)Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + ((*NumberOfTableEntries - 1) * sizeof (UINT32)), sizeof (UINT32));
        Rsdt->Length = Rsdt->Length - sizeof (UINT32);
      }

      if (Xsdt != NULL) {
        CopyMem (CurrentXsdtEntry, ((UINT64 *)CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index - 1) * sizeof (UINT64));
        ZeroMem ((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + ((*NumberOfTableEntries - 1) * sizeof (UINT64)), sizeof (UINT64));
        Xsdt->Length = Xsdt->Length - sizeof (UINT64);
      }

      break;
    } else if (Index + 1 == *NumberOfTableEntries) {
      //
      // At the last entry, and table not found
      //
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Checksum the tables
  //
  if (Rsdt != NULL) {
    AcpiPlatformChecksum (
      Rsdt,
      Rsdt->Length,
      OFFSET_OF (
        EFI_ACPI_DESCRIPTION_HEADER,
        Checksum
        )
      );
  }

  if (Xsdt != NULL) {
    AcpiPlatformChecksum (
      Xsdt,
      Xsdt->Length,
      OFFSET_OF (
        EFI_ACPI_DESCRIPTION_HEADER,
        Checksum
        )
      );
  }

  //
  // Decrement the number of tables
  //
  (*NumberOfTableEntries)--;

  return EFI_SUCCESS;
}

/**
  This function removes a table and frees any associated memory.

  @param  AcpiTableInstance  Instance of the protocol.
  @param  Version            Version(s) to delete.
  @param  Table              Pointer to table found.

  @return EFI_SUCCESS  The function completed successfully.

**/
EFI_STATUS
DeleteTable (
  IN EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance,
  IN EFI_ACPI_TABLE_VERSION   Version,
  IN OUT EFI_ACPI_TABLE_LIST  *Table
  )
{
  UINT32   CurrentTableSignature;
  BOOLEAN  RemoveFromRsdt;

  //
  // Check for invalid input parameters
  //
  ASSERT (AcpiTableInstance);
  ASSERT (Table);

  //
  // Init locals
  //
  RemoveFromRsdt = TRUE;
  //
  // Check for Table->Table
  //
  ASSERT (Table->Table != NULL);
  CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *)Table->Table)->Signature;

  //
  // Basic tasks to accomplish delete are:
  //   Determine removal requirements (in RSDT/XSDT or not)
  //   Remove entry from RSDT/XSDT
  //   Remove any table references to the table
  //   If no one is using the table
  //      Free the table (removing pointers from private data and tables)
  //      Remove from list
  //      Free list structure
  //
  //
  // Determine if this table is in the RSDT or XSDT
  //
  if ((CurrentTableSignature == EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
      (CurrentTableSignature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||
      (CurrentTableSignature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)
      )
  {
    RemoveFromRsdt = FALSE;
  }

  //
  // We don't remove the FADT in the standard way because some
  // OS expect the FADT to be early in the table list.
  // So we always put it as the first element in the list.
  //
  if (CurrentTableSignature == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
    RemoveFromRsdt = FALSE;
  }

  //
  // Remove the table from RSDT and XSDT
  //
  if (Table->Table != NULL) {
    //
    // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt
    //
    if (Version & EFI_ACPI_TABLE_VERSION_NONE & Table->Version) {
      //
      // Remove this version from the table
      //
      Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_NONE;
    }

    if (Version & EFI_ACPI_TABLE_VERSION_1_0B & Table->Version) {
      //
      // Remove this version from the table
      //
      Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_1_0B;

      //
      // Remove from Rsdt.  We don't care about the return value because it is
      // acceptable for the table to not exist in Rsdt.
      // We didn't add some tables so we don't remove them.
      //
      if (RemoveFromRsdt) {
        RemoveTableFromRsdt (
          Table,
          &AcpiTableInstance->NumberOfTableEntries1,
          AcpiTableInstance->Rsdt1,
          NULL
          );
      }
    }

    if (Version & ACPI_TABLE_VERSION_GTE_2_0 & Table->Version) {
      //
      // Remove this version from the table
      //
      Table->Version = Table->Version &~(Version & ACPI_TABLE_VERSION_GTE_2_0);

      //
      // Remove from Rsdt and Xsdt.  We don't care about the return value
      // because it is acceptable for the table to not exist in Rsdt/Xsdt.
      // We didn't add some tables so we don't remove them.
      //
      if (RemoveFromRsdt) {
        RemoveTableFromRsdt (
          Table,
          &AcpiTableInstance->NumberOfTableEntries3,
          AcpiTableInstance->Rsdt3,
          AcpiTableInstance->Xsdt
          );
      }
    }

    //
    // Free the table, clean up any dependent tables and our private data pointers.
    //
    switch (Table->Table->Signature) {
      case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
        if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
          AcpiTableInstance->Fadt1 = NULL;
        }

        if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
          AcpiTableInstance->Fadt3 = NULL;
        }

        break;

      case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
        if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
          AcpiTableInstance->Facs1 = NULL;

          //
          // Update FADT table pointers
          //
          if (AcpiTableInstance->Fadt1 != NULL) {
            AcpiTableInstance->Fadt1->FirmwareCtrl = 0;

            //
            // Checksum table
            //
            AcpiPlatformChecksum (
              AcpiTableInstance->Fadt1,
              AcpiTableInstance->Fadt1->Header.Length,
              OFFSET_OF (
                EFI_ACPI_DESCRIPTION_HEADER,
                Checksum
                )
              );
          }
        }

        if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
          AcpiTableInstance->Facs3 = NULL;

          //
          // Update FADT table pointers
          //
          if (AcpiTableInstance->Fadt3 != NULL) {
            AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
            ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));

            //
            // Checksum table
            //
            AcpiPlatformChecksum (
              AcpiTableInstance->Fadt3,
              AcpiTableInstance->Fadt3->Header.Length,
              OFFSET_OF (
                EFI_ACPI_DESCRIPTION_HEADER,
                Checksum
                )
              );
          }
        }

        break;

      case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
        if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
          AcpiTableInstance->Dsdt1 = NULL;

          //
          // Update FADT table pointers
          //
          if (AcpiTableInstance->Fadt1 != NULL) {
            AcpiTableInstance->Fadt1->Dsdt = 0;

            //
            // Checksum table
            //
            AcpiPlatformChecksum (
              AcpiTableInstance->Fadt1,
              AcpiTableInstance->Fadt1->Header.Length,
              OFFSET_OF (
                EFI_ACPI_DESCRIPTION_HEADER,
                Checksum
                )
              );
          }
        }

        if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
          AcpiTableInstance->Dsdt3 = NULL;

          //
          // Update FADT table pointers
          //
          if (AcpiTableInstance->Fadt3 != NULL) {
            AcpiTableInstance->Fadt3->Dsdt = 0;
            ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));

            //
            // Checksum table
            //
            AcpiPlatformChecksum (
              AcpiTableInstance->Fadt3,
              AcpiTableInstance->Fadt3->Header.Length,
              OFFSET_OF (
                EFI_ACPI_DESCRIPTION_HEADER,
                Checksum
                )
              );
          }
        }

        break;

      default:
        //
        // Do nothing
        //
        break;
    }
  }

  //
  // If no version is using this table anymore, remove and free list entry.
  //
  if (Table->Version == 0) {
    //
    // Free the Table
    //
    FreeTableMemory (Table);
    RemoveEntryList (&(Table->Link));
    gBS->FreePool (Table);
  }

  //
  // Done
  //
  return EFI_SUCCESS;
}

/**
  This function finds and removes the table specified by the handle.

  @param  AcpiTableInstance  Instance of the protocol.
  @param  Version            Bitmask of which versions to remove.
  @param  Handle             Table to remove.

  @return EFI_SUCCESS    The function completed successfully.
  @return EFI_ABORTED    An error occurred.
  @return EFI_NOT_FOUND  Handle not found in table list.

**/
EFI_STATUS
RemoveTableFromList (
  IN EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance,
  IN EFI_ACPI_TABLE_VERSION   Version,
  IN UINTN                    Handle
  )
{
  EFI_ACPI_TABLE_LIST  *Table;
  EFI_STATUS           Status;

  Table = (EFI_ACPI_TABLE_LIST *)NULL;

  //
  // Check for invalid input parameters
  //
  ASSERT (AcpiTableInstance);

  //
  // Find the table
  //
  Status = FindTableByHandle (
             Handle,
             &AcpiTableInstance->TableList,
             &Table
             );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  //
  // Remove the table
  //
  Status = DeleteTable (AcpiTableInstance, Version, Table);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  //
  // Completed successfully
  //
  return EFI_SUCCESS;
}

/**
  This function calculates and updates an UINT8 checksum.

  @param  Buffer          Pointer to buffer to checksum
  @param  Size            Number of bytes to checksum
  @param  ChecksumOffset  Offset to place the checksum result in

  @return EFI_SUCCESS             The function completed successfully.

**/
EFI_STATUS
AcpiPlatformChecksum (
  IN VOID   *Buffer,
  IN UINTN  Size,
  IN UINTN  ChecksumOffset
  )
{
  UINT8  Sum;
  UINT8  *Ptr;

  Sum = 0;
  //
  // Initialize pointer
  //
  Ptr = Buffer;

  //
  // set checksum to 0 first
  //
  Ptr[ChecksumOffset] = 0;

  //
  // add all content of buffer
  //
  while ((Size--) != 0) {
    Sum = (UINT8)(Sum + (*Ptr++));
  }

  //
  // set checksum
  //
  Ptr                 = Buffer;
  Ptr[ChecksumOffset] = (UINT8)(0xff - Sum + 1);

  return EFI_SUCCESS;
}

/**
  Checksum all versions of the common tables, RSDP, RSDT, XSDT.

  @param  AcpiTableInstance  Protocol instance private data.

  @return EFI_SUCCESS        The function completed successfully.

**/
EFI_STATUS
ChecksumCommonTables (
  IN OUT EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance
  )
{
  //
  // RSDP ACPI 1.0 checksum for 1.0 table.  This is only the first 20 bytes of the structure
  //
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    AcpiPlatformChecksum (
      AcpiTableInstance->Rsdp1,
      sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
      OFFSET_OF (
        EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
        Checksum
        )
      );
  }

  //
  // RSDP ACPI 1.0 checksum for 2.0/3.0 table.  This is only the first 20 bytes of the structure
  //
  AcpiPlatformChecksum (
    AcpiTableInstance->Rsdp3,
    sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
    OFFSET_OF (
      EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
      Checksum
      )
    );

  //
  // RSDP ACPI 2.0/3.0 checksum, this is the entire table
  //
  AcpiPlatformChecksum (
    AcpiTableInstance->Rsdp3,
    sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
    OFFSET_OF (
      EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
      ExtendedChecksum
      )
    );

  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    //
    // RSDT checksums
    //
    AcpiPlatformChecksum (
      AcpiTableInstance->Rsdt1,
      AcpiTableInstance->Rsdt1->Length,
      OFFSET_OF (
        EFI_ACPI_DESCRIPTION_HEADER,
        Checksum
        )
      );

    AcpiPlatformChecksum (
      AcpiTableInstance->Rsdt3,
      AcpiTableInstance->Rsdt3->Length,
      OFFSET_OF (
        EFI_ACPI_DESCRIPTION_HEADER,
        Checksum
        )
      );
  }

  //
  // XSDT checksum
  //
  AcpiPlatformChecksum (
    AcpiTableInstance->Xsdt,
    AcpiTableInstance->Xsdt->Length,
    OFFSET_OF (
      EFI_ACPI_DESCRIPTION_HEADER,
      Checksum
      )
    );

  return EFI_SUCCESS;
}

/**
  This function will find gUniversalPayloadAcpiTableGuid Guid Hob, and install Acpi table from it.

  @param  AcpiTableInstance  Protocol instance private data.

  @return EFI_SUCCESS        The function completed successfully.
  @return EFI_NOT_FOUND      The function doesn't find the gEfiAcpiTableGuid Guid Hob.
  @return EFI_ABORTED        The function could not complete successfully.

**/
EFI_STATUS
InstallAcpiTableFromHob (
  EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance
  )
{
  EFI_HOB_GUID_TYPE                             *GuidHob;
  EFI_ACPI_TABLE_VERSION                        Version;
  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp;
  EFI_ACPI_DESCRIPTION_HEADER                   *Rsdt;
  EFI_ACPI_DESCRIPTION_HEADER                   *ChildTable;
  UINT64                                        ChildTableAddress;
  UINTN                                         Count;
  UINTN                                         Index;
  UINTN                                         TableKey;
  EFI_STATUS                                    Status;
  UINTN                                         EntrySize;
  UNIVERSAL_PAYLOAD_ACPI_TABLE                  *AcpiTableAdress;
  VOID                                          *TableToInstall;
  EFI_ACPI_SDT_HEADER                           *Table;
  UNIVERSAL_PAYLOAD_GENERIC_HEADER              *GenericHeader;

  TableKey = 0;
  Version  = PcdGet32 (PcdAcpiExposedTableVersions);
  Status   = EFI_SUCCESS;
  //
  // HOB only contains the ACPI table in 2.0+ format.
  //
  GuidHob = GetFirstGuidHob (&gUniversalPayloadAcpiTableGuid);
  if (GuidHob == NULL) {
    return EFI_NOT_FOUND;
  }

  GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
  if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob)) || (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
    return EFI_NOT_FOUND;
  }

  if (GenericHeader->Revision == UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION) {
    //
    // UNIVERSAL_PAYLOAD_ACPI_TABLE structure is used when Revision equals to UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION
    //
    AcpiTableAdress = (UNIVERSAL_PAYLOAD_ACPI_TABLE *)GET_GUID_HOB_DATA (GuidHob);
    if (AcpiTableAdress->Header.Length < UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD (UNIVERSAL_PAYLOAD_ACPI_TABLE, Rsdp)) {
      //
      // Retrun if can't find the ACPI Info Hob with enough length
      //
      return EFI_NOT_FOUND;
    }

    Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)(AcpiTableAdress->Rsdp);

    //
    // An ACPI-compatible OS must use the XSDT if present.
    // It shouldn't happen that XsdtAddress points beyond 4G range in 32-bit environment.
    //
    ASSERT ((UINTN)Rsdp->XsdtAddress == Rsdp->XsdtAddress);

    EntrySize = sizeof (UINT64);
    Rsdt      = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress;
    if (Rsdt == NULL) {
      //
      // XsdtAddress is zero, then we use Rsdt which has 32 bit entry
      //
      Rsdt      = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;
      EntrySize = sizeof (UINT32);
    }

    if (Rsdt->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
      return EFI_ABORTED;
    }

    Count = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / EntrySize;

    for (Index = 0; Index < Count; Index++) {
      ChildTableAddress = 0;
      CopyMem (&ChildTableAddress, (UINT8 *)(Rsdt + 1) + EntrySize * Index, EntrySize);
      //
      // If the address is of UINT64 while this module runs at 32 bits,
      // make sure the upper bits are all-zeros.
      //
      ASSERT (ChildTableAddress == (UINTN)ChildTableAddress);
      if (ChildTableAddress != (UINTN)ChildTableAddress) {
        Status = EFI_ABORTED;
        break;
      }

      ChildTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)ChildTableAddress;
      Status     = AddTableToList (AcpiTableInstance, ChildTable, TRUE, Version, TRUE, &TableKey);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table at 0x%p\n", ChildTable));
        ASSERT_EFI_ERROR (Status);
        break;
      }

      if (ChildTable->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
        //
        // Add the FACS and DSDT tables if it is not NULL.
        //
        if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->FirmwareCtrl != 0) {
          TableToInstall = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->FirmwareCtrl;
          Status         = AddTableToList (AcpiTableInstance, TableToInstall, TRUE, Version, TRUE, &TableKey);
          if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table FACS\n"));
            ASSERT_EFI_ERROR (Status);
            break;
          }
        }

        //
        // First check if xDSDT is available, as that is preferred as per
        // ACPI Spec 6.5+ Table 5-9 X_DSDT definition
        //
        if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->XDsdt != 0) {
          TableToInstall = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->XDsdt;
        } else if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->Dsdt != 0) {
          TableToInstall = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->Dsdt;
        } else {
          DEBUG ((DEBUG_ERROR, "DSDT table not found\n"));
          continue;
        }

        Status = AddTableToList (AcpiTableInstance, TableToInstall, TRUE, Version, TRUE, &TableKey);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table DSDT\n"));
          ASSERT_EFI_ERROR (Status);
          break;
        }
      }
    }
  } else {
    return EFI_NOT_FOUND;
  }

  if (EFI_ERROR (Status)) {
    //
    // Error happens when trying to add ACPI table to the list.
    // Remove all of them from list because at this time, no other tables except from HOB are in the list
    //
    while (SdtGetAcpiTable (AcpiTableInstance, 0, &Table, &Version, &TableKey) == EFI_SUCCESS) {
      RemoveTableFromList (AcpiTableInstance, Version, TableKey);
    }
  } else {
    Status = PublishTables (AcpiTableInstance, Version);
  }

  ASSERT_EFI_ERROR (Status);
  return Status;
}

/**
  This function is updating the instance with RSDP and RSDT, these are steps in the constructor that will be skipped if this HOB is available.

  @param  AcpiTableInstance  Protocol instance private data.
  @param  GuidHob            GUID HOB header.

  @return EFI_SUCCESS        The function completed successfully.
  @return EFI_NOT_FOUND      The function doesn't find the Rsdp from AcpiSiliconHob.
  @return EFI_ABORTED        The function could not complete successfully.

**/
EFI_STATUS
InstallAcpiTableFromAcpiSiliconHob (
  IN OUT EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance,
  IN     EFI_HOB_GUID_TYPE        *GuidHob
  )
{
  ACPI_SILICON_HOB                              *AcpiSiliconHob;
  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *SiAcpiHobRsdp;
  EFI_ACPI_DESCRIPTION_HEADER                   *SiCommonAcpiTable;
  EFI_STATUS                                    Status;
  UINTN                                         NumOfTblEntries;
  EFI_ACPI_TABLE_VERSION                        Version;
  UINT64                                        SocTablePtr;
  EFI_ACPI_DESCRIPTION_HEADER                   *SocEntryTable;
  UINTN                                         Index;
  UINTN                                         TableKey;
  VOID                                          *NeedToInstallTable;
  UINT8                                         *Buffer;
  EFI_PHYSICAL_ADDRESS                          PageAddress;
  UINTN                                         TotalSocTablesize;
  UINT8                                         *Pointer;
  EFI_MEMORY_TYPE                               AcpiAllocateMemoryType;
  UINTN                                         AcpiRsdpSize;

  DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob - Start\n"));
  //
  // Initial variable.
  //
  SiAcpiHobRsdp     = NULL;
  SiCommonAcpiTable = NULL;
  AcpiSiliconHob    = GET_GUID_HOB_DATA (GuidHob);
  Status            = EFI_SUCCESS;
  Version           = PcdGet32 (PcdAcpiExposedTableVersions);
  TableKey          = 0;

  if (PcdGetBool (PcdNoACPIReclaimMemory)) {
    AcpiAllocateMemoryType = EfiACPIMemoryNVS;
  } else {
    AcpiAllocateMemoryType = EfiACPIReclaimMemory;
  }

  //
  // Got RSDP table from ACPI Silicon Hob.
  //
  SiAcpiHobRsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)(AcpiSiliconHob->Rsdp);
  if (SiAcpiHobRsdp == NULL) {
    DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromAcpiSiliconHob: Fail to locate RSDP Acpi table from AcpiSiliconHob!!\n"));
    return EFI_NOT_FOUND;
  } else {
    DEBUG ((DEBUG_INFO, "ACPI HOB RSDP address : 0x%016lx\n", SiAcpiHobRsdp));
  }

  //
  // Reserved the ACPI reclaim memory for new RSDP space.
  //
  AcpiRsdpSize = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
  if (mAcpiTableAllocType != AllocateAnyPages) {
    PageAddress = 0xFFFFFFFF;
    Status      = gBS->AllocatePages (
                         mAcpiTableAllocType,
                         AcpiAllocateMemoryType,
                         EFI_SIZE_TO_PAGES (AcpiRsdpSize),
                         &PageAddress
                         );
  } else {
    Status = gBS->AllocatePool (
                    AcpiAllocateMemoryType,
                    AcpiRsdpSize,
                    (VOID **)&Pointer
                    );
  }

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Fail to allocate EfiACPIReclaimMemory for RSDP. Status : %r\n", Status));
    return Status;
  } else {
    if (mAcpiTableAllocType != AllocateAnyPages) {
      Pointer = (UINT8 *)(UINTN)PageAddress;
    }
  }

  ZeroMem (Pointer, AcpiRsdpSize);
  //
  // Copy RSDP content from ACPI Hob to the ACPI table Instance.
  //
  AcpiTableInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)Pointer;
  CopyMem (AcpiTableInstance->Rsdp3, SiAcpiHobRsdp, sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER));
  SiAcpiHobRsdp = AcpiTableInstance->Rsdp3;

  DEBUG ((DEBUG_INFO, "Current ACPI RSDP address : 0x%016lx\n", SiAcpiHobRsdp));

  //
  // Got XSDT address from RSDP table.
  //
  Buffer            = (UINT8 *)(UINTN)(SiAcpiHobRsdp->XsdtAddress);
  SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)Buffer;

  DEBUG ((DEBUG_INFO, "ACPI HOB XSDT address : 0x%016lx\n", SiCommonAcpiTable));

  if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
    DEBUG ((DEBUG_ERROR, "XSDT length is incorrect\n"));
    return EFI_ABORTED;
  }

  //
  // Calcaue 64bit Acpi table number.
  //
  NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64);
  DEBUG ((DEBUG_INFO, "64bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
  //
  // Reserved the ACPI reclaim memory for XSDT.
  //
  TotalSocTablesize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + (mEfiAcpiMaxNumTables * sizeof (UINT64));
  if (mAcpiTableAllocType != AllocateAnyPages) {
    //
    // Allocate memory in the lower 32 bit of address range for
    // compatibility with ACPI 1.0 OS.
    //
    // This is done because ACPI 1.0 pointers are 32 bit values.
    // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
    // There is no architectural reason these should be below 4GB, it is purely
    // for convenience of implementation that we force memory below 4GB.
    //
    PageAddress = 0xFFFFFFFF;
    Status      = gBS->AllocatePages (
                         mAcpiTableAllocType,
                         AcpiAllocateMemoryType,
                         EFI_SIZE_TO_PAGES (TotalSocTablesize),
                         &PageAddress
                         );
  } else {
    Status = gBS->AllocatePool (
                    AcpiAllocateMemoryType,
                    TotalSocTablesize,
                    (VOID **)&Pointer
                    );
  }

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Fail to allocate EfiACPIReclaimMemory for XSDT. Status : %r\n", Status));
    return EFI_OUT_OF_RESOURCES;
  }

  if (mAcpiTableAllocType != AllocateAnyPages) {
    Pointer = (UINT8 *)(UINTN)PageAddress;
  }

  ZeroMem (Pointer, TotalSocTablesize);
  AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Pointer;
  //
  // Update the XsdtAddress of the AcpiTableInstance's Rsdp3 field.
  //
  AcpiTableInstance->Rsdp3->XsdtAddress = (UINT64)(UINTN)AcpiTableInstance->Xsdt;
  //
  // Initial XSDT table content.
  //
  AcpiTableInstance->Xsdt->Signature = SiCommonAcpiTable->Signature;
  //
  // Always reserve first one for FADT table.
  //
  AcpiTableInstance->Xsdt->Length   = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + sizeof (UINT64);
  AcpiTableInstance->Xsdt->Revision = SiCommonAcpiTable->Revision;
  CopyMem (
    &AcpiTableInstance->Xsdt->OemId,
    SiCommonAcpiTable->OemId,
    sizeof (AcpiTableInstance->Xsdt->OemId)
    );
  CopyMem (
    &AcpiTableInstance->Xsdt->OemTableId,
    &SiCommonAcpiTable->OemTableId,
    sizeof (UINT64)
    );
  AcpiTableInstance->Xsdt->OemRevision     = SiCommonAcpiTable->OemRevision;
  AcpiTableInstance->Xsdt->CreatorId       = SiCommonAcpiTable->CreatorId;
  AcpiTableInstance->Xsdt->CreatorRevision = SiCommonAcpiTable->CreatorRevision;
  AcpiTableInstance->NumberOfTableEntries3 = 1;
  //
  // Extract ACPI table from AcpiSiliconHob XSDT.
  //
  for (Index = 0; Index < NumOfTblEntries; Index++) {
    CopyMem (&SocTablePtr, (((UINT8 *)(SiCommonAcpiTable + 1)) + ((sizeof (UINT64)) * Index)), sizeof (UINT64));
    SocEntryTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)SocTablePtr;
    //
    // Display table information.
    //
    DEBUG ((DEBUG_INFO, "[%x] Table address : 0x%016lx\n", Index, SocTablePtr));

    Buffer = (UINT8 *)&SocEntryTable->Signature;
    DEBUG ((DEBUG_INFO, "Table signature = %c%c%c%c\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3]));

    DEBUG ((DEBUG_INFO, "Table Length : 0x%x\n", SocEntryTable->Length));

    Buffer = (UINT8 *)&SocEntryTable->OemId;
    DEBUG (
      (DEBUG_INFO, "Table OemId = %c%c%c%c%c%c\n",
       Buffer[0],
       Buffer[1],
       Buffer[2],
       Buffer[3],
       Buffer[4],
       Buffer[5]
      )
      );

    Buffer = (UINT8 *)&SocEntryTable->OemTableId;
    DEBUG (
      (DEBUG_INFO, "Table OemTableId = %c%c%c%c%c%c%c%c\n",
       Buffer[0],
       Buffer[1],
       Buffer[2],
       Buffer[3],
       Buffer[4],
       Buffer[5],
       Buffer[6],
       Buffer[7]
      )
      );
    DEBUG ((DEBUG_INFO, "\n"));
    //
    // Add ACPI table in the DXE AcpiTableInstance.
    //
    Status = AddTableToList (AcpiTableInstance, SocEntryTable, TRUE, Version, TRUE, &TableKey);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromAcpiSiliconHob: Fail to add ACPI table at 0x%p\n", SocEntryTable));
      ASSERT_EFI_ERROR (Status);
      break;
    } else {
      Status = PublishTables (AcpiTableInstance, Version);
      if (!EFI_ERROR (Status)) {
        //
        // Add a new table successfully, notify registed callback
        //
        if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
          SdtNotifyAcpiList (AcpiTableInstance, Version, TableKey);
        }
      }
    }

    if (SocEntryTable->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
      //
      // According ACPI spec, if XDsdt field contains a nonzero value which can be used by the OSPM, then the Dsdt field must be ignored by the OSPM.
      //
      if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XDsdt != 0) {
        NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XDsdt;
      } else if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->Dsdt != 0) {
        NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->Dsdt;
      } else {
        //
        // The XDsdt or Dsdt not be detected, so set NeedToInstallTable to NULL to skip Dsdt installation.
        //
        NeedToInstallTable = NULL;
      }

      if (NeedToInstallTable != NULL) {
        //
        // if signature can not be found from the XDsdt / Dsdt field then skip it.
        //
        if (((EFI_ACPI_DESCRIPTION_HEADER *)NeedToInstallTable)->Signature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
          Status = AddTableToList (AcpiTableInstance, NeedToInstallTable, TRUE, Version, TRUE, &TableKey);
          if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "Fail to add DSDT in the DXE Table list!\n"));
            ASSERT_EFI_ERROR (Status);
            break;
          } else {
            Status = PublishTables (AcpiTableInstance, Version);
            if (!EFI_ERROR (Status)) {
              //
              // Add a new table successfully, notify registed callback
              //
              if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
                SdtNotifyAcpiList (AcpiTableInstance, Version, TableKey);
              }
            }

            DEBUG ((DEBUG_INFO, "Installed DSDT in the DXE Table list!\n"));
          }
        } else {
          DEBUG ((DEBUG_ERROR, "The DSDT content is not correct, then skip it!\n"));
        }
      } else {
        DEBUG ((DEBUG_ERROR, "The DSDT Table not initialized during PEI phase yet.\n"));
      }

      //
      // According ACPI spec, if XFirmwareCtrl field contains a nonzero value which can be used by the OSPM, then the FirmwareCtrl field must be ignored by the OSPM.
      //
      if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XFirmwareCtrl != 0) {
        NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XFirmwareCtrl;
      } else if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->FirmwareCtrl != 0) {
        NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->FirmwareCtrl;
      } else {
        //
        // The XFirmwareCtrl or FirmwareCtrl not be detected, so set NeedToInstallTable to NULL to skip Facs installation.
        //
        NeedToInstallTable = NULL;
      }

      if (NeedToInstallTable != NULL) {
        //
        // if signature can not be found from the XFirmwareCtrl / FirmwareCtrl field then skip it.
        //
        if (((EFI_ACPI_DESCRIPTION_HEADER *)NeedToInstallTable)->Signature == EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
          Status = AddTableToList (AcpiTableInstance, NeedToInstallTable, TRUE, Version, FALSE, &TableKey);
          if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "Fail to add FACS in the DXE Table list!\n"));
            ASSERT_EFI_ERROR (Status);
            break;
          } else {
            Status = PublishTables (AcpiTableInstance, Version);
            if (!EFI_ERROR (Status)) {
              //
              // Add a new table successfully, notify registed callback
              //
              if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
                SdtNotifyAcpiList (AcpiTableInstance, Version, TableKey);
              }
            }

            DEBUG ((DEBUG_INFO, "Installed FACS in the DXE Table list!\n"));
          }
        } else {
          DEBUG ((DEBUG_ERROR, "The FACS content is not correct, then skip it!\n"));
        }
      } else {
        DEBUG ((DEBUG_ERROR, "The FACS Table not initialized during PEI phase yet.\n"));
      }
    }
  }

  DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob - End\n"));
  return Status;
}

/**
  Constructor for the ACPI table protocol.  Initializes instance
  data.

  @param  AcpiTableInstance   Instance to construct

  @return EFI_SUCCESS             Instance initialized.
  @return EFI_OUT_OF_RESOURCES    Unable to allocate required resources.

**/
EFI_STATUS
AcpiTableAcpiTableConstructor (
  EFI_ACPI_TABLE_INSTANCE  *AcpiTableInstance
  )
{
  EFI_STATUS            Status;
  UINT64                CurrentData;
  UINTN                 TotalSize;
  UINTN                 RsdpTableSize;
  UINT8                 *Pointer;
  EFI_PHYSICAL_ADDRESS  PageAddress;
  EFI_MEMORY_TYPE       AcpiAllocateMemoryType;
  EFI_HOB_GUID_TYPE     *GuidHob;

  //
  // Check for invalid input parameters
  //
  ASSERT (AcpiTableInstance);

  //
  // If ACPI v1.0b is among the ACPI versions we aim to support, we have to
  // ensure that all memory allocations are below 4 GB.
  //
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    mAcpiTableAllocType = AllocateMaxAddress;
  } else {
    mAcpiTableAllocType = AllocateAnyPages;
  }

  InitializeListHead (&AcpiTableInstance->TableList);
  AcpiTableInstance->CurrentHandle = 1;

  AcpiTableInstance->AcpiTableProtocol.InstallAcpiTable   = InstallAcpiTable;
  AcpiTableInstance->AcpiTableProtocol.UninstallAcpiTable = UninstallAcpiTable;

  if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
    SdtAcpiTableAcpiSdtConstructor (AcpiTableInstance);
  }

  //
  // Check Silicon ACPI Hob.
  //
  GuidHob = GetFirstGuidHob (&gAcpiTableHobGuid);
  if (GuidHob != NULL) {
    Status = InstallAcpiTableFromAcpiSiliconHob (AcpiTableInstance, GuidHob);
    if (Status == EFI_SUCCESS) {
      DEBUG ((DEBUG_INFO, "Installed ACPI Table from AcpiSiliconHob.\n"));
      return EFI_SUCCESS;
    } else {
      DEBUG ((DEBUG_ERROR, "Fail to Installed ACPI Table from AcpiSiliconHob!!\n"));
      ASSERT (Status != EFI_SUCCESS);
    }
  } else {
    DEBUG ((DEBUG_INFO, "Fail to locate AcpiSiliconHob!!\n"));
  }

  //
  // Create RSDP table
  //
  RsdpTableSize = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    RsdpTableSize += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
  }

  if (PcdGetBool (PcdNoACPIReclaimMemory)) {
    AcpiAllocateMemoryType = EfiACPIMemoryNVS;
  } else {
    AcpiAllocateMemoryType = EfiACPIReclaimMemory;
  }

  if (mAcpiTableAllocType != AllocateAnyPages) {
    PageAddress = 0xFFFFFFFF;
    Status      = gBS->AllocatePages (
                         mAcpiTableAllocType,
                         AcpiAllocateMemoryType,
                         EFI_SIZE_TO_PAGES (RsdpTableSize),
                         &PageAddress
                         );
  } else {
    Status = gBS->AllocatePool (
                    AcpiAllocateMemoryType,
                    RsdpTableSize,
                    (VOID **)&Pointer
                    );
  }

  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (mAcpiTableAllocType != AllocateAnyPages) {
    Pointer = (UINT8 *)(UINTN)PageAddress;
  }

  ZeroMem (Pointer, RsdpTableSize);

  AcpiTableInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)Pointer;
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
  }

  AcpiTableInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)Pointer;

  //
  // Create RSDT, XSDT structures
  //
  TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT
              mEfiAcpiMaxNumTables * sizeof (UINT64);

  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) +      // for ACPI 1.0 RSDT
                 mEfiAcpiMaxNumTables * sizeof (UINT32) +
                 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +      // for ACPI 2.0/3.0 RSDT
                 mEfiAcpiMaxNumTables * sizeof (UINT32);
  }

  if (mAcpiTableAllocType != AllocateAnyPages) {
    //
    // Allocate memory in the lower 32 bit of address range for
    // compatibility with ACPI 1.0 OS.
    //
    // This is done because ACPI 1.0 pointers are 32 bit values.
    // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
    // There is no architectural reason these should be below 4GB, it is purely
    // for convenience of implementation that we force memory below 4GB.
    //
    PageAddress = 0xFFFFFFFF;
    Status      = gBS->AllocatePages (
                         mAcpiTableAllocType,
                         AcpiAllocateMemoryType,
                         EFI_SIZE_TO_PAGES (TotalSize),
                         &PageAddress
                         );
  } else {
    Status = gBS->AllocatePool (
                    AcpiAllocateMemoryType,
                    TotalSize,
                    (VOID **)&Pointer
                    );
  }

  if (EFI_ERROR (Status)) {
    if (mAcpiTableAllocType != AllocateAnyPages) {
      gBS->FreePages (
             (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiTableInstance->Rsdp1,
             EFI_SIZE_TO_PAGES (RsdpTableSize)
             );
    } else {
      gBS->FreePool (AcpiTableInstance->Rsdp1);
    }

    return EFI_OUT_OF_RESOURCES;
  }

  if (mAcpiTableAllocType != AllocateAnyPages) {
    Pointer = (UINT8 *)(UINTN)PageAddress;
  }

  ZeroMem (Pointer, TotalSize);

  AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    Pointer                 += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));
    AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
    Pointer                 += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));
  }

  AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;

  //
  // Initialize RSDP
  //
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    CurrentData = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;
    CopyMem (&AcpiTableInstance->Rsdp1->Signature, &CurrentData, sizeof (UINT64));
    CopyMem (AcpiTableInstance->Rsdp1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp1->OemId));
    AcpiTableInstance->Rsdp1->Reserved    = EFI_ACPI_RESERVED_BYTE;
    AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32)(UINTN)AcpiTableInstance->Rsdt1;
  }

  CurrentData = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;
  CopyMem (&AcpiTableInstance->Rsdp3->Signature, &CurrentData, sizeof (UINT64));
  CopyMem (AcpiTableInstance->Rsdp3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp3->OemId));
  AcpiTableInstance->Rsdp3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION;
  AcpiTableInstance->Rsdp3->Length   = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32)(UINTN)AcpiTableInstance->Rsdt3;
  }

  CurrentData = (UINT64)(UINTN)AcpiTableInstance->Xsdt;
  CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));
  SetMem (AcpiTableInstance->Rsdp3->Reserved, 3, EFI_ACPI_RESERVED_BYTE);

  if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
    //
    // Initialize Rsdt
    //
    // Note that we "reserve" one entry for the FADT so it can always be
    // at the beginning of the list of tables.  Some OS don't seem
    // to find it correctly if it is too far down the list.
    //
    AcpiTableInstance->Rsdt1->Signature = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
    AcpiTableInstance->Rsdt1->Length    = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
    AcpiTableInstance->Rsdt1->Revision  = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
    CopyMem (AcpiTableInstance->Rsdt1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt1->OemId));
    CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
    CopyMem (&AcpiTableInstance->Rsdt1->OemTableId, &CurrentData, sizeof (UINT64));
    AcpiTableInstance->Rsdt1->OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
    AcpiTableInstance->Rsdt1->CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
    AcpiTableInstance->Rsdt1->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
    //
    // We always reserve first one for FADT
    //
    AcpiTableInstance->NumberOfTableEntries1 = 1;
    AcpiTableInstance->Rsdt1->Length         = AcpiTableInstance->Rsdt1->Length + sizeof (UINT32);

    AcpiTableInstance->Rsdt3->Signature = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
    AcpiTableInstance->Rsdt3->Length    = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
    AcpiTableInstance->Rsdt3->Revision  = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
    CopyMem (AcpiTableInstance->Rsdt3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt3->OemId));
    CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
    CopyMem (&AcpiTableInstance->Rsdt3->OemTableId, &CurrentData, sizeof (UINT64));
    AcpiTableInstance->Rsdt3->OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
    AcpiTableInstance->Rsdt3->CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
    AcpiTableInstance->Rsdt3->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
    //
    // We always reserve first one for FADT
    //
    AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);
  }

  AcpiTableInstance->NumberOfTableEntries3 = 1;

  //
  // Initialize Xsdt
  //
  AcpiTableInstance->Xsdt->Signature = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
  AcpiTableInstance->Xsdt->Length    = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
  AcpiTableInstance->Xsdt->Revision  = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION;
  CopyMem (AcpiTableInstance->Xsdt->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Xsdt->OemId));
  CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
  CopyMem (&AcpiTableInstance->Xsdt->OemTableId, &CurrentData, sizeof (UINT64));
  AcpiTableInstance->Xsdt->OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
  AcpiTableInstance->Xsdt->CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
  AcpiTableInstance->Xsdt->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
  //
  // We always reserve first one for FADT
  //
  AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);

  ChecksumCommonTables (AcpiTableInstance);

  InstallAcpiTableFromHob (AcpiTableInstance);

  //
  // Completed successfully
  //
  return EFI_SUCCESS;
}
