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
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
\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