diff mbox

[edk2,v4,1/2] MdeModulePkg: AcpiTableDxe: make 4 GB table allocation limit optional

Message ID 1456248932-28109-2-git-send-email-ard.biesheuvel@linaro.org
State Accepted
Commit f9bbb8d9c3f065faba9f266cf4e731fe2ca70c4d
Headers show

Commit Message

Ard Biesheuvel Feb. 23, 2016, 5:35 p.m. UTC
AARCH64 systems never require compatibility with legacy ACPI OSes, and
may not have any 32-bit addressable system RAM. To support ACPI on these
systems, we need to be able to relax the 4 GB allocation restriction.

So add a PCD PcdAcpiExposedTableVersions containing a bitmask describing
which ACPI versions are targeted, and wire it up it up to the memory
allocation calls in AcpiTableDxe/AcpiTableProtocol.c. I.e., if ACPI v1.0b
is not among the supported versions, the memory allocations are not limited
to 4 GB, and only table types that carry 64-bit addresses are emitted.

Note that this will inhibit the publishing of any tables that carry only
32-bit addresses, i.e., RSDPv1, RSDTv1 and RSDTv3.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Reviewed-by: "Yao, Jiewen" <jiewen.yao@intel.com>

---
 MdeModulePkg/MdeModulePkg.dec                                |  11 +
 MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c           |   3 +-
 MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf    |   3 +
 MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 441 ++++++++++++--------
 4 files changed, 274 insertions(+), 184 deletions(-)

-- 
2.5.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Comments

Ard Biesheuvel Feb. 24, 2016, 7:10 a.m. UTC | #1
On 23 February 2016 at 18:35, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> AARCH64 systems never require compatibility with legacy ACPI OSes, and

> may not have any 32-bit addressable system RAM. To support ACPI on these

> systems, we need to be able to relax the 4 GB allocation restriction.

>

> So add a PCD PcdAcpiExposedTableVersions containing a bitmask describing

> which ACPI versions are targeted, and wire it up it up to the memory

> allocation calls in AcpiTableDxe/AcpiTableProtocol.c. I.e., if ACPI v1.0b

> is not among the supported versions, the memory allocations are not limited

> to 4 GB, and only table types that carry 64-bit addresses are emitted.

>

> Note that this will inhibit the publishing of any tables that carry only

> 32-bit addresses, i.e., RSDPv1, RSDTv1 and RSDTv3.

>

> Contributed-under: TianoCore Contribution Agreement 1.0

> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> Reviewed-by: "Yao, Jiewen" <jiewen.yao@intel.com>

> ---

>  MdeModulePkg/MdeModulePkg.dec                                |  11 +

>  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c           |   3 +-

>  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf    |   3 +

>  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 441 ++++++++++++--------

>  4 files changed, 274 insertions(+), 184 deletions(-)

>

> diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec

> index 623d8ed68286..af7bcab3baf6 100644

> --- a/MdeModulePkg/MdeModulePkg.dec

> +++ b/MdeModulePkg/MdeModulePkg.dec

> @@ -4,6 +4,7 @@

>  # and libraries instances, which are used for those modules.

>  #

>  # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>

> +# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

>  # This program and the accompanying materials are licensed and made available under

>  # the terms and conditions of the BSD License that accompanies this distribution.

>  # The full text of the license may be found at

> @@ -1049,6 +1050,16 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]

>    # @Prompt Driver guid array of VFR drivers for VarCheckHiiBin generation.

>    gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray|{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0x3000103A

>

> +  ## Indicates which ACPI versions are targeted by the ACPI tables exposed to the OS

> +  #  These values are aligned with the definitions in MdePkg/Include/Protocol/AcpiSystemDescriptionTable.h

> +  #   BIT 1 - EFI_ACPI_TABLE_VERSION_1_0B.<BR>

> +  #   BIT 2 - EFI_ACPI_TABLE_VERSION_2_0.<BR>

> +  #   BIT 3 - EFI_ACPI_TABLE_VERSION_3_0.<BR>

> +  #   BIT 4 - EFI_ACPI_TABLE_VERSION_4_0.<BR>

> +  #   BIT 5 - EFI_ACPI_TABLE_VERSION_5_0.<BR>

> +  # @Prompt Exposed ACPI table versions.

> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x3E|UINT32|0x0001004c

> +

>  [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]

>    ## This PCD defines the Console output row. The default value is 25 according to UEFI spec.

>    #  This PCD could be set to 0 then console output would be at max column and max row.

> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

> index 57fdc7844e93..db693900758a 100644

> --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

> +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

> @@ -19,7 +19,7 @@

>

>  GLOBAL_REMOVE_IF_UNREFERENCED

>  EFI_ACPI_SDT_PROTOCOL  mAcpiSdtProtocolTemplate = {

> -  EFI_ACPI_TABLE_VERSION_NONE | EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,

> +  EFI_ACPI_TABLE_VERSION_NONE,

>    GetAcpiTable2,

>    RegisterNotify,

>    Open,

> @@ -1102,6 +1102,7 @@ SdtAcpiTableAcpiSdtConstructor (

>

>    InitializeListHead (&AcpiTableInstance->NotifyList);

>    CopyMem (&AcpiTableInstance->AcpiSdtProtocol, &mAcpiSdtProtocolTemplate, sizeof(mAcpiSdtProtocolTemplate));

> +  AcpiTableInstance->AcpiSdtProtocol.AcpiVersion = (EFI_ACPI_TABLE_VERSION)PcdGet32 (PcdAcpiExposedTableVersions);

>

>    //

>    // Register event for ExitPmAuth, so that we can uninstall ACPI SDT protocol after ExitPmAuth.

> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

> index e9cd728dbfb6..669df15c5c59 100644

> --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

> +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

> @@ -2,6 +2,7 @@

>  #  ACPI Table Protocol Driver

>  #

>  #  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

> +#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

>  #  This program and the accompanying materials are

>  #  licensed and made available under the terms and conditions of the BSD License

>  #  which accompanies this distribution.  The full text of the license may be found at

> @@ -60,6 +61,7 @@ [Guids]

>

>  [FeaturePcd]

>    gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol  ## CONSUMES

> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode  ## CONSUMES

>


This was left over from a previous version. I will remove it before applying.

>  [Pcd]

>    gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId            ## CONSUMES

> @@ -67,6 +69,7 @@ [Pcd]

>    gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision      ## CONSUMES

>    gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId        ## CONSUMES

>    gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision  ## CONSUMES

> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions    ## CONSUMES

>

>  [Protocols]

>    gEfiAcpiTableProtocolGuid                     ## PRODUCES

> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

> index c6abf1bf0c52..f069458b1cba 100644

> --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

> +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

> @@ -2,6 +2,7 @@

>    ACPI Table Protocol Implementation

>

>    Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>

> +  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

>    This program and the accompanying materials

>    are licensed and made available under the terms and conditions of the BSD License

>    which accompanies this distribution.  The full text of the license may be found at

> @@ -21,6 +22,12 @@

>  //

>  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.

> @@ -133,10 +140,11 @@ PublishTables (

>    if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {

>      CurrentRsdtEntry  = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt1 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));

>      *CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt1;

> -  }

> -  if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {

> +

>      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

> @@ -209,6 +217,7 @@ InstallAcpiTable (

>    EFI_ACPI_TABLE_INSTANCE   *AcpiTableInstance;

>    EFI_STATUS                Status;

>    VOID                      *AcpiTableBufferConst;

> +  EFI_ACPI_TABLE_VERSION    Version;

>

>    //

>    // Check for invalid input parameters

> @@ -218,6 +227,8 @@ InstallAcpiTable (

>      return EFI_INVALID_PARAMETER;

>    }

>

> +  Version = PcdGet32 (PcdAcpiExposedTableVersions);

> +

>    //

>    // Get the instance of the ACPI table protocol

>    //

> @@ -232,13 +243,13 @@ InstallAcpiTable (

>               AcpiTableInstance,

>               AcpiTableBufferConst,

>               TRUE,

> -             EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,

> +             Version,

>               TableKey

>               );

>    if (!EFI_ERROR (Status)) {

>      Status = PublishTables (

>                 AcpiTableInstance,

> -               EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0

> +               Version

>                 );

>    }

>    FreePool (AcpiTableBufferConst);

> @@ -250,7 +261,7 @@ InstallAcpiTable (

>      if (!EFI_ERROR (Status)) {

>        SdtNotifyAcpiList (

>          AcpiTableInstance,

> -        EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,

> +        Version,

>          *TableKey

>          );

>      }

> @@ -337,13 +348,16 @@ ReallocateAcpiTableBuffer (

>    //

>    // Create RSDT, XSDT structures and allocate buffers.

>    //

> -  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) +

> -              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT

> +  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);

> +  }

> +

>    //

>    // Allocate memory in the lower 32 bit of address range for

>    // compatibility with ACPI 1.0 OS.

> @@ -355,7 +369,7 @@ ReallocateAcpiTableBuffer (

>    //

>    PageAddress = 0xFFFFFFFF;

>    Status = gBS->AllocatePages (

> -                  AllocateMaxAddress,

> +                  mAcpiTableAllocType,

>                    EfiACPIReclaimMemory,

>                    EFI_SIZE_TO_PAGES (TotalSize),

>                    &PageAddress

> @@ -369,35 +383,45 @@ ReallocateAcpiTableBuffer (

>    ZeroMem (Pointer, TotalSize);

>

>    AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;

> -  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));

> +  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.

>    //

> -  AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;

> -  AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;

> +  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

>    //

> -  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)));

> +  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)));

>

>    //

>    // Calculate orignal ACPI table buffer size

>    //

> -  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) +

> -              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT

> +  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));

>

>    //

> @@ -504,7 +528,7 @@ AddTableToList (

>      // All other tables are ACPI reclaim memory, no alignment requirements.

>      //

>      Status = gBS->AllocatePages (

> -                    AllocateMaxAddress,

> +                    mAcpiTableAllocType,

>                      EfiACPIReclaimMemory,

>                      CurrentTableList->NumberOfPages,

>                      &CurrentTableList->PageAddress

> @@ -621,13 +645,18 @@ AddTableToList (

>            );

>          AcpiTableInstance->Fadt3->FirmwareCtrl = 0;

>        }

> -      AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;

> -      Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;

> -      CopyMem (

> -        &AcpiTableInstance->Fadt3->XDsdt,

> -        &Buffer64,

> -        sizeof (UINT64)

> -        );

> +      if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {

> +        AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;

> +        ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));

> +      } else {

> +        Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;

> +        CopyMem (

> +          &AcpiTableInstance->Fadt3->XDsdt,

> +          &Buffer64,

> +          sizeof (UINT64)

> +          );

> +        AcpiTableInstance->Fadt3->Dsdt = 0;

> +      }

>

>        //

>        // RSDP OEM information is updated to match the FADT OEM information

> @@ -638,21 +667,23 @@ AddTableToList (

>          6

>          );

>

> -      //

> -      // 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;

> -

> +      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.

>        //

> @@ -818,7 +849,9 @@ AddTableToList (

>        // If FADT already exists, update table pointers.

>        //

>        if (AcpiTableInstance->Fadt3 != NULL) {

> -        AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;

> +        if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {

> +          AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;

> +        }

>          Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;

>          CopyMem (

>            &AcpiTableInstance->Fadt3->XDsdt,

> @@ -909,65 +942,70 @@ AddTableToList (

>    // 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);

> -       }

> -       //

> -       // 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 *)

> +    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)

>           );

> +      }

>

> -       //

> -       // 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)

> -         );

> +      //

> +      // 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 the RSDT

> -       //

> -       *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;

> -

> -       //

> -       // Update RSDT length

> -       //

> -       AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);

> -

> -       //

> -       // 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)

> -         );

> +      if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {

> +        //

> +        // Add entry to the RSDT

> +        //

> +        *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;

> +

> +        //

> +        // Update RSDT length

> +        //

> +        AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);

> +      }

>

> -       //

> -       // Update length

> -       //

> -       AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + 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)

> +        );

>

> -       AcpiTableInstance->NumberOfTableEntries3++;

> +      //

> +      // Update length

> +      //

> +      AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);

> +

> +      AcpiTableInstance->NumberOfTableEntries3++;

>      }

>    }

>

> @@ -1046,7 +1084,7 @@ EFI_STATUS

>  RemoveTableFromRsdt (

>    IN OUT EFI_ACPI_TABLE_LIST              * Table,

>    IN OUT UINTN                            *NumberOfTableEntries,

> -  IN OUT EFI_ACPI_DESCRIPTION_HEADER      * Rsdt,

> +  IN OUT EFI_ACPI_DESCRIPTION_HEADER      * Rsdt OPTIONAL,

>    IN OUT EFI_ACPI_DESCRIPTION_HEADER      * Xsdt OPTIONAL

>    )

>  {

> @@ -1060,7 +1098,7 @@ RemoveTableFromRsdt (

>    //

>    ASSERT (Table);

>    ASSERT (NumberOfTableEntries);

> -  ASSERT (Rsdt);

> +  ASSERT (Rsdt || Xsdt);

>

>    //

>    // Find the table entry in the RSDT and XSDT

> @@ -1070,7 +1108,11 @@ RemoveTableFromRsdt (

>      // 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 *) Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));

> +    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

> @@ -1092,7 +1134,7 @@ RemoveTableFromRsdt (

>      //

>      // Check if we have found the corresponding entry in both RSDT and XSDT

>      //

> -    if (*CurrentRsdtEntry == (UINT32) (UINTN) Table->Table &&

> +    if ((CurrentRsdtEntry == NULL || *CurrentRsdtEntry == (UINT32) (UINTN) Table->Table) &&

>          ((Xsdt == NULL) || CurrentTablePointer64 == (UINT64) (UINTN) Table->Table)

>          ) {

>        //

> @@ -1100,8 +1142,10 @@ RemoveTableFromRsdt (

>        // We actually copy all + 1 to copy the initialized value of memory over

>        // the last entry.

>        //

> -      CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));

> -      Rsdt->Length = Rsdt->Length - sizeof (UINT32);

> +      if (Rsdt != NULL) {

> +        CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));

> +        Rsdt->Length = Rsdt->Length - sizeof (UINT32);

> +      }

>        if (Xsdt != NULL) {

>          CopyMem (CurrentXsdtEntry, ((UINT64 *) CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index) * sizeof (UINT64));

>          Xsdt->Length = Xsdt->Length - sizeof (UINT64);

> @@ -1117,12 +1161,14 @@ RemoveTableFromRsdt (

>    //

>    // Checksum the tables

>    //

> -  AcpiPlatformChecksum (

> -    Rsdt,

> -    Rsdt->Length,

> -    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,

> -    Checksum)

> -    );

> +  if (Rsdt != NULL) {

> +    AcpiPlatformChecksum (

> +      Rsdt,

> +      Rsdt->Length,

> +      OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,

> +      Checksum)

> +      );

> +  }

>

>    if (Xsdt != NULL) {

>      AcpiPlatformChecksum (

> @@ -1508,12 +1554,14 @@ ChecksumCommonTables (

>    //

>    // RSDP ACPI 1.0 checksum for 1.0 table.  This is only the first 20 bytes of the structure

>    //

> -  AcpiPlatformChecksum (

> -    AcpiTableInstance->Rsdp1,

> -    sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),

> -    OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,

> -    Checksum)

> -    );

> +  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

> @@ -1535,22 +1583,24 @@ ChecksumCommonTables (

>      ExtendedChecksum)

>      );

>

> -  //

> -  // RSDT checksums

> -  //

> -  AcpiPlatformChecksum (

> -    AcpiTableInstance->Rsdt1,

> -    AcpiTableInstance->Rsdt1->Length,

> -    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,

> -    Checksum)

> -    );

> +  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)

> -    );

> +    AcpiPlatformChecksum (

> +      AcpiTableInstance->Rsdt3,

> +      AcpiTableInstance->Rsdt3->Length,

> +      OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,

> +      Checksum)

> +      );

> +  }

>

>    //

>    // XSDT checksum

> @@ -1593,6 +1643,16 @@ AcpiTableAcpiTableConstructor (

>    //

>    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;

>

> @@ -1606,12 +1666,14 @@ AcpiTableAcpiTableConstructor (

>    //

>    // Create RSDP table

>    //

> -  RsdpTableSize = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +

> -                  sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);

> +  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);

> +  }

>

>    PageAddress = 0xFFFFFFFF;

>    Status = gBS->AllocatePages (

> -                  AllocateMaxAddress,

> +                  mAcpiTableAllocType,

>                    EfiACPIReclaimMemory,

>                    EFI_SIZE_TO_PAGES (RsdpTableSize),

>                    &PageAddress

> @@ -1625,19 +1687,24 @@ AcpiTableAcpiTableConstructor (

>    ZeroMem (Pointer, RsdpTableSize);

>

>    AcpiTableInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;

> -  Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_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 1.0 RSDT

> -              mEfiAcpiMaxNumTables * sizeof (UINT32) +

> -              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 RSDT

> -              mEfiAcpiMaxNumTables * sizeof (UINT32) +

> -              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT

> +  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);

> +  }

> +

>    //

>    // Allocate memory in the lower 32 bit of address range for

>    // compatibility with ACPI 1.0 OS.

> @@ -1649,7 +1716,7 @@ AcpiTableAcpiTableConstructor (

>    //

>    PageAddress = 0xFFFFFFFF;

>    Status = gBS->AllocatePages (

> -                  AllocateMaxAddress,

> +                  mAcpiTableAllocType,

>                    EfiACPIReclaimMemory,

>                    EFI_SIZE_TO_PAGES (TotalSize),

>                    &PageAddress

> @@ -1664,66 +1731,74 @@ AcpiTableAcpiTableConstructor (

>    ZeroMem (Pointer, TotalSize);

>

>    AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;

> -  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));

> +  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

>    //

> -  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;

> +  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->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;

>    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);

>

> -  //

> -  // 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

> -  //

> +  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;

> -  AcpiTableInstance->Rsdt3->Length          = AcpiTableInstance->Rsdt3->Length + sizeof(UINT32);

>

>    //

>    // Initialize Xsdt

> --

> 2.5.0

>

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel Feb. 24, 2016, 8:21 a.m. UTC | #2
On 24 February 2016 at 08:42, Zeng, Star <star.zeng@intel.com> wrote:
> On 2016/2/24 15:10, Ard Biesheuvel wrote:

>>

>> On 23 February 2016 at 18:35, Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> wrote:

>>>

>>> AARCH64 systems never require compatibility with legacy ACPI OSes, and

>>> may not have any 32-bit addressable system RAM. To support ACPI on these

>>> systems, we need to be able to relax the 4 GB allocation restriction.

>>>

>>> So add a PCD PcdAcpiExposedTableVersions containing a bitmask describing

>>> which ACPI versions are targeted, and wire it up it up to the memory

>>> allocation calls in AcpiTableDxe/AcpiTableProtocol.c. I.e., if ACPI v1.0b

>>> is not among the supported versions, the memory allocations are not

>>> limited

>>> to 4 GB, and only table types that carry 64-bit addresses are emitted.

>>>

>>> Note that this will inhibit the publishing of any tables that carry only

>>> 32-bit addresses, i.e., RSDPv1, RSDTv1 and RSDTv3.

>>>

>>> Contributed-under: TianoCore Contribution Agreement 1.0

>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>>> Reviewed-by: "Yao, Jiewen" <jiewen.yao@intel.com>

>>> ---

>>>   MdeModulePkg/MdeModulePkg.dec                                |  11 +

>>>   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c           |   3 +-

>>>   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf    |   3 +

>>>   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 441

>>> ++++++++++++--------

>>>   4 files changed, 274 insertions(+), 184 deletions(-)

>>>

>>> diff --git a/MdeModulePkg/MdeModulePkg.dec

>>> b/MdeModulePkg/MdeModulePkg.dec

>>> index 623d8ed68286..af7bcab3baf6 100644

>>> --- a/MdeModulePkg/MdeModulePkg.dec

>>> +++ b/MdeModulePkg/MdeModulePkg.dec

>>> @@ -4,6 +4,7 @@

>>>   # and libraries instances, which are used for those modules.

>>>   #

>>>   # Copyright (c) 2007 - 2016, Intel Corporation. All rights

>>> reserved.<BR>

>>> +# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

>>>   # This program and the accompanying materials are licensed and made

>>> available under

>>>   # the terms and conditions of the BSD License that accompanies this

>>> distribution.

>>>   # The full text of the license may be found at

>>> @@ -1049,6 +1050,16 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]

>>>     # @Prompt Driver guid array of VFR drivers for VarCheckHiiBin

>>> generation.

>>>     gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray|{ 0x00,

>>> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

>>> 0x00, 0x00, 0x00 }|VOID*|0x3000103A

>>>

>>> +  ## Indicates which ACPI versions are targeted by the ACPI tables

>>> exposed to the OS

>>> +  #  These values are aligned with the definitions in

>>> MdePkg/Include/Protocol/AcpiSystemDescriptionTable.h

>>> +  #   BIT 1 - EFI_ACPI_TABLE_VERSION_1_0B.<BR>

>>> +  #   BIT 2 - EFI_ACPI_TABLE_VERSION_2_0.<BR>

>>> +  #   BIT 3 - EFI_ACPI_TABLE_VERSION_3_0.<BR>

>>> +  #   BIT 4 - EFI_ACPI_TABLE_VERSION_4_0.<BR>

>>> +  #   BIT 5 - EFI_ACPI_TABLE_VERSION_5_0.<BR>

>>> +  # @Prompt Exposed ACPI table versions.

>>> +

>>> gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x3E|UINT32|0x0001004c

>>> +

>>>   [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]

>>>     ## This PCD defines the Console output row. The default value is 25

>>> according to UEFI spec.

>>>     #  This PCD could be set to 0 then console output would be at max

>>> column and max row.

>>> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

>>> b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

>>> index 57fdc7844e93..db693900758a 100644

>>> --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

>>> +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

>>> @@ -19,7 +19,7 @@

>>>

>>>   GLOBAL_REMOVE_IF_UNREFERENCED

>>>   EFI_ACPI_SDT_PROTOCOL  mAcpiSdtProtocolTemplate = {

>>> -  EFI_ACPI_TABLE_VERSION_NONE | EFI_ACPI_TABLE_VERSION_1_0B |

>>> ACPI_TABLE_VERSION_GTE_2_0,

>>> +  EFI_ACPI_TABLE_VERSION_NONE,

>>>     GetAcpiTable2,

>>>     RegisterNotify,

>>>     Open,

>>> @@ -1102,6 +1102,7 @@ SdtAcpiTableAcpiSdtConstructor (

>>>

>>>     InitializeListHead (&AcpiTableInstance->NotifyList);

>>>     CopyMem (&AcpiTableInstance->AcpiSdtProtocol,

>>> &mAcpiSdtProtocolTemplate, sizeof(mAcpiSdtProtocolTemplate));

>>> +  AcpiTableInstance->AcpiSdtProtocol.AcpiVersion =

>>> (EFI_ACPI_TABLE_VERSION)PcdGet32 (PcdAcpiExposedTableVersions);

>>>

>>>     //

>>>     // Register event for ExitPmAuth, so that we can uninstall ACPI SDT

>>> protocol after ExitPmAuth.

>>> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

>>> b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

>>> index e9cd728dbfb6..669df15c5c59 100644

>>> --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

>>> +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

>>> @@ -2,6 +2,7 @@

>>>   #  ACPI Table Protocol Driver

>>>   #

>>>   #  Copyright (c) 2006 - 2014, Intel Corporation. All rights

>>> reserved.<BR>

>>> +#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

>>>   #  This program and the accompanying materials are

>>>   #  licensed and made available under the terms and conditions of the

>>> BSD License

>>>   #  which accompanies this distribution.  The full text of the license

>>> may be found at

>>> @@ -60,6 +61,7 @@ [Guids]

>>>

>>>   [FeaturePcd]

>>>     gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol  ## CONSUMES

>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode  ## CONSUMES

>>>

>>

>> This was left over from a previous version. I will remove it before

>> applying.

>>

>>>   [Pcd]

>>>     gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId            ##

>>> CONSUMES

>>> @@ -67,6 +69,7 @@ [Pcd]

>>>     gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision      ##

>>> CONSUMES

>>>     gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId        ##

>>> CONSUMES

>>>     gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision  ##

>>> CONSUMES

>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions    ##

>>> CONSUMES

>>>

>>>   [Protocols]

>>>     gEfiAcpiTableProtocolGuid                     ## PRODUCES

>>> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

>>> b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

>>> index c6abf1bf0c52..f069458b1cba 100644

>>> --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

>>> +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

>>> @@ -2,6 +2,7 @@

>>>     ACPI Table Protocol Implementation

>>>

>>>     Copyright (c) 2006 - 2015, Intel Corporation. All rights

>>> reserved.<BR>

>>> +  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

>>>     This program and the accompanying materials

>>>     are licensed and made available under the terms and conditions of the

>>> BSD License

>>>     which accompanies this distribution.  The full text of the license

>>> may be found at

>>> @@ -21,6 +22,12 @@

>>>   //

>>>   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.

>>> @@ -133,10 +140,11 @@ PublishTables (

>>>     if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {

>>>       CurrentRsdtEntry  = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt1

>>> + sizeof (EFI_ACPI_DESCRIPTION_HEADER));

>>>       *CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt1;

>>> -  }

>>> -  if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {

>>> +

>>>       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

>>> @@ -209,6 +217,7 @@ InstallAcpiTable (

>>>     EFI_ACPI_TABLE_INSTANCE   *AcpiTableInstance;

>>>     EFI_STATUS                Status;

>>>     VOID                      *AcpiTableBufferConst;

>>> +  EFI_ACPI_TABLE_VERSION    Version;

>>>

>>>     //

>>>     // Check for invalid input parameters

>>> @@ -218,6 +227,8 @@ InstallAcpiTable (

>>>       return EFI_INVALID_PARAMETER;

>>>     }

>>>

>>> +  Version = PcdGet32 (PcdAcpiExposedTableVersions);

>>> +

>>>     //

>>>     // Get the instance of the ACPI table protocol

>>>     //

>>> @@ -232,13 +243,13 @@ InstallAcpiTable (

>>>                AcpiTableInstance,

>>>                AcpiTableBufferConst,

>>>                TRUE,

>>> -             EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,

>>> +             Version,

>>>                TableKey

>>>                );

>>>     if (!EFI_ERROR (Status)) {

>>>       Status = PublishTables (

>>>                  AcpiTableInstance,

>>> -               EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0

>>> +               Version

>>>                  );

>>>     }

>>>     FreePool (AcpiTableBufferConst);

>>> @@ -250,7 +261,7 @@ InstallAcpiTable (

>>>       if (!EFI_ERROR (Status)) {

>>>         SdtNotifyAcpiList (

>>>           AcpiTableInstance,

>>> -        EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,

>>> +        Version,

>>>           *TableKey

>>>           );

>>>       }

>>> @@ -337,13 +348,16 @@ ReallocateAcpiTableBuffer (

>>>     //

>>>     // Create RSDT, XSDT structures and allocate buffers.

>>>     //

>>> -  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) +

>>> -              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI

>>> 2.0/3.0 XSDT

>>> +  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);

>>> +  }

>>> +

>>>     //

>>>     // Allocate memory in the lower 32 bit of address range for

>>>     // compatibility with ACPI 1.0 OS.

>>> @@ -355,7 +369,7 @@ ReallocateAcpiTableBuffer (

>>>     //

>>>     PageAddress = 0xFFFFFFFF;

>>>     Status = gBS->AllocatePages (

>>> -                  AllocateMaxAddress,

>>> +                  mAcpiTableAllocType,

>>>                     EfiACPIReclaimMemory,

>>>                     EFI_SIZE_TO_PAGES (TotalSize),

>>>                     &PageAddress

>>> @@ -369,35 +383,45 @@ ReallocateAcpiTableBuffer (

>>>     ZeroMem (Pointer, TotalSize);

>>>

>>>     AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;

>>> -  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));

>>> +  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.

>>>     //

>>> -  AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN)

>>> AcpiTableInstance->Rsdt1;

>>> -  AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN)

>>> AcpiTableInstance->Rsdt3;

>>> +  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

>>>     //

>>> -  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)));

>>> +  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)));

>>>

>>>     //

>>>     // Calculate orignal ACPI table buffer size

>>>     //

>>> -  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) +

>>> -              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI

>>> 2.0/3.0 XSDT

>>> +  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));

>>>

>>>     //

>>> @@ -504,7 +528,7 @@ AddTableToList (

>>>       // All other tables are ACPI reclaim memory, no alignment

>>> requirements.

>>>       //

>>>       Status = gBS->AllocatePages (

>>> -                    AllocateMaxAddress,

>>> +                    mAcpiTableAllocType,

>>>                       EfiACPIReclaimMemory,

>>>                       CurrentTableList->NumberOfPages,

>>>                       &CurrentTableList->PageAddress

>>> @@ -621,13 +645,18 @@ AddTableToList (

>>>             );

>>>           AcpiTableInstance->Fadt3->FirmwareCtrl = 0;

>>>         }

>>> -      AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN)

>>> AcpiTableInstance->Dsdt3;

>>> -      Buffer64                          = (UINT64) (UINTN)

>>> AcpiTableInstance->Dsdt3;

>>> -      CopyMem (

>>> -        &AcpiTableInstance->Fadt3->XDsdt,

>>> -        &Buffer64,

>>> -        sizeof (UINT64)

>>> -        );

>>> +      if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {

>>> +        AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN)

>>> AcpiTableInstance->Dsdt3;

>>> +        ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));

>>> +      } else {

>>> +        Buffer64                          = (UINT64) (UINTN)

>>> AcpiTableInstance->Dsdt3;

>>> +        CopyMem (

>>> +          &AcpiTableInstance->Fadt3->XDsdt,

>>> +          &Buffer64,

>>> +          sizeof (UINT64)

>>> +          );

>>> +        AcpiTableInstance->Fadt3->Dsdt = 0;

>>> +      }

>>>

>>>         //

>>>         // RSDP OEM information is updated to match the FADT OEM

>>> information

>>

>> Path: news.gmane.org!not-for-mail

>> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> Newsgroups: gmane.comp.bios.edk2.devel

>> Subject: Re: [edk2] [PATCH v4 1/2] MdeModulePkg: AcpiTableDxe: make 4 GB

>>   table allocation limit optional

>> Date: Wed, 24 Feb 2016 08:10:38 +0100

>> Lines: 812

>> Approved: news@gmane.org

>> Message-ID:

>> <CAKv+Gu9-wj_P+1fErh-OOCHXTOOiDyuog-x3XDboyS3bgWAixQ@mail.gmail.com>

>> References: <1456248932-28109-1-git-send-email-ard.biesheuvel@linaro.org>

>>   <1456248932-28109-2-git-send-email-ard.biesheuvel@linaro.org>

>> NNTP-Posting-Host: plane.gmane.org

>> Mime-Version: 1.0

>> Content-Type: text/plain; charset="us-ascii"

>> Content-Transfer-Encoding: 7bit

>> X-Trace: ger.gmane.org 1456297851 22905 80.91.229.3 (24 Feb 2016 07:10:51

>> GMT)

>> X-Complaints-To: usenet@ger.gmane.org

>> NNTP-Posting-Date: Wed, 24 Feb 2016 07:10:51 +0000 (UTC)

>> Cc: Leif Lindholm <leif.lindholm@linaro.org>,

>>   Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> To: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>, "Tian,

>>   Feng" <feng.tian@intel.com>,

>>   "Zeng, Star" <star.zeng@intel.com>, "Fan, Jeff" <jeff.fan@intel.com>,

>>   "Yao, Jiewen" <jiewen.yao@intel.com>, Laszlo Ersek <lersek@redhat.com>,

>>   "Gao, Liming" <liming.gao@intel.com>

>> Original-X-From: edk2-devel-bounces@lists.01.org Wed Feb 24 08:10:44 2016

>> Return-path: <edk2-devel-bounces@lists.01.org>

>> Envelope-to: gcbed-edk2@m.gmane.org

>> Original-Received: from ml01.01.org ([198.145.21.10])

>>         by plane.gmane.org with esmtp (Exim 4.69)

>>         (envelope-from <edk2-devel-bounces@lists.01.org>)

>>         id 1aYTat-0008Ms-LO

>>         for gcbed-edk2@m.gmane.org; Wed, 24 Feb 2016 08:10:44 +0100

>> Original-Received: from [127.0.0.1] (localhost [IPv6:::1])

>>         by ml01.01.org (Postfix) with ESMTP id 070FB1A1F41;

>>         Tue, 23 Feb 2016 23:10:44 -0800 (PST)

>> X-Original-To: edk2-devel@lists.01.org

>> Delivered-To: edk2-devel@lists.01.org

>> Original-Received: from mail-io0-x229.google.com (mail-io0-x229.google.com

>>   [IPv6:2607:f8b0:4001:c06::229])

>>   (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))

>>   (No client certificate requested)

>>   by ml01.01.org (Postfix) with ESMTPS id A09311A1EED

>>   for <edk2-devel@lists.01.org>; Tue, 23 Feb 2016 23:10:42 -0800 (PST)

>> Original-Received: by mail-io0-x229.google.com with SMTP id

>> z135so21946371iof.0

>>   for <edk2-devel@lists.01.org>; Tue, 23 Feb 2016 23:10:39 -0800 (PST)

>> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org;

>> s=google;

>>   h=mime-version:in-reply-to:references:date:message-id:subject:from:to

>>   :cc:content-type;

>>   bh=NOB2RVwm5baYJMUvz1ixy7ZpswUxueKxCdVmacix/sg=;

>>   b=kVyLMvCblOdKXJFvyJNK4JDAOjNOJKBQsngV7d3Z4NV/TwWT1PQ97AMtVMoZ01qzKY

>>   3KdPEzqx7LA5YSN6+GBea1lq1k7luqUv1A6PZ6+Y1s53Cv1aE/BTOyaSwxqlRLENehsC

>>   eKyMxHLM2Fb/lvOZaLtm/QA/Qo+1CKjg4dfvA=

>> X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;

>>   d=1e100.net; s=20130820;

>>   h=x-gm-message-state:mime-version:in-reply-to:references:date

>>   :message-id:subject:from:to:cc:content-type;

>>   bh=NOB2RVwm5baYJMUvz1ixy7ZpswUxueKxCdVmacix/sg=;

>>   b=VYGTt4Ug+mS3P6klMR6nBA2NI+gTJzEtjLlKIIPRHBAmyn0nOiV6VftmD3LO4fz5en

>>   jfSL2wM2XXUwTEXRrEKk19NbS2vPsIUnAYlrv1yEGRgmsna0lpl9liKEEFcRCzsjwCtw

>>   4gjmi/l3Pk35xm76Imrg+axbxnqESXGBPma7oxFCbtn2OhxbANIeMyBxYWe4tOwXZjKn

>>   mEedZhh1eSJuuScsDs3Wq9bC8tT7LnrDirDLJYIJV6+SboadfMelJYYg5sLHviIYPcF1

>>   pBMIgK5PKjfz9/X07qBM6UiCIKbxe38q1asskTvb30oiVYbiOS1dW44RB+kXELnZHtDZ

>>   0rAw==

>> X-Gm-Message-State:

>> AG10YOQK5I9BlSKUTRYaYD/oh2oVzivxPZmqrDYSfFD9OVqaALLDVrQEGBva9SyERvIQp14esS+74S0A0XhFPA28

>> X-Received: by 10.107.135.20 with SMTP id

>> j20mr43275482iod.56.1456297838725;

>>   Tue, 23 Feb 2016 23:10:38 -0800 (PST)

>> Original-Received: by 10.36.29.6 with HTTP; Tue, 23 Feb 2016 23:10:38

>> -0800 (PST)

>> In-Reply-To: <1456248932-28109-2-git-send-email-ard.biesheuvel@linaro.org>

>> X-BeenThere: edk2-devel@lists.01.org

>> X-Mailman-Version: 2.1.17

>> Precedence: list

>> List-Id: EDK II Development  <edk2-devel.lists.01.org>

>> List-Unsubscribe: <https://lists.01.org/mailman/options/edk2-devel>,

>>   <mailto:edk2-devel-request@lists.01.org?subject=unsubscribe>

>> List-Post: <mailto:edk2-devel@lists.01.org>

>> List-Help: <mailto:edk2-devel-request@lists.01.org?subject=help>

>> List-Subscribe: <https://lists.01.org/mailman/listinfo/edk2-devel>,

>>   <mailto:edk2-devel-request@lists.01.org?subject=subscribe>

>> Errors-To: edk2-devel-bounces@lists.01.org

>> Original-Sender: "edk2-devel" <edk2-devel-bounces@lists.01.org>

>> Xref: news.gmane.org gmane.comp.bios.edk2.devel:8081

>> Archived-At: <http://permalink.gmane.org/gmane.comp.bios.edk2.devel/8081>

>>

>>

>> On 23 February 2016 at 18:35, Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> wrote:

>>>

>>> AARCH64 systems never require compatibility with legacy ACPI OSes, and

>>> may not have any 32-bit addressable system RAM. To support ACPI on these

>>> systems, we need to be able to relax the 4 GB allocation restriction.

>>>

>>> So add a PCD PcdAcpiExposedTableVersions containing a bitmask describing

>>> which ACPI versions are targeted, and wire it up it up to the memory

>>> allocation calls in AcpiTableDxe/AcpiTableProtocol.c. I.e., if ACPI v1.0b

>>> is not among the supported versions, the memory allocations are not

>>> limited

>>> to 4 GB, and only table types that carry 64-bit addresses are emitted.

>>>

>>> Note that this will inhibit the publishing of any tables that carry only

>>> 32-bit addresses, i.e., RSDPv1, RSDTv1 and RSDTv3.

>>>

>>> Contributed-under: TianoCore Contribution Agreement 1.0

>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>>> Reviewed-by: "Yao, Jiewen" <jiewen.yao@intel.com>

>>> ---

>>>   MdeModulePkg/MdeModulePkg.dec                                |  11 +

>>>   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c           |   3 +-

>>>   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf    |   3 +

>>>   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 441

>>> ++++++++++++--------

>>>   4 files changed, 274 insertions(+), 184 deletions(-)

>>>

>>> diff --git a/MdeModulePkg/MdeModulePkg.dec

>>> b/MdeModulePkg/MdeModulePkg.dec

>>> index 623d8ed68286..af7bcab3baf6 100644

>>> --- a/MdeModulePkg/MdeModulePkg.dec

>>> +++ b/MdeModulePkg/MdeModulePkg.dec

>>> @@ -4,6 +4,7 @@

>>>   # and libraries instances, which are used for those modules.

>>>   #

>>>   # Copyright (c) 2007 - 2016, Intel Corporation. All rights

>>> reserved.<BR>

>>> +# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

>>>   # This program and the accompanying materials are licensed and made

>>> available under

>>>   # the terms and conditions of the BSD License that accompanies this

>>> distribution.

>>>   # The full text of the license may be found at

>>> @@ -1049,6 +1050,16 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]

>>>     # @Prompt Driver guid array of VFR drivers for VarCheckHiiBin

>>> generation.

>>>     gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray|{ 0x00,

>>> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

>>> 0x00, 0x00, 0x00 }|VOID*|0x3000103A

>>>

>>> +  ## Indicates which ACPI versions are targeted by the ACPI tables

>>> exposed to the OS

>>> +  #  These values are aligned with the definitions in

>>> MdePkg/Include/Protocol/AcpiSystemDescriptionTable.h

>>> +  #   BIT 1 - EFI_ACPI_TABLE_VERSION_1_0B.<BR>

>>> +  #   BIT 2 - EFI_ACPI_TABLE_VERSION_2_0.<BR>

>>> +  #   BIT 3 - EFI_ACPI_TABLE_VERSION_3_0.<BR>

>>> +  #   BIT 4 - EFI_ACPI_TABLE_VERSION_4_0.<BR>

>>> +  #   BIT 5 - EFI_ACPI_TABLE_VERSION_5_0.<BR>

>>> +  # @Prompt Exposed ACPI table versions.

>>> +

>>> gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x3E|UINT32|0x0001004c

>>> +

>>>   [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]

>>>     ## This PCD defines the Console output row. The default value is 25

>>> according to UEFI spec.

>>>     #  This PCD could be set to 0 then console output would be at max

>>> column and max row.

>>> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

>>> b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

>>> index 57fdc7844e93..db693900758a 100644

>>> --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

>>> +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c

>>> @@ -19,7 +19,7 @@

>>>

>>>   GLOBAL_REMOVE_IF_UNREFERENCED

>>>   EFI_ACPI_SDT_PROTOCOL  mAcpiSdtProtocolTemplate = {

>>> -  EFI_ACPI_TABLE_VERSION_NONE | EFI_ACPI_TABLE_VERSION_1_0B |

>>> ACPI_TABLE_VERSION_GTE_2_0,

>>> +  EFI_ACPI_TABLE_VERSION_NONE,

>>>     GetAcpiTable2,

>>>     RegisterNotify,

>>>     Open,

>>> @@ -1102,6 +1102,7 @@ SdtAcpiTableAcpiSdtConstructor (

>>>

>>>     InitializeListHead (&AcpiTableInstance->NotifyList);

>>>     CopyMem (&AcpiTableInstance->AcpiSdtProtocol,

>>> &mAcpiSdtProtocolTemplate, sizeof(mAcpiSdtProtocolTemplate));

>>> +  AcpiTableInstance->AcpiSdtProtocol.AcpiVersion =

>>> (EFI_ACPI_TABLE_VERSION)PcdGet32 (PcdAcpiExposedTableVersions);

>>>

>>>     //

>>>     // Register event for ExitPmAuth, so that we can uninstall ACPI SDT

>>> protocol after ExitPmAuth.

>>> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

>>> b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

>>> index e9cd728dbfb6..669df15c5c59 100644

>>> --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

>>> +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf

>>> @@ -2,6 +2,7 @@

>>>   #  ACPI Table Protocol Driver

>>>   #

>>>   #  Copyright (c) 2006 - 2014, Intel Corporation. All rights

>>> reserved.<BR>

>>> +#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

>>>   #  This program and the accompanying materials are

>>>   #  licensed and made available under the terms and conditions of the

>>> BSD License

>>>   #  which accompanies this distribution.  The full text of the license

>>> may be found at

>>> @@ -60,6 +61,7 @@ [Guids]

>>>

>>>   [FeaturePcd]

>>>     gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol  ## CONSUMES

>>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode  ## CONSUMES

>>>

>>

>> This was left over from a previous version. I will remove it before

>> applying.\

>

>

> With this remove, Reviewed-by: Star Zeng <star.zeng@intel.com>

>


Thanks everyone. Series committed as

f9bbb8d9c3f0 MdeModulePkg: AcpiTableDxe: make 4 GB table allocation
limit optional
e0692789058e ArmVirtPkg/ArmVirtQemu: limit ACPI support to v5.0 and higher

Regards,
Ard.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel Feb. 25, 2016, 4:16 p.m. UTC | #3
On 25 February 2016 at 17:07, David Woodhouse <dwmw2@infradead.org> wrote:
> On Tue, 2016-02-23 at 18:35 +0100, Ard Biesheuvel wrote:

>> AARCH64 systems never require compatibility with legacy ACPI OSes, and

>> may not have any 32-bit addressable system RAM. To support ACPI on these

>> systems, we need to be able to relax the 4 GB allocation restriction.

>>

>> So add a PCD PcdAcpiExposedTableVersions containing a bitmask describing

>> which ACPI versions are targeted, and wire it up it up to the memory

>> allocation calls in AcpiTableDxe/AcpiTableProtocol.c. I.e., if ACPI v1.0b

>> is not among the supported versions, the memory allocations are not limited

>> to 4 GB, and only table types that carry 64-bit addresses are emitted.

>>

>> Note that this will inhibit the publishing of any tables that carry only

>> 32-bit addresses, i.e., RSDPv1, RSDTv1 and RSDTv3.

>

> This appears to break the build with VS2008 for me:

>

> e:\edk2\mdemodulepkg\universal\acpi\acpitabledxe\acpitableprotocol.c(98

> 4) : warning C4701: potentially uninitialized local variable

> 'CurrentRsdtEntry' used

> LINK : fatal error LNK1257: code generation failed

>


Apologies. I don't have access to that toolchain

>

> You misspelled "4 GiB" in the commit comment too, btw.

>


I think the context of 32-bit addressable RAM and memory allocation
kind of makes it obvious that this is 2base not 10base.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Laszlo Ersek Feb. 25, 2016, 5:53 p.m. UTC | #4
On 02/25/16 18:04, David Woodhouse wrote:
> On Thu, 2016-02-25 at 17:16 +0100, Ard Biesheuvel wrote:
>>
>>> This appears to break the build with VS2008 for me:
>>>
>>> e:\edk2\mdemodulepkg\universal\acpi\acpitabledxe\acpitableprotocol.c(98
>>> 4) : warning C4701: potentially uninitialized local variable
>>> 'CurrentRsdtEntry' used
>>> LINK : fatal error LNK1257: code generation failed
>>>
>>
>> Apologies. I don't have access to that toolchain
> 
> I wish I didn't have to. It would be useful to have CI running
> automatically with the supported toolchains and targets — ideally on
> all pull requests, but at *least* on what's committed to HEAD.
> 
> Thanks for the quick patch. I will attempt to get it into the Windows
> VM and apply it there.
> 
>>> You misspelled "4 GiB" in the commit comment too, btw.
>>
>> I think the context of 32-bit addressable RAM and memory allocation
>> kind of makes it obvious that this is 2base not 10base.
> 
> That's a very strange response. The same "it's obvious in context"
> statement could be made of fairly much *any* typo or spelling mistake
> you could make. That isn't really the point though; we strive to avoid
> such errors anyway.

To fuel the flame :), "4 GB" is not a typo, or an error, but the only
way to express four gigabytes (4 * 2^30 bytes). If we say "gibibyte", we
retro-actively give in to marketing folks, who invented the marketing
gigabyte, for hard disk. It is *their* error, not ours. There is *zero*
use for the marketing gigabyte (except for deceiving hard disk buyers,
of course), so "GB" uniquely resolves to 2^30 bytes.

(In my understanding, the UK near-universally uses SI units, so my next
comment is absolutely not directed at you personally:) in general I find
it pretty funny that in a world where most native English speakers
refuse to abandon imperial units for weight (stones and pounds?), volume
(ounces and gallons?), distance (miles, yards, feet, inches?), area
(acre, square feet?), temperature (Fahrenheit?), and so on -- i.e., they
refuse to adopt SI units --, I as a universal SI-user am forced to be
politically correct, and call the *real* gigabyte "gibibyte" just to
accommodate the marketing gigabyte.

No can do.

Laszlo
diff mbox

Patch

diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 623d8ed68286..af7bcab3baf6 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -4,6 +4,7 @@ 
 # and libraries instances, which are used for those modules.
 #
 # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
 # This program and the accompanying materials are licensed and made available under
 # the terms and conditions of the BSD License that accompanies this distribution.
 # The full text of the license may be found at
@@ -1049,6 +1050,16 @@  [PcdsFixedAtBuild, PcdsPatchableInModule]
   # @Prompt Driver guid array of VFR drivers for VarCheckHiiBin generation.
   gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray|{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0x3000103A
 
+  ## Indicates which ACPI versions are targeted by the ACPI tables exposed to the OS
+  #  These values are aligned with the definitions in MdePkg/Include/Protocol/AcpiSystemDescriptionTable.h
+  #   BIT 1 - EFI_ACPI_TABLE_VERSION_1_0B.<BR>
+  #   BIT 2 - EFI_ACPI_TABLE_VERSION_2_0.<BR>
+  #   BIT 3 - EFI_ACPI_TABLE_VERSION_3_0.<BR>
+  #   BIT 4 - EFI_ACPI_TABLE_VERSION_4_0.<BR>
+  #   BIT 5 - EFI_ACPI_TABLE_VERSION_5_0.<BR>
+  # @Prompt Exposed ACPI table versions.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x3E|UINT32|0x0001004c
+
 [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
   ## This PCD defines the Console output row. The default value is 25 according to UEFI spec.
   #  This PCD could be set to 0 then console output would be at max column and max row.
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c
index 57fdc7844e93..db693900758a 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c
@@ -19,7 +19,7 @@ 
 
 GLOBAL_REMOVE_IF_UNREFERENCED
 EFI_ACPI_SDT_PROTOCOL  mAcpiSdtProtocolTemplate = {
-  EFI_ACPI_TABLE_VERSION_NONE | EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,
+  EFI_ACPI_TABLE_VERSION_NONE,
   GetAcpiTable2,
   RegisterNotify,
   Open,
@@ -1102,6 +1102,7 @@  SdtAcpiTableAcpiSdtConstructor (
 
   InitializeListHead (&AcpiTableInstance->NotifyList);
   CopyMem (&AcpiTableInstance->AcpiSdtProtocol, &mAcpiSdtProtocolTemplate, sizeof(mAcpiSdtProtocolTemplate));
+  AcpiTableInstance->AcpiSdtProtocol.AcpiVersion = (EFI_ACPI_TABLE_VERSION)PcdGet32 (PcdAcpiExposedTableVersions);
 
   //
   // Register event for ExitPmAuth, so that we can uninstall ACPI SDT protocol after ExitPmAuth.
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
index e9cd728dbfb6..669df15c5c59 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
@@ -2,6 +2,7 @@ 
 #  ACPI Table Protocol Driver
 #
 #  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
 #  This program and the accompanying materials are
 #  licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
@@ -60,6 +61,7 @@  [Guids]
 
 [FeaturePcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode  ## CONSUMES
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId            ## CONSUMES
@@ -67,6 +69,7 @@  [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision      ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId        ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions    ## CONSUMES
 
 [Protocols]
   gEfiAcpiTableProtocolGuid                     ## PRODUCES
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
index c6abf1bf0c52..f069458b1cba 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
@@ -2,6 +2,7 @@ 
   ACPI Table Protocol Implementation
 
   Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -21,6 +22,12 @@ 
 //
 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.
@@ -133,10 +140,11 @@  PublishTables (
   if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
     CurrentRsdtEntry  = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt1 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
     *CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt1;
-  }
-  if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
+
     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
@@ -209,6 +217,7 @@  InstallAcpiTable (
   EFI_ACPI_TABLE_INSTANCE   *AcpiTableInstance;
   EFI_STATUS                Status;
   VOID                      *AcpiTableBufferConst;
+  EFI_ACPI_TABLE_VERSION    Version;
 
   //
   // Check for invalid input parameters
@@ -218,6 +227,8 @@  InstallAcpiTable (
     return EFI_INVALID_PARAMETER;
   }
 
+  Version = PcdGet32 (PcdAcpiExposedTableVersions);
+
   //
   // Get the instance of the ACPI table protocol
   //
@@ -232,13 +243,13 @@  InstallAcpiTable (
              AcpiTableInstance,
              AcpiTableBufferConst,
              TRUE,
-             EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,
+             Version,
              TableKey
              );
   if (!EFI_ERROR (Status)) {
     Status = PublishTables (
                AcpiTableInstance,
-               EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0
+               Version
                );
   }
   FreePool (AcpiTableBufferConst);
@@ -250,7 +261,7 @@  InstallAcpiTable (
     if (!EFI_ERROR (Status)) {
       SdtNotifyAcpiList (
         AcpiTableInstance,
-        EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,
+        Version,
         *TableKey
         );
     }
@@ -337,13 +348,16 @@  ReallocateAcpiTableBuffer (
   //
   // Create RSDT, XSDT structures and allocate buffers.
   //
-  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) +
-              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT
+  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);
+  }
+
   //
   // Allocate memory in the lower 32 bit of address range for
   // compatibility with ACPI 1.0 OS.
@@ -355,7 +369,7 @@  ReallocateAcpiTableBuffer (
   //
   PageAddress = 0xFFFFFFFF;
   Status = gBS->AllocatePages (
-                  AllocateMaxAddress,
+                  mAcpiTableAllocType,
                   EfiACPIReclaimMemory,
                   EFI_SIZE_TO_PAGES (TotalSize),
                   &PageAddress
@@ -369,35 +383,45 @@  ReallocateAcpiTableBuffer (
   ZeroMem (Pointer, TotalSize);
   
   AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
-  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));
+  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.
   //
-  AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;
-  AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;
+  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 
   //
-  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))); 
+  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)));
   
   //
   // Calculate orignal ACPI table buffer size
   //
-  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) +
-              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT
+  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));
   
   //
@@ -504,7 +528,7 @@  AddTableToList (
     // All other tables are ACPI reclaim memory, no alignment requirements.
     //
     Status = gBS->AllocatePages (
-                    AllocateMaxAddress,
+                    mAcpiTableAllocType,
                     EfiACPIReclaimMemory,
                     CurrentTableList->NumberOfPages,
                     &CurrentTableList->PageAddress
@@ -621,13 +645,18 @@  AddTableToList (
           );
         AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
       }
-      AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;
-      Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;
-      CopyMem (
-        &AcpiTableInstance->Fadt3->XDsdt,
-        &Buffer64,
-        sizeof (UINT64)
-        );
+      if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {
+        AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;
+        ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));
+      } else {
+        Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;
+        CopyMem (
+          &AcpiTableInstance->Fadt3->XDsdt,
+          &Buffer64,
+          sizeof (UINT64)
+          );
+        AcpiTableInstance->Fadt3->Dsdt = 0;
+      }
 
       //
       // RSDP OEM information is updated to match the FADT OEM information
@@ -638,21 +667,23 @@  AddTableToList (
         6
         );
       
-      //
-      // 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;
-      
+      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.
       //
@@ -818,7 +849,9 @@  AddTableToList (
       // If FADT already exists, update table pointers.
       //
       if (AcpiTableInstance->Fadt3 != NULL) {
-        AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;
+        if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {
+          AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;
+        }
         Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;
         CopyMem (
           &AcpiTableInstance->Fadt3->XDsdt,
@@ -909,65 +942,70 @@  AddTableToList (
   // 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);
-       }
-       //
-       // 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 *)
+    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)
          );
+      }
 
-       //
-       // 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)
-         );
+      //
+      // 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 the RSDT
-       //
-       *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;
-
-       //
-       // Update RSDT length
-       //
-       AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);
-
-       //
-       // 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)
-         );
+      if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
+        //
+        // Add entry to the RSDT
+        //
+        *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;
+
+        //
+        // Update RSDT length
+        //
+        AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);
+      }
 
-       //
-       // Update length
-       //
-       AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + 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)
+        );
 
-       AcpiTableInstance->NumberOfTableEntries3++;
+      //
+      // Update length
+      //
+      AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);
+
+      AcpiTableInstance->NumberOfTableEntries3++;
     }
   }
 
@@ -1046,7 +1084,7 @@  EFI_STATUS
 RemoveTableFromRsdt (
   IN OUT EFI_ACPI_TABLE_LIST              * Table,
   IN OUT UINTN                            *NumberOfTableEntries,
-  IN OUT EFI_ACPI_DESCRIPTION_HEADER      * Rsdt,
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER      * Rsdt OPTIONAL,
   IN OUT EFI_ACPI_DESCRIPTION_HEADER      * Xsdt OPTIONAL
   )
 {
@@ -1060,7 +1098,7 @@  RemoveTableFromRsdt (
   //
   ASSERT (Table);
   ASSERT (NumberOfTableEntries);
-  ASSERT (Rsdt);
+  ASSERT (Rsdt || Xsdt);
 
   //
   // Find the table entry in the RSDT and XSDT
@@ -1070,7 +1108,11 @@  RemoveTableFromRsdt (
     // 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 *) Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));
+    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
@@ -1092,7 +1134,7 @@  RemoveTableFromRsdt (
     //
     // Check if we have found the corresponding entry in both RSDT and XSDT
     //
-    if (*CurrentRsdtEntry == (UINT32) (UINTN) Table->Table &&
+    if ((CurrentRsdtEntry == NULL || *CurrentRsdtEntry == (UINT32) (UINTN) Table->Table) &&
         ((Xsdt == NULL) || CurrentTablePointer64 == (UINT64) (UINTN) Table->Table)
         ) {
       //
@@ -1100,8 +1142,10 @@  RemoveTableFromRsdt (
       // We actually copy all + 1 to copy the initialized value of memory over
       // the last entry.
       //
-      CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));
-      Rsdt->Length = Rsdt->Length - sizeof (UINT32);
+      if (Rsdt != NULL) {
+        CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));
+        Rsdt->Length = Rsdt->Length - sizeof (UINT32);
+      }
       if (Xsdt != NULL) {
         CopyMem (CurrentXsdtEntry, ((UINT64 *) CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index) * sizeof (UINT64));
         Xsdt->Length = Xsdt->Length - sizeof (UINT64);
@@ -1117,12 +1161,14 @@  RemoveTableFromRsdt (
   //
   // Checksum the tables
   //
-  AcpiPlatformChecksum (
-    Rsdt,
-    Rsdt->Length,
-    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
-    Checksum)
-    );
+  if (Rsdt != NULL) {
+    AcpiPlatformChecksum (
+      Rsdt,
+      Rsdt->Length,
+      OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
+      Checksum)
+      );
+  }
 
   if (Xsdt != NULL) {
     AcpiPlatformChecksum (
@@ -1508,12 +1554,14 @@  ChecksumCommonTables (
   //
   // RSDP ACPI 1.0 checksum for 1.0 table.  This is only the first 20 bytes of the structure
   //
-  AcpiPlatformChecksum (
-    AcpiTableInstance->Rsdp1,
-    sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
-    OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
-    Checksum)
-    );
+  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
@@ -1535,22 +1583,24 @@  ChecksumCommonTables (
     ExtendedChecksum)
     );
 
-  //
-  // RSDT checksums
-  //
-  AcpiPlatformChecksum (
-    AcpiTableInstance->Rsdt1,
-    AcpiTableInstance->Rsdt1->Length,
-    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
-    Checksum)
-    );
+  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)
-    );
+    AcpiPlatformChecksum (
+      AcpiTableInstance->Rsdt3,
+      AcpiTableInstance->Rsdt3->Length,
+      OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
+      Checksum)
+      );
+  }
 
   //
   // XSDT checksum
@@ -1593,6 +1643,16 @@  AcpiTableAcpiTableConstructor (
   //
   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;
 
@@ -1606,12 +1666,14 @@  AcpiTableAcpiTableConstructor (
   //
   // Create RSDP table
   //
-  RsdpTableSize = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +
-                  sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
+  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);
+  }
 
   PageAddress = 0xFFFFFFFF;
   Status = gBS->AllocatePages (
-                  AllocateMaxAddress,
+                  mAcpiTableAllocType,
                   EfiACPIReclaimMemory,
                   EFI_SIZE_TO_PAGES (RsdpTableSize),
                   &PageAddress
@@ -1625,19 +1687,24 @@  AcpiTableAcpiTableConstructor (
   ZeroMem (Pointer, RsdpTableSize);
 
   AcpiTableInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;
-  Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_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 1.0 RSDT
-              mEfiAcpiMaxNumTables * sizeof (UINT32) +
-              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 RSDT
-              mEfiAcpiMaxNumTables * sizeof (UINT32) +
-              sizeof (EFI_ACPI_DESCRIPTION_HEADER) +         // for ACPI 2.0/3.0 XSDT
+  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);
+  }
+
   //
   // Allocate memory in the lower 32 bit of address range for
   // compatibility with ACPI 1.0 OS.
@@ -1649,7 +1716,7 @@  AcpiTableAcpiTableConstructor (
   //
   PageAddress = 0xFFFFFFFF;
   Status = gBS->AllocatePages (
-                  AllocateMaxAddress,
+                  mAcpiTableAllocType,
                   EfiACPIReclaimMemory,
                   EFI_SIZE_TO_PAGES (TotalSize),
                   &PageAddress
@@ -1664,66 +1731,74 @@  AcpiTableAcpiTableConstructor (
   ZeroMem (Pointer, TotalSize);
 
   AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
-  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));
+  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
   //
-  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;
+  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->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;
   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);
 
-  //
-  // 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
-  //
+  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;
-  AcpiTableInstance->Rsdt3->Length          = AcpiTableInstance->Rsdt3->Length + sizeof(UINT32);
 
   //
   // Initialize Xsdt