diff options
author | Shannon Zhao <shannon.zhao@linaro.org> | 2016-06-25 15:16:49 +0800 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2016-06-28 13:37:25 +0200 |
commit | 402dde68aff982d8a22cf032a002053d2081eb95 (patch) | |
tree | cde13ea540de850d26758e53f889e87e46e53005 | |
parent | 763cfa739b1733715fe6700a29ec078c36453f5e (diff) | |
download | edk2-402dde68aff982d8a22cf032a002053d2081eb95.tar.gz edk2-402dde68aff982d8a22cf032a002053d2081eb95.tar.bz2 edk2-402dde68aff982d8a22cf032a002053d2081eb95.zip |
ArmVirtPkg/ArmVirtXen: Add ACPI support for Virt Xen ARM
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>
-rw-r--r-- | ArmVirtPkg/ArmVirtXen.dsc | 8 | ||||
-rw-r--r-- | ArmVirtPkg/ArmVirtXen.fdf | 8 | ||||
-rw-r--r-- | ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c | 244 | ||||
-rw-r--r-- | ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf | 50 |
4 files changed, 310 insertions, 0 deletions
diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc index 594ca6491b..a869986ffa 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 13412f9e24..b1e00e5b68 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 0000000000..37aea80628 --- /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 0000000000..4f9107bc15 --- /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
|