]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmVirtPkg/ArmVirtXen: Add ACPI support for Virt Xen ARM
authorShannon Zhao <shannon.zhao@linaro.org>
Sat, 25 Jun 2016 07:16:49 +0000 (15:16 +0800)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 28 Jun 2016 11:37:25 +0000 (13:37 +0200)
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>
ArmVirtPkg/ArmVirtXen.dsc
ArmVirtPkg/ArmVirtXen.fdf
ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c [new file with mode: 0644]
ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf [new file with mode: 0644]

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