On 02/17/16 15:48, 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 PcdAcpiAllocateTablesBelow4GB defaulting to TRUE, and wire
> it up to the memory allocation calls in AcpiTableDxe/AcpiTableProtocol.c
> 
> 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 <[email protected]>
> ---
>  MdeModulePkg/MdeModulePkg.dec                                |   7 +
>  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf    |   2 +
>  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 447 
> ++++++++++++--------
>  3 files changed, 270 insertions(+), 186 deletions(-)

Somewhat independently of your patch, I agree 100% that the interface
exposed by EFI_ACPI_TABLE_PROTOCOL is seriously lacking. It doesn't
allow the caller to control the allocation limit (--> see your patch),
nor the UEFI memory type that the copy of the table being installed will
be placed into (it would be valid for the caller to choose between
AcpiReclaim vs. AcpiNVS), nor the question whether the table being
installed should be linked into the RSDT, XSDT, or both.

I don't find this an implementation problem; this is a problem with the
specification. In particular, in October last year I cross-posted an
email to the USWG and ASWG lists, entitled

  LoadTable vs. EFI_ACPI_TABLE_PROTOCOL

In that email, I pointed out that the current edk2 implementation of
EFI_ACPI_TABLE_PROTOCOL makes it impossible to support the LoadTable
ACPI operator. Namely, the LoadTable operator requires the definition
block (= AML code) being loaded dynamically to come *from* AcpiNVS type
memory, but edk2's implementation doesn't allow the caller to install
tables into AcpiNVS type memory, *except* those with the signature
"UEFI" -- those however are *data* tables, not definition blocks (= AML
code, like SSDT or DSDT).

For this reason, I proposed EFI_ACPI_TABLE2_PROTOCOL:

> - same set of member functions
> - UninstallAcpiTable() works the same
> - InstallAcpiTable() gets a new parameter called MemoryType:
>
> typedef
> EFI_STATUS
> (EFIAPI *EFI_ACPI_TABLE2_INSTALL_ACPI_TABLE) (
>   IN EFI_ACPI_TABLE2_PROTOCOL *This,
>   IN VOID                     *AcpiTableBuffer,
>   IN UINTN                    AcpiTableBufferSize,
>   IN EFI_MEMORY_TYPE          *MemoryType         OPTIONAL,
>   OUT UINTN                   *TableKey
> );
>
> - If MemoryType is NULL, then the new interface works identically to
>   the preexistent one.
> - Otherwise, if EFI_ACPI_TABLE2_PROTOCOL can prove that *MemoryType is
>   invalid for the signature detected in AcpiTableBuffer, then
>   EFI_INVALID_PARAMETER is returned.
> - Otherwise, the copy of AcpiTableBuffer is allocated from *MemoryType
>   memory.
>
> This would allow tables with any (non-standard) signatures to be
> placed in reserved or AcpiNVS memory, regardless of contents.

My query to the USWG & ASWG garnered exactly *zero* replies. I guess
nobody cared about (or understood) my problem.

Now I absolutely view your use case as a further parameter that
"EFI_ACPI_TABLE2_PROTOCOL" should expose. From that POV, I support your
use case.

Regarding the implementation, I guess you are not enthusiastic about
turning this question into a standardization effort. (I tried and
failed.) So, whatever works for you -- I won't review the code, but as
long as it can remain compatible with current clients, given the right
PCD settings, I absolutely support the idea.

(QEMU currently depends on tables being allocated under 4GB, even for
aarch64 guests, as far as I recall.)

Digressing a bit, I'll also mention that I found out (and reported) the
hard way that Microsoft's ACPI.SYS does not implement the
DataTableRegion operator. (ACPI CA does.) That operator is supposed to
be extremely powerful, it is not optional, and it dates back to the ACPI
2.0 specification -- which Microsoft co-authored.

I'm sorry to say, but this makes the ACPI spec, and the ASWG, a joke.

Thanks
Laszlo

> 
> diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
> index 5c5a9ee13138..35da23c15eb5 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
> @@ -652,6 +653,12 @@ [PcdsFeatureFlag]
>    # @Prompt Enable ACPI SDT support.
>    
> gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|FALSE|BOOLEAN|0x0001004d
>  
> +  ## Indicates if ACPI table allocations should be below 4 GB.<BR><BR>
> +  #   TRUE  - Allocate ACPI tables below 4 GB.<BR>
> +  #   FALSE - Allocate ACPI tables anywhere.<BR>
> +  # @Prompt Allocate ACPI tables below 4 GB.
> +  
> gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiAllocateTablesBelow4GB|TRUE|BOOLEAN|0x0001004c
> +
>    ## Indicates if the unaligned I/O, MMIO, and PCI Configuration cycles 
> through the PCI I/O Protocol are enabled.
>    #  The default value for this PCD is false to disable support for 
> unaligned PCI I/O Protocol requests.<BR><BR>
>    #   TRUE  - Enables the unaligned I/O, MMIO, and PCI Configuration cycles 
> through the PCI I/O Protocol.<BR>
> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf 
> b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> index e9cd728dbfb6..c5e6788186ce 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
> @@ -67,6 +68,7 @@ [Pcd]
>    gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision      ## CONSUMES
>    gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId        ## CONSUMES
>    gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision  ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiAllocateTablesBelow4GB  ## CONSUMES
>  
>  [Protocols]
>    gEfiAcpiTableProtocolGuid                     ## PRODUCES
> diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c 
> b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
> index c6abf1bf0c52..cb2b957989e2 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 PcdAcpiAllocateTablesBelow4GB.
> +//
> +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.
> @@ -135,8 +142,10 @@ PublishTables (
>      *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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +      CurrentRsdtEntry  = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt3 + 
> sizeof (EFI_ACPI_DESCRIPTION_HEADER));
> +      *CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt3;
> +    }
>      CurrentXsdtEntry  = (VOID *) ((UINT8 *) AcpiTableInstance->Xsdt + sizeof 
> (EFI_ACPI_DESCRIPTION_HEADER));
>      //
>      // Add entry to XSDT, XSDT expects 64 bit pointers, but
> @@ -209,6 +218,7 @@ InstallAcpiTable (
>    EFI_ACPI_TABLE_INSTANCE   *AcpiTableInstance;
>    EFI_STATUS                Status;
>    VOID                      *AcpiTableBufferConst;
> +  EFI_ACPI_TABLE_VERSION    Version;
>  
>    //
>    // Check for invalid input parameters
> @@ -218,6 +228,11 @@ InstallAcpiTable (
>      return EFI_INVALID_PARAMETER;
>    }
>  
> +  Version = ACPI_TABLE_VERSION_GTE_2_0;
> +  if (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    Version |= EFI_ACPI_TABLE_VERSION_1_0B;
> +  }
> +
>    //
>    // Get the instance of the ACPI table protocol
>    //
> @@ -232,13 +247,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 +265,7 @@ InstallAcpiTable (
>      if (!EFI_ERROR (Status)) {
>        SdtNotifyAcpiList (
>          AcpiTableInstance,
> -        EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,
> +        Version,
>          *TableKey
>          );
>      }
> @@ -337,16 +352,19 @@ 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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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.
> +  // compatibility with ACPI 1.0 OS if PcdAcpiAllocateTablesBelow4GB == TRUE
>    //
>    // This is done because ACPI 1.0 pointers are 32 bit values.
>    // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
> @@ -355,7 +373,7 @@ ReallocateAcpiTableBuffer (
>    //
>    PageAddress = 0xFFFFFFFF;
>    Status = gBS->AllocatePages (
> -                  AllocateMaxAddress,
> +                  mAcpiTableAllocType,
>                    EfiACPIReclaimMemory,
>                    EFI_SIZE_TO_PAGES (TotalSize),
>                    &PageAddress
> @@ -369,35 +387,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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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));
>    
>    //
> @@ -494,7 +522,7 @@ AddTableToList (
>      //
>      ASSERT ((EFI_PAGE_SIZE % 64) == 0);
>      Status = gBS->AllocatePages (
> -                    AllocateMaxAddress,
> +                    mAcpiTableAllocType,
>                      EfiACPIMemoryNVS,
>                      CurrentTableList->NumberOfPages,
>                      &CurrentTableList->PageAddress
> @@ -504,7 +532,7 @@ AddTableToList (
>      // All other tables are ACPI reclaim memory, no alignment requirements.
>      //
>      Status = gBS->AllocatePages (
> -                    AllocateMaxAddress,
> +                    mAcpiTableAllocType,
>                      EfiACPIReclaimMemory,
>                      CurrentTableList->NumberOfPages,
>                      &CurrentTableList->PageAddress
> @@ -621,13 +649,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 +671,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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +        //
> +        // 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 +853,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 +946,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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +        //
> +        // 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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +        //
> +        // 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 +1088,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 +1102,7 @@ RemoveTableFromRsdt (
>    //
>    ASSERT (Table);
>    ASSERT (NumberOfTableEntries);
> -  ASSERT (Rsdt);
> +  ASSERT (Rsdt || Xsdt);
>  
>    //
>    // Find the table entry in the RSDT and XSDT
> @@ -1070,7 +1112,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 +1138,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 +1146,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 +1165,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 +1558,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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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 +1587,24 @@ ChecksumCommonTables (
>      ExtendedChecksum)
>      );
>  
> -  //
> -  // RSDT checksums
> -  //
> -  AcpiPlatformChecksum (
> -    AcpiTableInstance->Rsdt1,
> -    AcpiTableInstance->Rsdt1->Length,
> -    OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
> -    Checksum)
> -    );
> +  if (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    //
> +    // 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 +1647,12 @@ AcpiTableAcpiTableConstructor (
>    //
>    ASSERT (AcpiTableInstance);
>  
> +  if (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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,22 +1687,27 @@ 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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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.
> +  // compatibility with ACPI 1.0 OS if PcdAcpiAllocateTablesBelow4GB == TRUE
>    //
>    // This is done because ACPI 1.0 pointers are 32 bit values.
>    // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
> @@ -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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    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));
> +  if (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) 
> AcpiTableInstance->Rsdt3;
> +  }
>    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);
>    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 (FeaturePcdGet (PcdAcpiAllocateTablesBelow4GB)) {
> +    //
> +    // 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
> 

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to