From 7594c5bfe2d9943aaca73c492dcbf7015bfbf825 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Fri, 10 Dec 2021 22:41:58 +0800 Subject: 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 Reviewed-by: Jiewen Yao Signed-off-by: Rob Bradford Signed-off-by: Sebastien Boeuf --- OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c | 11 ++- OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h | 6 ++ OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | 2 + OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c | 118 ++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c (limited to 'OvmfPkg/AcpiPlatformDxe') 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 // 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 @@ -19,6 +19,12 @@ typedef struct { typedef struct S3_CONTEXT S3_CONTEXT; +EFI_STATUS +EFIAPI +InstallCloudHvTables ( + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol + ); + EFI_STATUS EFIAPI InstallQemuFwCfgTables ( 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 // CLOUDHV_RSDP_ADDRESS +#include // CpuDeadLoop() +#include // 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; +} -- cgit v1.2.3