Browse Source

OvmfPkg: Handle Cloud Hypervisor host bridge

Handle things differently when the detected host bridge matches the
Cloud Hypervisor PCI host bridge identifier.

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>
Sebastien Boeuf 2 years ago
parent
commit
9afcd48a94

+ 36 - 0
OvmfPkg/Include/IndustryStandard/CloudHv.h

@@ -0,0 +1,36 @@
+/** @file
+  Various defines related to Cloud Hypervisor
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __CLOUDHV_H__
+#define __CLOUDHV_H__
+
+//
+// Host Bridge Device ID
+//
+#define CLOUDHV_DEVICE_ID  0x0d57
+
+//
+// ACPI timer address
+//
+#define CLOUDHV_ACPI_TIMER_IO_ADDRESS  0xb008
+
+//
+// ACPI shutdown device address
+//
+#define CLOUDHV_ACPI_SHUTDOWN_IO_ADDRESS  0x03c0
+
+//
+// 32-bit MMIO memory hole base address
+//
+#define CLOUDHV_MMIO_HOLE_ADDRESS  0xc0000000
+
+//
+// 32-bit MMIO memory hole size
+//
+#define CLOUDHV_MMIO_HOLE_SIZE  0x38000000
+
+#endif // __CLOUDHV_H__

+ 1 - 0
OvmfPkg/Include/OvmfPlatforms.h

@@ -16,6 +16,7 @@
 #include <IndustryStandard/I440FxPiix4.h>
 #include <IndustryStandard/Bhyve.h>
 #include <IndustryStandard/Microvm.h>
+#include <IndustryStandard/CloudHv.h>
 
 //
 // OVMF Host Bridge DID Address

+ 3 - 0
OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c

@@ -55,6 +55,9 @@ AcpiTimerLibConstructor (
       AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
       AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
       break;
+    case CLOUDHV_DEVICE_ID:
+      mAcpiTimerIoAddr =  CLOUDHV_ACPI_TIMER_IO_ADDRESS;
+      return RETURN_SUCCESS;
     default:
       DEBUG ((
         DEBUG_ERROR,

+ 4 - 0
OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.c

@@ -53,6 +53,8 @@ AcpiTimerLibConstructor (
       AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
       AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
       break;
+    case CLOUDHV_DEVICE_ID:
+      return RETURN_SUCCESS;
     default:
       DEBUG ((
         DEBUG_ERROR,
@@ -111,6 +113,8 @@ InternalAcpiGetTimerTick (
     case INTEL_Q35_MCH_DEVICE_ID:
       Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
       break;
+    case CLOUDHV_DEVICE_ID:
+      return IoRead32 (CLOUDHV_ACPI_TIMER_IO_ADDRESS);
     default:
       DEBUG ((
         DEBUG_ERROR,

+ 3 - 0
OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c

@@ -50,6 +50,9 @@ AcpiTimerLibConstructor (
     case INTEL_Q35_MCH_DEVICE_ID:
       Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
       break;
+    case CLOUDHV_DEVICE_ID:
+      mAcpiTimerIoAddr = CLOUDHV_ACPI_TIMER_IO_ADDRESS;
+      return RETURN_SUCCESS;
     default:
       DEBUG ((
         DEBUG_ERROR,

+ 1 - 0
OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c

@@ -1390,6 +1390,7 @@ PciAcpiInitialization (
       PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), PciHostIrqs[3]); // H
       break;
     case MICROVM_PSEUDO_DEVICE_ID:
+    case CLOUDHV_DEVICE_ID:
       return;
     default:
       if (XenDetected ()) {

+ 3 - 0
OvmfPkg/Library/ResetSystemLib/BaseResetShutdown.c

@@ -40,6 +40,9 @@ ResetShutdown (
     case INTEL_Q35_MCH_DEVICE_ID:
       AcpiPmBaseAddress = ICH9_PMBASE_VALUE;
       break;
+    case CLOUDHV_DEVICE_ID:
+      IoWrite8 (CLOUDHV_ACPI_SHUTDOWN_IO_ADDRESS, 5 << 2 | 1 << 5);
+      CpuDeadLoop ();
     default:
       ASSERT (FALSE);
       CpuDeadLoop ();

+ 11 - 2
OvmfPkg/Library/ResetSystemLib/DxeResetShutdown.c

@@ -16,6 +16,7 @@
 #include <OvmfPlatforms.h>          // PIIX4_PMBA_VALUE
 
 STATIC UINT16  mAcpiPmBaseAddress;
+STATIC UINT16  mAcpiHwReducedSleepCtl;
 
 EFI_STATUS
 EFIAPI
@@ -34,6 +35,9 @@ DxeResetInit (
     case INTEL_Q35_MCH_DEVICE_ID:
       mAcpiPmBaseAddress = ICH9_PMBASE_VALUE;
       break;
+    case CLOUDHV_DEVICE_ID:
+      mAcpiHwReducedSleepCtl = CLOUDHV_ACPI_SHUTDOWN_IO_ADDRESS;
+      break;
     default:
       ASSERT (FALSE);
       CpuDeadLoop ();
@@ -56,7 +60,12 @@ ResetShutdown (
   VOID
   )
 {
-  IoBitFieldWrite16 (mAcpiPmBaseAddress + 4, 10, 13, 0);
-  IoOr16 (mAcpiPmBaseAddress + 4, BIT13);
+  if (mAcpiHwReducedSleepCtl) {
+    IoWrite8 (mAcpiHwReducedSleepCtl, 5 << 2 | 1 << 5);
+  } else {
+    IoBitFieldWrite16 (mAcpiPmBaseAddress + 4, 10, 13, 0);
+    IoOr16 (mAcpiPmBaseAddress + 4, BIT13);
+  }
+
   CpuDeadLoop ();
 }

+ 8 - 1
OvmfPkg/PlatformPei/MemDetect.c

@@ -16,6 +16,7 @@ Module Name:
 #include <IndustryStandard/E820.h>
 #include <IndustryStandard/I440FxPiix4.h>
 #include <IndustryStandard/Q35MchIch9.h>
+#include <IndustryStandard/CloudHv.h>
 #include <PiPei.h>
 #include <Register/Intel/SmramSaveStateMap.h>
 
@@ -159,6 +160,12 @@ QemuUc32BaseInitialization (
     return;
   }
 
+  if (mHostBridgeDevId == CLOUDHV_DEVICE_ID) {
+    Uc32Size      = CLOUDHV_MMIO_HOLE_SIZE;
+    mQemuUc32Base = CLOUDHV_MMIO_HOLE_ADDRESS;
+    return;
+  }
+
   ASSERT (mHostBridgeDevId == INTEL_82441_DEVICE_ID);
   //
   // On i440fx, start with the [LowerMemorySize, 4GB) range. Make sure one
@@ -819,7 +826,7 @@ QemuInitializeRam (
   // practically any alignment, and we may not have enough variable MTRRs to
   // cover it exactly.
   //
-  if (IsMtrrSupported ()) {
+  if (IsMtrrSupported () && (mHostBridgeDevId != CLOUDHV_DEVICE_ID)) {
     MtrrGetAllMtrrs (&MtrrSettings);
 
     //

+ 8 - 0
OvmfPkg/PlatformPei/Platform.c

@@ -374,6 +374,14 @@ MiscInitialization (
                     );
       ASSERT_RETURN_ERROR (PcdStatus);
       return;
+    case CLOUDHV_DEVICE_ID:
+      DEBUG ((DEBUG_INFO, "%a: Cloud Hypervisor host bridge\n", __FUNCTION__));
+      PcdStatus = PcdSet16S (
+                    PcdOvmfHostBridgePciDevId,
+                    CLOUDHV_DEVICE_ID
+                    );
+      ASSERT_RETURN_ERROR (PcdStatus);
+      return;
     default:
       DEBUG ((
         DEBUG_ERROR,