summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/AcpiPlatformDxe
diff options
context:
space:
mode:
authorSebastien Boeuf <sebastien.boeuf@intel.com>2021-12-10 22:41:58 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-12-11 14:26:05 +0000
commit7594c5bfe2d9943aaca73c492dcbf7015bfbf825 (patch)
treefb471912ac5077d61a60ba18c11cae0b6b47c22f /OvmfPkg/AcpiPlatformDxe
parent66bce05f6d153c8d731d0d27cdec065406604d50 (diff)
downloadedk2-7594c5bfe2d9943aaca73c492dcbf7015bfbf825.tar.gz
edk2-7594c5bfe2d9943aaca73c492dcbf7015bfbf825.tar.bz2
edk2-7594c5bfe2d9943aaca73c492dcbf7015bfbf825.zip
OvmfPkg: Install ACPI tables for Cloud Hypervisor
Adding support for retrieving the Cloud Hypervisor ACPI tables as a fallback mechanism if tables are not found through fw_cfg. Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Rob Bradford <robert.bradford@intel.com> Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Diffstat (limited to 'OvmfPkg/AcpiPlatformDxe')
-rw-r--r--OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c11
-rw-r--r--OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h6
-rw-r--r--OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf2
-rw-r--r--OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c118
4 files changed, 136 insertions, 1 deletions
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
index 274db28685..fcfb9703bd 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
@@ -7,6 +7,8 @@
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
+#include <OvmfPlatforms.h> // CLOUDHV_DEVICE_ID
+
#include "AcpiPlatform.h"
/**
@@ -27,7 +29,14 @@ InstallAcpiTables (
)
{
EFI_STATUS Status;
+ UINT16 HostBridgeDevId;
+
+ HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);
+ if (HostBridgeDevId == CLOUDHV_DEVICE_ID) {
+ Status = InstallCloudHvTables (AcpiTable);
+ } else {
+ Status = InstallQemuFwCfgTables (AcpiTable);
+ }
- Status = InstallQemuFwCfgTables (AcpiTable);
return Status;
}
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
index 1ccca0a368..342339750d 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
@@ -21,6 +21,12 @@ typedef struct S3_CONTEXT S3_CONTEXT;
EFI_STATUS
EFIAPI
+InstallCloudHvTables (
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
+ );
+
+EFI_STATUS
+EFIAPI
InstallQemuFwCfgTables (
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
);
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
index eedd3b5af3..b36b8413e0 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -24,6 +24,7 @@
AcpiPlatform.c
AcpiPlatform.h
BootScript.c
+ CloudHvAcpi.c
EntryPoint.c
PciDecoding.c
QemuFwCfgAcpi.c
@@ -54,6 +55,7 @@
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
[Depex]
gEfiAcpiTableProtocolGuid
diff --git a/OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c b/OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
new file mode 100644
index 0000000000..44a6bb70fe
--- /dev/null
+++ b/OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
@@ -0,0 +1,118 @@
+/** @file
+ OVMF ACPI Cloud Hypervisor support
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/CloudHv.h> // CLOUDHV_RSDP_ADDRESS
+#include <Library/BaseLib.h> // CpuDeadLoop()
+#include <Library/DebugLib.h> // DEBUG()
+
+#include "AcpiPlatform.h"
+
+// Get the ACPI tables from EBDA start
+EFI_STATUS
+EFIAPI
+InstallCloudHvTables (
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
+ )
+{
+ EFI_STATUS Status;
+ UINTN TableHandle;
+
+ EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
+ VOID *CurrentTableEntry;
+ UINTN CurrentTablePointer;
+ EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
+ UINTN Index;
+ UINTN NumberOfTableEntries;
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;
+ EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;
+
+ Fadt2Table = NULL;
+ DsdtTable = NULL;
+ TableHandle = 0;
+ NumberOfTableEntries = 0;
+ EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *AcpiRsdpStructurePtr = (VOID *)CLOUDHV_RSDP_ADDRESS;
+
+ // If XSDT table is found, just install its tables.
+ // Otherwise, try to find and install the RSDT tables.
+ //
+ if (AcpiRsdpStructurePtr->XsdtAddress) {
+ //
+ // Retrieve the addresses of XSDT and
+ // calculate the number of its table entries.
+ //
+ Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)
+ AcpiRsdpStructurePtr->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)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ //
+ // Get the X-DSDT table address from the table FADT
+ //
+ if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) {
+ Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)
+ (UINTN)CurrentTablePointer;
+ DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt2Table->XDsdt;
+ }
+ }
+ } else {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Install DSDT table. If we reached this point without finding the DSDT,
+ // then we're out of sync with the hypervisor, and cannot continue.
+ //
+ if (DsdtTable == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ Status = AcpiProtocol->InstallAcpiTable (
+ AcpiProtocol,
+ DsdtTable,
+ DsdtTable->Length,
+ &TableHandle
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}