diff mbox

[edk2,v3] ArmVirtPkg/ArmVirtXen: Add ACPI support for Virt Xen ARM

Message ID 1466839009-14812-1-git-send-email-zhaoshenglong@huawei.com
State New
Headers show

Commit Message

Shannon Zhao June 25, 2016, 7:16 a.m. UTC
From: Shannon Zhao <shannon.zhao@linaro.org>


Add ACPI support for Virt Xen ARM and only for aarch64. It gets the
ACPI tables through Xen ARM multiboot protocol.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>

---
Changes since v2:
* add gFdtClientProtocolGuid to the [Depex]
* make functions static
* move XenAcpiRsdpStructurePtr to InstallXenArmTables ()
* initialize AcpiTable and FdtClient to NULL

Changes since v1:
* move the codes into ArmVirtPkg
* use FdtClient
* don't rely on OvmfPkg/AcpiPlatformDxe/EntryPoint.c while implement own
  entry point since it's minor
* use compatible string to find the DT node instead of node path

If you want to test, the corresponding Xen patches can be fetched from:
https://git.linaro.org/people/shannon.zhao/xen.git  domu_acpi_v2
---
 ArmVirtPkg/ArmVirtXen.dsc                          |   8 +
 ArmVirtPkg/ArmVirtXen.fdf                          |   8 +
 ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c | 244 +++++++++++++++++++++
 .../XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf      |  50 +++++
 4 files changed, 310 insertions(+)
 create mode 100644 ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
 create mode 100644 ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf

-- 
2.0.4


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

Comments

Ard Biesheuvel June 28, 2016, 11:39 a.m. UTC | #1
On 25 June 2016 at 09:16, Shannon Zhao <zhaoshenglong@huawei.com> wrote:
> From: Shannon Zhao <shannon.zhao@linaro.org>

>

> Add ACPI support for Virt Xen ARM and only for aarch64. It gets the

> ACPI tables through Xen ARM multiboot protocol.

>

> Contributed-under: TianoCore Contribution Agreement 1.0

> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>


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


Committed as 402dde68aff9

Thanks,
Ard.

> ---

> Changes since v2:

> * add gFdtClientProtocolGuid to the [Depex]

> * make functions static

> * move XenAcpiRsdpStructurePtr to InstallXenArmTables ()

> * initialize AcpiTable and FdtClient to NULL

>

> Changes since v1:

> * move the codes into ArmVirtPkg

> * use FdtClient

> * don't rely on OvmfPkg/AcpiPlatformDxe/EntryPoint.c while implement own

>   entry point since it's minor

> * use compatible string to find the DT node instead of node path

>

> If you want to test, the corresponding Xen patches can be fetched from:

> https://git.linaro.org/people/shannon.zhao/xen.git  domu_acpi_v2

> ---

>  ArmVirtPkg/ArmVirtXen.dsc                          |   8 +

>  ArmVirtPkg/ArmVirtXen.fdf                          |   8 +

>  ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c | 244 +++++++++++++++++++++

>  .../XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf      |  50 +++++

>  4 files changed, 310 insertions(+)

>  create mode 100644 ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c

>  create mode 100644 ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf

>

> diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc

> index 594ca64..a869986 100644

> --- a/ArmVirtPkg/ArmVirtXen.dsc

> +++ b/ArmVirtPkg/ArmVirtXen.dsc

> @@ -216,3 +216,11 @@

>

>    OvmfPkg/XenBusDxe/XenBusDxe.inf

>    OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf

> +

> +  #

> +  # ACPI support

> +  #

> +!if $(ARCH) == AARCH64

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

> +  ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf

> +!endif

> diff --git a/ArmVirtPkg/ArmVirtXen.fdf b/ArmVirtPkg/ArmVirtXen.fdf

> index 13412f9..b1e00e5 100644

> --- a/ArmVirtPkg/ArmVirtXen.fdf

> +++ b/ArmVirtPkg/ArmVirtXen.fdf

> @@ -179,6 +179,14 @@ READ_LOCK_STATUS   = TRUE

>    INF OvmfPkg/XenBusDxe/XenBusDxe.inf

>    INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf

>

> +  #

> +  # ACPI support

> +  #

> +!if $(ARCH) == AARCH64

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

> +  INF ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf

> +!endif

> +

>  [FV.FVMAIN_COMPACT]

>  FvAlignment        = 16

>  ERASE_POLARITY     = 1

> diff --git a/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c

> new file mode 100644

> index 0000000..c6912ba

> --- /dev/null

> +++ b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c

> @@ -0,0 +1,244 @@

> +/** @file

> +  Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol

> +

> +  Copyright (C) 2016, Linaro Ltd. All rights reserved.

> +

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

> +  http://opensource.org/licenses/bsd-license.php

> +

> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

> +

> +**/

> +

> +#include <Library/BaseLib.h>

> +#include <Library/DebugLib.h>

> +#include <Library/UefiBootServicesTableLib.h>

> +#include <Library/UefiDriverEntryPoint.h>

> +

> +#include <Protocol/AcpiTable.h>

> +#include <Protocol/FdtClient.h>

> +

> +#include <IndustryStandard/Acpi.h>

> +

> +/**

> +  Get the address of Xen ACPI Root System Description Pointer (RSDP)

> +  structure.

> +

> +  @param  RsdpStructurePtr   Return pointer to RSDP structure

> +

> +  @return EFI_SUCCESS        Find Xen RSDP structure successfully.

> +  @return EFI_NOT_FOUND      Don't find Xen RSDP structure.

> +  @return EFI_ABORTED        Find Xen RSDP structure, but it's not integrated.

> +

> +**/

> +STATIC

> +EFI_STATUS

> +EFIAPI

> +GetXenArmAcpiRsdp (

> +  OUT   EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER   **RsdpPtr

> +  )

> +{

> +  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER   *RsdpStructurePtr;

> +  EFI_STATUS                                     Status;

> +  FDT_CLIENT_PROTOCOL                            *FdtClient;

> +  CONST UINT64                                   *Reg;

> +  UINT32                                         RegElemSize, RegSize;

> +  UINT64                                         RegBase;

> +  UINT8                                          Sum;

> +

> +  RsdpStructurePtr = NULL;

> +  FdtClient = NULL;

> +  //

> +  // Get the RSDP structure address from DeviceTree

> +  //

> +  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,

> +                  (VOID **)&FdtClient);

> +  ASSERT_EFI_ERROR (Status);

> +

> +  Status = FdtClient->FindCompatibleNodeReg (FdtClient, "xen,guest-acpi",

> +                        (CONST VOID **)&Reg, &RegElemSize, &RegSize);

> +  if (EFI_ERROR (Status)) {

> +    DEBUG ((EFI_D_WARN, "%a: No 'xen,guest-acpi' compatible DT node found\n",

> +      __FUNCTION__));

> +    return EFI_NOT_FOUND;

> +  }

> +

> +  ASSERT (RegSize == 2 * sizeof (UINT64));

> +

> +  RegBase = SwapBytes64(Reg[0]);

> +  RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)RegBase;

> +

> +  if (RsdpStructurePtr && RsdpStructurePtr->Revision >= 2) {

> +    Sum = CalculateSum8 ((CONST UINT8 *)RsdpStructurePtr,

> +            sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER));

> +    if (Sum != 0) {

> +      return EFI_ABORTED;

> +    }

> +  }

> +

> +  *RsdpPtr = RsdpStructurePtr;

> +  return EFI_SUCCESS;

> +}

> +

> +/**

> +  Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables

> +  into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed

> +  ACPI tables are: FACP, APIC, GTDT, DSDT.

> +

> +  @param  AcpiProtocol           Protocol instance pointer.

> +

> +  @return EFI_SUCCESS            The table was successfully inserted.

> +  @return EFI_INVALID_PARAMETER  Either AcpiTableBuffer is NULL, TableHandle is

> +                                 NULL, or AcpiTableBufferSize and the size

> +                                 field embedded in the ACPI table pointed to

> +                                 by AcpiTableBuffer are not in sync.

> +  @return EFI_OUT_OF_RESOURCES   Insufficient resources exist to complete the request.

> +

> +**/

> +STATIC

> +EFI_STATUS

> +EFIAPI

> +InstallXenArmTables (

> +  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol

> +  )

> +{

> +  EFI_STATUS                                       Status;

> +  UINTN                                            TableHandle;

> +  VOID                                             *CurrentTableEntry;

> +  UINTN                                            CurrentTablePointer;

> +  EFI_ACPI_DESCRIPTION_HEADER                      *CurrentTable;

> +  UINTN                                            Index;

> +  UINTN                                            NumberOfTableEntries;

> +  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER     *XenAcpiRsdpStructurePtr;

> +  EFI_ACPI_DESCRIPTION_HEADER                      *Xsdt;

> +  EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE        *FadtTable;

> +  EFI_ACPI_DESCRIPTION_HEADER                      *DsdtTable;

> +

> +  XenAcpiRsdpStructurePtr = NULL;

> +  FadtTable   = NULL;

> +  DsdtTable   = NULL;

> +  TableHandle = 0;

> +  NumberOfTableEntries = 0;

> +

> +  //

> +  // Try to find Xen ARM ACPI tables

> +  //

> +  Status = GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr);

> +  if (EFI_ERROR (Status)) {

> +    DEBUG ((EFI_D_INFO, "%a: No RSDP table found\n", __FUNCTION__));

> +    return Status;

> +  }

> +

> +  //

> +  // If XSDT table is find, just install its tables.

> +  //

> +  if (XenAcpiRsdpStructurePtr->XsdtAddress) {

> +    //

> +    // Retrieve the addresses of XSDT and

> +    // calculate the number of its table entries.

> +    //

> +    Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)

> +             XenAcpiRsdpStructurePtr->XsdtAddress;

> +    NumberOfTableEntries = (Xsdt->Length -

> +                             sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /

> +                             sizeof (UINT64);

> +    //

> +    // Install ACPI tables found in XSDT.

> +    //

> +    for (Index = 0; Index < NumberOfTableEntries; Index++) {

> +      //

> +      // Get the table entry from XSDT

> +      //

> +      CurrentTableEntry = (VOID *) ((UINT8 *) Xsdt +

> +                            sizeof (EFI_ACPI_DESCRIPTION_HEADER) +

> +                            Index * sizeof (UINT64));

> +      CurrentTablePointer = (UINTN) *(UINT64 *)CurrentTableEntry;

> +      CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;

> +

> +      //

> +      // Install the XSDT tables

> +      //

> +      Status = AcpiProtocol->InstallAcpiTable (

> +                 AcpiProtocol,

> +                 CurrentTable,

> +                 CurrentTable->Length,

> +                 &TableHandle

> +                 );

> +

> +      if (EFI_ERROR (Status)) {

> +        return Status;

> +      }

> +

> +      //

> +      // Get the FACS and DSDT table address from the table FADT

> +      //

> +      if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {

> +        FadtTable = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)

> +                      (UINTN) CurrentTablePointer;

> +        DsdtTable  = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) FadtTable->Dsdt;

> +      }

> +    }

> +  }

> +

> +  //

> +  // Install DSDT table.

> +  //

> +  Status = AcpiProtocol->InstallAcpiTable (

> +             AcpiProtocol,

> +             DsdtTable,

> +             DsdtTable->Length,

> +             &TableHandle

> +             );

> +  if (EFI_ERROR (Status)) {

> +    return Status;

> +  }

> +

> +  return EFI_SUCCESS;

> +}

> +

> +STATIC

> +EFI_ACPI_TABLE_PROTOCOL *

> +FindAcpiTableProtocol (

> +  VOID

> +  )

> +{

> +  EFI_STATUS              Status;

> +  EFI_ACPI_TABLE_PROTOCOL *AcpiTable;

> +

> +  AcpiTable = NULL;

> +  Status = gBS->LocateProtocol (

> +                  &gEfiAcpiTableProtocolGuid,

> +                  NULL,

> +                  (VOID**)&AcpiTable

> +                  );

> +  ASSERT_EFI_ERROR (Status);

> +  return AcpiTable;

> +}

> +

> +/**

> +  Entrypoint of Xen ARM Acpi Platform driver.

> +

> +  @param  ImageHandle

> +  @param  SystemTable

> +

> +  @return EFI_SUCCESS

> +  @return EFI_LOAD_ERROR

> +  @return EFI_OUT_OF_RESOURCES

> +

> +**/

> +

> +EFI_STATUS

> +EFIAPI

> +XenAcpiPlatformEntryPoint (

> +  IN EFI_HANDLE         ImageHandle,

> +  IN EFI_SYSTEM_TABLE   *SystemTable

> +  )

> +{

> +  EFI_STATUS                         Status;

> +

> +  Status = InstallXenArmTables (FindAcpiTableProtocol ());

> +  return Status;

> +}

> diff --git a/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf

> new file mode 100644

> index 0000000..4f9107b

> --- /dev/null

> +++ b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf

> @@ -0,0 +1,50 @@

> +## @file

> +#  Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol

> +#

> +#  Copyright (C) 2016, Linaro Ltd. All rights reserved.

> +#

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

> +#  http://opensource.org/licenses/bsd-license.php

> +#

> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

> +#

> +##

> +

> +[Defines]

> +  INF_VERSION                    = 0x00010005

> +  BASE_NAME                      = XenAcpiPlatformDxe

> +  FILE_GUID                      = 0efc6282-f1e5-469a-8a70-194a8761f9aa

> +  MODULE_TYPE                    = DXE_DRIVER

> +  VERSION_STRING                 = 1.0

> +  ENTRY_POINT                    = XenAcpiPlatformEntryPoint

> +

> +#

> +# The following information is for reference only and not required by the build tools.

> +#

> +#  VALID_ARCHITECTURES           = AARCH64

> +#

> +

> +[Sources]

> +  XenAcpiPlatformDxe.c

> +

> +[Packages]

> +  ArmVirtPkg/ArmVirtPkg.dec

> +  MdePkg/MdePkg.dec

> +  MdeModulePkg/MdeModulePkg.dec

> +

> +[LibraryClasses]

> +  BaseLib

> +  DebugLib

> +  UefiBootServicesTableLib

> +  UefiDriverEntryPoint

> +

> +[Protocols]

> +  gEfiAcpiTableProtocolGuid                     ## PROTOCOL ALWAYS_CONSUMED

> +  gFdtClientProtocolGuid                        ## CONSUMES

> +

> +[Depex]

> +  gFdtClientProtocolGuid    AND

> +  gEfiAcpiTableProtocolGuid

> --

> 2.0.4

>

>

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Julien Grall June 28, 2016, 12:06 p.m. UTC | #2
Hi Ard,

On 28/06/16 12:39, Ard Biesheuvel wrote:
> On 25 June 2016 at 09:16, Shannon Zhao <zhaoshenglong@huawei.com> wrote:
>> From: Shannon Zhao <shannon.zhao@linaro.org>
>>
>> Add ACPI support for Virt Xen ARM and only for aarch64. It gets the
>> ACPI tables through Xen ARM multiboot protocol.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> Committed as 402dde68aff9

We have not yet agreed on the bindings between Xen and UEFI (see patch 
[1]). How EDK2 deal with compatibility if we decide to modify the 
bindings for whatever reasons?

Regards,

[1] 
http://lists.xenproject.org/archives/html/xen-devel/2016-06/msg02943.html
Ard Biesheuvel June 28, 2016, 12:13 p.m. UTC | #3
On 28 June 2016 at 14:06, Julien Grall <julien.grall@arm.com> wrote:
> Hi Ard,

>

> On 28/06/16 12:39, Ard Biesheuvel wrote:

>>

>> On 25 June 2016 at 09:16, Shannon Zhao <zhaoshenglong@huawei.com> wrote:

>>>

>>> From: Shannon Zhao <shannon.zhao@linaro.org>

>>>

>>> Add ACPI support for Virt Xen ARM and only for aarch64. It gets the

>>> ACPI tables through Xen ARM multiboot protocol.

>>>

>>> Contributed-under: TianoCore Contribution Agreement 1.0

>>> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>

>>

>>

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

>>

>> Committed as 402dde68aff9

>

>

> We have not yet agreed on the bindings between Xen and UEFI (see patch [1]).

> How EDK2 deal with compatibility if we decide to modify the bindings for

> whatever reasons?

>


Thanks for emphasizing that. It would have been good to mention it in
the commit log.

Since this is all under development, I would prefer only the final
version of the binding to be supported (if it deviates from the one
this patch implements). As soon as anything ends up in a Xen release,
we can discuss again whether we need to support different versions of
the binding.

Thanks,
Ard.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
diff mbox

Patch

diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc
index 594ca64..a869986 100644
--- a/ArmVirtPkg/ArmVirtXen.dsc
+++ b/ArmVirtPkg/ArmVirtXen.dsc
@@ -216,3 +216,11 @@ 
 
   OvmfPkg/XenBusDxe/XenBusDxe.inf
   OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+
+  #
+  # ACPI support
+  #
+!if $(ARCH) == AARCH64
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf
+!endif
diff --git a/ArmVirtPkg/ArmVirtXen.fdf b/ArmVirtPkg/ArmVirtXen.fdf
index 13412f9..b1e00e5 100644
--- a/ArmVirtPkg/ArmVirtXen.fdf
+++ b/ArmVirtPkg/ArmVirtXen.fdf
@@ -179,6 +179,14 @@  READ_LOCK_STATUS   = TRUE
   INF OvmfPkg/XenBusDxe/XenBusDxe.inf
   INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
 
+  #
+  # ACPI support
+  #
+!if $(ARCH) == AARCH64
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  INF ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf
+!endif
+
 [FV.FVMAIN_COMPACT]
 FvAlignment        = 16
 ERASE_POLARITY     = 1
diff --git a/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
new file mode 100644
index 0000000..c6912ba
--- /dev/null
+++ b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
@@ -0,0 +1,244 @@ 
+/** @file
+  Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol
+
+  Copyright (C) 2016, Linaro Ltd. All rights reserved.
+
+  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
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/ 
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/FdtClient.h>
+
+#include <IndustryStandard/Acpi.h>
+
+/**
+  Get the address of Xen ACPI Root System Description Pointer (RSDP)
+  structure.
+
+  @param  RsdpStructurePtr   Return pointer to RSDP structure
+
+  @return EFI_SUCCESS        Find Xen RSDP structure successfully.
+  @return EFI_NOT_FOUND      Don't find Xen RSDP structure.
+  @return EFI_ABORTED        Find Xen RSDP structure, but it's not integrated.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetXenArmAcpiRsdp (
+  OUT   EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER   **RsdpPtr
+  )
+{
+  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER   *RsdpStructurePtr;
+  EFI_STATUS                                     Status;
+  FDT_CLIENT_PROTOCOL                            *FdtClient;
+  CONST UINT64                                   *Reg;
+  UINT32                                         RegElemSize, RegSize;
+  UINT64                                         RegBase;
+  UINT8                                          Sum;
+
+  RsdpStructurePtr = NULL;
+  FdtClient = NULL;
+  //
+  // Get the RSDP structure address from DeviceTree
+  //
+  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
+                  (VOID **)&FdtClient);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = FdtClient->FindCompatibleNodeReg (FdtClient, "xen,guest-acpi",
+                        (CONST VOID **)&Reg, &RegElemSize, &RegSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_WARN, "%a: No 'xen,guest-acpi' compatible DT node found\n",
+      __FUNCTION__));
+    return EFI_NOT_FOUND;
+  }
+
+  ASSERT (RegSize == 2 * sizeof (UINT64));
+
+  RegBase = SwapBytes64(Reg[0]);
+  RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)RegBase;
+
+  if (RsdpStructurePtr && RsdpStructurePtr->Revision >= 2) {
+    Sum = CalculateSum8 ((CONST UINT8 *)RsdpStructurePtr,
+            sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER));
+    if (Sum != 0) {
+      return EFI_ABORTED;
+    }
+  }
+
+  *RsdpPtr = RsdpStructurePtr;
+  return EFI_SUCCESS;
+}
+
+/**
+  Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
+  into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
+  ACPI tables are: FACP, APIC, GTDT, DSDT.
+
+  @param  AcpiProtocol           Protocol instance pointer.
+
+  @return EFI_SUCCESS            The table was successfully inserted.
+  @return EFI_INVALID_PARAMETER  Either AcpiTableBuffer is NULL, TableHandle is
+                                 NULL, or AcpiTableBufferSize and the size
+                                 field embedded in the ACPI table pointed to
+                                 by AcpiTableBuffer are not in sync.
+  @return EFI_OUT_OF_RESOURCES   Insufficient resources exist to complete the request.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+InstallXenArmTables (
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol
+  )
+{
+  EFI_STATUS                                       Status;
+  UINTN                                            TableHandle;
+  VOID                                             *CurrentTableEntry;
+  UINTN                                            CurrentTablePointer;
+  EFI_ACPI_DESCRIPTION_HEADER                      *CurrentTable;
+  UINTN                                            Index;
+  UINTN                                            NumberOfTableEntries;
+  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER     *XenAcpiRsdpStructurePtr;
+  EFI_ACPI_DESCRIPTION_HEADER                      *Xsdt;
+  EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE        *FadtTable;
+  EFI_ACPI_DESCRIPTION_HEADER                      *DsdtTable;
+
+  XenAcpiRsdpStructurePtr = NULL;
+  FadtTable   = NULL;
+  DsdtTable   = NULL;
+  TableHandle = 0;
+  NumberOfTableEntries = 0;
+
+  //
+  // Try to find Xen ARM ACPI tables
+  //
+  Status = GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_INFO, "%a: No RSDP table found\n", __FUNCTION__));
+    return Status;
+  }
+
+  //
+  // If XSDT table is find, just install its tables. 
+  //
+  if (XenAcpiRsdpStructurePtr->XsdtAddress) {
+    //
+    // Retrieve the addresses of XSDT and 
+    // calculate the number of its table entries.
+    //
+    Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)
+             XenAcpiRsdpStructurePtr->XsdtAddress;
+    NumberOfTableEntries = (Xsdt->Length -
+                             sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
+                             sizeof (UINT64);
+    //
+    // Install ACPI tables found in XSDT.
+    //
+    for (Index = 0; Index < NumberOfTableEntries; Index++) {
+      //
+      // Get the table entry from XSDT
+      //
+      CurrentTableEntry = (VOID *) ((UINT8 *) Xsdt +
+                            sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
+                            Index * sizeof (UINT64));
+      CurrentTablePointer = (UINTN) *(UINT64 *)CurrentTableEntry;
+      CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;
+
+      //
+      // Install the XSDT tables
+      //
+      Status = AcpiProtocol->InstallAcpiTable (
+                 AcpiProtocol,
+                 CurrentTable,
+                 CurrentTable->Length,
+                 &TableHandle
+                 );
+
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+
+      //
+      // Get the FACS and DSDT table address from the table FADT
+      //
+      if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {
+        FadtTable = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)
+                      (UINTN) CurrentTablePointer;
+        DsdtTable  = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) FadtTable->Dsdt;
+      }
+    }
+  }
+
+  //
+  // Install DSDT table.
+  //
+  Status = AcpiProtocol->InstallAcpiTable (
+             AcpiProtocol,
+             DsdtTable,
+             DsdtTable->Length,
+             &TableHandle
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_ACPI_TABLE_PROTOCOL *
+FindAcpiTableProtocol (
+  VOID
+  )
+{
+  EFI_STATUS              Status;
+  EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+
+  AcpiTable = NULL;
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID**)&AcpiTable
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return AcpiTable;
+}
+
+/**
+  Entrypoint of Xen ARM Acpi Platform driver.
+
+  @param  ImageHandle
+  @param  SystemTable
+
+  @return EFI_SUCCESS
+  @return EFI_LOAD_ERROR
+  @return EFI_OUT_OF_RESOURCES
+
+**/
+
+EFI_STATUS
+EFIAPI
+XenAcpiPlatformEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                         Status;
+
+  Status = InstallXenArmTables (FindAcpiTableProtocol ());
+  return Status;
+}
diff --git a/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf
new file mode 100644
index 0000000..4f9107b
--- /dev/null
+++ b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf
@@ -0,0 +1,50 @@ 
+## @file
+#  Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol
+#
+#  Copyright (C) 2016, Linaro Ltd. All rights reserved.
+#
+#  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
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = XenAcpiPlatformDxe
+  FILE_GUID                      = 0efc6282-f1e5-469a-8a70-194a8761f9aa
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = XenAcpiPlatformEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  XenAcpiPlatformDxe.c
+
+[Packages]
+  ArmVirtPkg/ArmVirtPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid                     ## PROTOCOL ALWAYS_CONSUMED
+  gFdtClientProtocolGuid                        ## CONSUMES
+
+[Depex]
+  gFdtClientProtocolGuid    AND
+  gEfiAcpiTableProtocolGuid