]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/XenPlatformPei/MemDetect.c
OvmfPkg/XenPlatformPei: Use CPUID to get physical address width on Xen
[mirror_edk2.git] / OvmfPkg / XenPlatformPei / MemDetect.c
index 1f81eee4074c207c2b32da91e783a17d73969ef3..1970b631c94d32fdec7fca547ff027f75340f50f 100644 (file)
@@ -172,175 +172,33 @@ GetSystemMemorySizeBelow4gb (
   return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);\r
 }\r
 \r
-\r
-STATIC\r
-UINT64\r
-GetSystemMemorySizeAbove4gb (\r
-  )\r
-{\r
-  UINT32 Size;\r
-  UINTN  CmosIndex;\r
-\r
-  //\r
-  // In PVH case, there is no CMOS, we have to calculate the memory size\r
-  // from parsing the E820\r
-  //\r
-  if (XenPvhDetected ()) {\r
-    UINT64  HighestAddress;\r
-\r
-    HighestAddress = GetHighestSystemMemoryAddress (FALSE);\r
-    ASSERT (HighestAddress == 0 || HighestAddress >= BASE_4GB);\r
-\r
-    if (HighestAddress >= BASE_4GB) {\r
-      HighestAddress -= BASE_4GB;\r
-    }\r
-\r
-    return HighestAddress;\r
-  }\r
-\r
-  //\r
-  // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.\r
-  // * CMOS(0x5d) is the most significant size byte\r
-  // * CMOS(0x5c) is the middle size byte\r
-  // * CMOS(0x5b) is the least significant size byte\r
-  // * The size is specified in 64kb chunks\r
-  //\r
-\r
-  Size = 0;\r
-  for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {\r
-    Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);\r
-  }\r
-\r
-  return LShiftU64 (Size, 16);\r
-}\r
-\r
-\r
-/**\r
-  Return the highest address that DXE could possibly use, plus one.\r
-**/\r
-STATIC\r
-UINT64\r
-GetFirstNonAddress (\r
-  VOID\r
-  )\r
-{\r
-  UINT64               FirstNonAddress;\r
-  UINT64               Pci64Base, Pci64Size;\r
-  RETURN_STATUS        PcdStatus;\r
-\r
-  FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();\r
-\r
-  //\r
-  // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO\r
-  // resources to 32-bit anyway. See DegradeResource() in\r
-  // "PciResourceSupport.c".\r
-  //\r
-#ifdef MDE_CPU_IA32\r
-  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
-    return FirstNonAddress;\r
-  }\r
-#endif\r
-\r
-  //\r
-  // Otherwise, in order to calculate the highest address plus one, we must\r
-  // consider the 64-bit PCI host aperture too. Fetch the default size.\r
-  //\r
-  Pci64Size = PcdGet64 (PcdPciMmio64Size);\r
-\r
-  if (Pci64Size == 0) {\r
-    if (mBootMode != BOOT_ON_S3_RESUME) {\r
-      DEBUG ((DEBUG_INFO, "%a: disabling 64-bit PCI host aperture\n",\r
-        __FUNCTION__));\r
-      PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);\r
-      ASSERT_RETURN_ERROR (PcdStatus);\r
-    }\r
-\r
-    //\r
-    // There's nothing more to do; the amount of memory above 4GB fully\r
-    // determines the highest address plus one. The memory hotplug area (see\r
-    // below) plays no role for the firmware in this case.\r
-    //\r
-    return FirstNonAddress;\r
-  }\r
-\r
-  //\r
-  // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so\r
-  // that the host can map it with 1GB hugepages. Follow suit.\r
-  //\r
-  Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);\r
-  Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);\r
-\r
-  //\r
-  // The 64-bit PCI host aperture should also be "naturally" aligned. The\r
-  // alignment is determined by rounding the size of the aperture down to the\r
-  // next smaller or equal power of two. That is, align the aperture by the\r
-  // largest BAR size that can fit into it.\r
-  //\r
-  Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));\r
-\r
-  if (mBootMode != BOOT_ON_S3_RESUME) {\r
-    //\r
-    // The core PciHostBridgeDxe driver will automatically add this range to\r
-    // the GCD memory space map through our PciHostBridgeLib instance; here we\r
-    // only need to set the PCDs.\r
-    //\r
-    PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base);\r
-    ASSERT_RETURN_ERROR (PcdStatus);\r
-    PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size);\r
-    ASSERT_RETURN_ERROR (PcdStatus);\r
-\r
-    DEBUG ((DEBUG_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",\r
-      __FUNCTION__, Pci64Base, Pci64Size));\r
-  }\r
-\r
-  //\r
-  // The useful address space ends with the 64-bit PCI host aperture.\r
-  //\r
-  FirstNonAddress = Pci64Base + Pci64Size;\r
-  return FirstNonAddress;\r
-}\r
-\r
-\r
 /**\r
-  Initialize the mPhysMemAddressWidth variable, based on guest RAM size.\r
+  Initialize the mPhysMemAddressWidth variable, based on CPUID data.\r
 **/\r
 VOID\r
 AddressWidthInitialization (\r
   VOID\r
   )\r
 {\r
-  UINT64 FirstNonAddress;\r
+  UINT32 RegEax;\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
-  // The DXL IPL keys off of the physical address bits advertized in the CPU\r
-  // HOB. To conserve memory, we calculate the minimum address width here.\r
-  //\r
-  FirstNonAddress      = GetFirstNonAddress ();\r
-  mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);\r
-\r
-  //\r
-  // If FirstNonAddress is not an integral power of two, then we need an\r
-  // additional bit.\r
-  //\r
-  if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {\r
-    ++mPhysMemAddressWidth;\r
+  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+  if (RegEax >= 0x80000008) {\r
+    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+    mPhysMemAddressWidth = (UINT8) RegEax;\r
+  } else {\r
+    mPhysMemAddressWidth = 36;\r
   }\r
 \r
   //\r
-  // The minimum address width is 36 (covers up to and excluding 64 GB, which\r
-  // is the maximum for Ia32 + PAE). The theoretical architecture maximum for\r
-  // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We\r
-  // can simply assert that here, since 48 bits are good enough for 256 TB.\r
+  // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
   //\r
-  if (mPhysMemAddressWidth <= 36) {\r
-    mPhysMemAddressWidth = 36;\r
+  ASSERT (mPhysMemAddressWidth <= 52);\r
+  if (mPhysMemAddressWidth > 48) {\r
+    mPhysMemAddressWidth = 48;\r
   }\r
-  ASSERT (mPhysMemAddressWidth <= 48);\r
 }\r
 \r
-\r
 /**\r
   Calculate the cap for the permanent PEI memory.\r
 **/\r