--- /dev/null
+/** @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
--- /dev/null
+## @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