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>
This commit is contained in:
committed by
mergify[bot]
parent
66bce05f6d
commit
7594c5bfe2
118
OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
Normal file
118
OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
Normal file
@@ -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;
|
||||
}
|
Reference in New Issue
Block a user