]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Install ACPI tables for Cloud Hypervisor
authorSebastien Boeuf <sebastien.boeuf@intel.com>
Fri, 10 Dec 2021 14:41:58 +0000 (22:41 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sat, 11 Dec 2021 14:26:05 +0000 (14:26 +0000)
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>
OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c [new file with mode: 0644]
OvmfPkg/Include/IndustryStandard/CloudHv.h

index 274db2868500cf683a35046bcf5f9efc3e51966a..fcfb9703bd60e0bf7dffebd93ef9c72844bbbc18 100644 (file)
@@ -7,6 +7,8 @@
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 **/\r
 \r
+#include <OvmfPlatforms.h> // CLOUDHV_DEVICE_ID\r
+\r
 #include "AcpiPlatform.h"\r
 \r
 /**\r
@@ -27,7 +29,14 @@ InstallAcpiTables (
   )\r
 {\r
   EFI_STATUS  Status;\r
+  UINT16      HostBridgeDevId;\r
+\r
+  HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);\r
+  if (HostBridgeDevId == CLOUDHV_DEVICE_ID) {\r
+    Status = InstallCloudHvTables (AcpiTable);\r
+  } else {\r
+    Status = InstallQemuFwCfgTables (AcpiTable);\r
+  }\r
 \r
-  Status = InstallQemuFwCfgTables (AcpiTable);\r
   return Status;\r
 }\r
index 1ccca0a368c485bb90c7beee70f3e387ef7981ec..342339750ddb51e76ebf328f19c23115bacfd234 100644 (file)
@@ -19,6 +19,12 @@ typedef struct {
 \r
 typedef struct S3_CONTEXT S3_CONTEXT;\r
 \r
+EFI_STATUS\r
+EFIAPI\r
+InstallCloudHvTables (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL  *AcpiProtocol\r
+  );\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 InstallQemuFwCfgTables (\r
index eedd3b5af387580cac44419f563df5ab030a7a6b..b36b8413e007aa01afd1fe40739440a4af7b9476 100644 (file)
@@ -24,6 +24,7 @@
   AcpiPlatform.c\r
   AcpiPlatform.h\r
   BootScript.c\r
+  CloudHvAcpi.c\r
   EntryPoint.c\r
   PciDecoding.c\r
   QemuFwCfgAcpi.c\r
@@ -54,6 +55,7 @@
 \r
 [Pcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId\r
 \r
 [Depex]\r
   gEfiAcpiTableProtocolGuid\r
diff --git a/OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c b/OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
new file mode 100644 (file)
index 0000000..44a6bb7
--- /dev/null
@@ -0,0 +1,118 @@
+/** @file\r
+  OVMF ACPI Cloud Hypervisor support\r
+\r
+  Copyright (c) 2021, Intel Corporation. All rights reserved.\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <IndustryStandard/CloudHv.h> // CLOUDHV_RSDP_ADDRESS\r
+#include <Library/BaseLib.h>          // CpuDeadLoop()\r
+#include <Library/DebugLib.h>         // DEBUG()\r
+\r
+#include "AcpiPlatform.h"\r
+\r
+// Get the ACPI tables from EBDA start\r
+EFI_STATUS\r
+EFIAPI\r
+InstallCloudHvTables (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL  *AcpiProtocol\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       TableHandle;\r
+\r
+  EFI_ACPI_DESCRIPTION_HEADER                *Xsdt;\r
+  VOID                                       *CurrentTableEntry;\r
+  UINTN                                      CurrentTablePointer;\r
+  EFI_ACPI_DESCRIPTION_HEADER                *CurrentTable;\r
+  UINTN                                      Index;\r
+  UINTN                                      NumberOfTableEntries;\r
+  EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE  *Fadt2Table;\r
+  EFI_ACPI_DESCRIPTION_HEADER                *DsdtTable;\r
+\r
+  Fadt2Table           = NULL;\r
+  DsdtTable            = NULL;\r
+  TableHandle          = 0;\r
+  NumberOfTableEntries = 0;\r
+  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *AcpiRsdpStructurePtr = (VOID *)CLOUDHV_RSDP_ADDRESS;\r
+\r
+  // If XSDT table is found, just install its tables.\r
+  // Otherwise, try to find and install the RSDT tables.\r
+  //\r
+  if (AcpiRsdpStructurePtr->XsdtAddress) {\r
+    //\r
+    // Retrieve the addresses of XSDT and\r
+    // calculate the number of its table entries.\r
+    //\r
+    Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)\r
+           AcpiRsdpStructurePtr->XsdtAddress;\r
+    NumberOfTableEntries = (Xsdt->Length -\r
+                            sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
+                           sizeof (UINT64);\r
+\r
+    //\r
+    // Install ACPI tables found in XSDT.\r
+    //\r
+    for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
+      //\r
+      // Get the table entry from XSDT\r
+      //\r
+      CurrentTableEntry = (VOID *)((UINT8 *)Xsdt +\r
+                                   sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
+                                   Index * sizeof (UINT64));\r
+      CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry;\r
+      CurrentTable        = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer;\r
+\r
+      //\r
+      // Install the XSDT tables\r
+      //\r
+      Status = AcpiProtocol->InstallAcpiTable (\r
+                               AcpiProtocol,\r
+                               CurrentTable,\r
+                               CurrentTable->Length,\r
+                               &TableHandle\r
+                               );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ASSERT_EFI_ERROR (Status);\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Get the X-DSDT table address from the table FADT\r
+      //\r
+      if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) {\r
+        Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
+                     (UINTN)CurrentTablePointer;\r
+        DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt2Table->XDsdt;\r
+      }\r
+    }\r
+  } else {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Install DSDT table. If we reached this point without finding the DSDT,\r
+  // then we're out of sync with the hypervisor, and cannot continue.\r
+  //\r
+  if (DsdtTable == NULL) {\r
+    DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));\r
+    ASSERT (FALSE);\r
+    CpuDeadLoop ();\r
+  }\r
+\r
+  Status = AcpiProtocol->InstallAcpiTable (\r
+                           AcpiProtocol,\r
+                           DsdtTable,\r
+                           DsdtTable->Length,\r
+                           &TableHandle\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT_EFI_ERROR (Status);\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
index d31ecc9eec93738198f3c6e474b812147d53dfc8..86404cc97e492ad140ff97737faeadae8aa265eb 100644 (file)
@@ -38,4 +38,9 @@
 //\r
 #define CLOUDHV_SMBIOS_ADDRESS  0xf0000\r
 \r
+//\r
+// RSDP address\r
+//\r
+#define CLOUDHV_RSDP_ADDRESS  0xa0000\r
+\r
 #endif // __CLOUDHV_H__\r