Skip to content

Commit

Permalink
OvmfPkg: Install ACPI tables for Cloud Hypervisor
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Jiewen Yao <[email protected]>
Signed-off-by: Rob Bradford <[email protected]>
Signed-off-by: Sebastien Boeuf <[email protected]>
  • Loading branch information
Sebastien Boeuf committed Dec 6, 2021
1 parent 0cfd195 commit 003998b
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 1 deletion.
11 changes: 10 additions & 1 deletion OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <OvmfPlatforms.h> // CLOUDHV_DEVICE_ID

#include "AcpiPlatform.h"

/**
Expand All @@ -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;
}
6 changes: 6 additions & 0 deletions OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
2 changes: 2 additions & 0 deletions OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
AcpiPlatform.c
AcpiPlatform.h
BootScript.c
CloudHvAcpi.c
EntryPoint.c
PciDecoding.c
QemuFwCfgAcpi.c
Expand Down Expand Up @@ -54,6 +55,7 @@

[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId

[Depex]
gEfiAcpiTableProtocolGuid
117 changes: 117 additions & 0 deletions OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/** @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;
}
5 changes: 5 additions & 0 deletions OvmfPkg/Include/IndustryStandard/CloudHv.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,9 @@
//
#define CLOUDHV_SMBIOS_ADDRESS 0xf0000

//
// RSDP address
//
#define CLOUDHV_RSDP_ADDRESS 0xa0000

#endif // __CLOUDHV_H__

0 comments on commit 003998b

Please sign in to comment.