]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/Microvm/pcie: mPhysMemAddressWidth tweak
authorGerd Hoffmann <kraxel@redhat.com>
Thu, 2 Jun 2022 08:42:15 +0000 (10:42 +0200)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 3 Jun 2022 09:06:44 +0000 (09:06 +0000)
microvm places the 64bit mmio space at the end of the physical address
space.  So mPhysMemAddressWidth must be correct, otherwise the pci host
bridge setup throws an error because it thinks the 64bit mmio window is
not addressable.

On microvm we can simply use standard cpuid to figure the address width
because the host-phys-bits option (-cpu ${name},host-phys-bits=on) is
forced to be enabled.  Side note: For 'pc' and 'q35' this is not the
case for backward compatibility reasons.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
OvmfPkg/Library/PlatformInitLib/MemDetect.c
OvmfPkg/PlatformPei/Platform.c

index 83a7b6726bb74ae941aac289be64c5127d456950..c28d7601f87ebc37ccd083ac2d06be31bc917494 100644 (file)
@@ -491,6 +491,42 @@ PlatformGetFirstNonAddress (
   return FirstNonAddress;\r
 }\r
 \r
+/*\r
+ * Use CPUID to figure physical address width.  Does *not* work\r
+ * reliable on qemu.  For historical reasons qemu returns phys-bits=40\r
+ * even in case the host machine supports less than that.\r
+ *\r
+ * qemu has a cpu property (host-phys-bits={on,off}) to change that\r
+ * and make sure guest phys-bits are not larger than host phys-bits.,\r
+ * but it is off by default.  Exception: microvm machine type\r
+ * hard-wires that property to on.\r
+ */\r
+VOID\r
+EFIAPI\r
+PlatformAddressWidthFromCpuid (\r
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob\r
+  )\r
+{\r
+  UINT32  RegEax;\r
+\r
+  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+  if (RegEax >= 0x80000008) {\r
+    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+    PlatformInfoHob->PhysMemAddressWidth = (UINT8)RegEax;\r
+  } else {\r
+    PlatformInfoHob->PhysMemAddressWidth = 36;\r
+  }\r
+\r
+  PlatformInfoHob->FirstNonAddress = LShiftU64 (1, PlatformInfoHob->PhysMemAddressWidth);\r
+\r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "%a: cpuid: phys-bits is %d\n",\r
+    __FUNCTION__,\r
+    PlatformInfoHob->PhysMemAddressWidth\r
+    ));\r
+}\r
+\r
 /**\r
   Initialize the PhysMemAddressWidth field in PlatformInfoHob based on guest RAM size.\r
 **/\r
@@ -503,6 +539,11 @@ PlatformAddressWidthInitialization (
   UINT64  FirstNonAddress;\r
   UINT8   PhysMemAddressWidth;\r
 \r
+  if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {\r
+    PlatformAddressWidthFromCpuid (PlatformInfoHob);\r
+    return;\r
+  }\r
+\r
   //\r
   // As guest-physical memory size grows, the permanent PEI RAM requirements\r
   // are dominated by the identity-mapping page tables built by the DXE IPL.\r
index f006755d5fdb2f6364711bf40b5e2bb12a70c62b..009db67ee60ad8b426ca880e36a752e4ad025ffd 100644 (file)
@@ -357,12 +357,12 @@ InitializePlatform (
 \r
   S3Verification ();\r
   BootModeInitialization (&mPlatformInfoHob);\r
-  AddressWidthInitialization (&mPlatformInfoHob);\r
 \r
   //\r
   // Query Host Bridge DID\r
   //\r
   mPlatformInfoHob.HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);\r
+  AddressWidthInitialization (&mPlatformInfoHob);\r
 \r
   MaxCpuCountInitialization (&mPlatformInfoHob);\r
 \r