]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/PlatformPei: Revert "stop using cmos for memory detection"
authorArd Biesheuvel <ardb@kernel.org>
Wed, 15 Dec 2021 16:48:58 +0000 (17:48 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 15 Dec 2021 18:03:26 +0000 (18:03 +0000)
This reverts commit 41d8bb30386ceab55787fc9f5aac6434e2493e27, as it
breaks Cloud Hypervisor.

Reported-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
OvmfPkg/PlatformPei/MemDetect.c

index fb38e3c39d8ee49c09eb64b1100b6b1d63c8b467..1bcb5a08bca640e24ed1cf9ea0e81e7114f10328 100644 (file)
@@ -38,6 +38,7 @@ Module Name:
 #include <Library/QemuFwCfgSimpleParserLib.h>\r
 \r
 #include "Platform.h"\r
+#include "Cmos.h"\r
 \r
 UINT8  mPhysMemAddressWidth;\r
 \r
@@ -321,11 +322,51 @@ GetSystemMemorySizeBelow4gb (
 {\r
   EFI_STATUS  Status;\r
   UINT64      LowerMemorySize = 0;\r
+  UINT8       Cmos0x34;\r
+  UINT8       Cmos0x35;\r
 \r
   Status = ScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL);\r
-  ASSERT_EFI_ERROR (Status);\r
-  ASSERT (LowerMemorySize > 0);\r
-  return (UINT32)LowerMemorySize;\r
+  if ((Status == EFI_SUCCESS) && (LowerMemorySize > 0)) {\r
+    return (UINT32)LowerMemorySize;\r
+  }\r
+\r
+  //\r
+  // CMOS 0x34/0x35 specifies the system memory above 16 MB.\r
+  // * CMOS(0x35) is the high byte\r
+  // * CMOS(0x34) is the low byte\r
+  // * The size is specified in 64kb chunks\r
+  // * Since this is memory above 16MB, the 16MB must be added\r
+  //   into the calculation to get the total memory size.\r
+  //\r
+\r
+  Cmos0x34 = (UINT8)CmosRead8 (0x34);\r
+  Cmos0x35 = (UINT8)CmosRead8 (0x35);\r
+\r
+  return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);\r
+}\r
+\r
+STATIC\r
+UINT64\r
+GetSystemMemorySizeAbove4gb (\r
+  )\r
+{\r
+  UINT32  Size;\r
+  UINTN   CmosIndex;\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
@@ -355,9 +396,12 @@ GetFirstNonAddress (
   // If QEMU presents an E820 map, then get the highest exclusive >=4GB RAM\r
   // address from it. This can express an address >= 4GB+1TB.\r
   //\r
+  // Otherwise, get the flat size of the memory above 4GB from the CMOS (which\r
+  // can only express a size smaller than 1TB), and add it to 4GB.\r
+  //\r
   Status = ScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);\r
   if (EFI_ERROR (Status)) {\r
-    FirstNonAddress = BASE_4GB;\r
+    FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();\r
   }\r
 \r
   //\r
@@ -729,6 +773,7 @@ QemuInitializeRam (
   )\r
 {\r
   UINT64         LowerMemorySize;\r
+  UINT64         UpperMemorySize;\r
   MTRR_SETTINGS  MtrrSettings;\r
   EFI_STATUS     Status;\r
 \r
@@ -787,6 +832,12 @@ QemuInitializeRam (
     // memory size read from the CMOS.\r
     //\r
     Status = ScanOrAdd64BitE820Ram (TRUE, NULL, NULL);\r
+    if (EFI_ERROR (Status)) {\r
+      UpperMemorySize = GetSystemMemorySizeAbove4gb ();\r
+      if (UpperMemorySize != 0) {\r
+        AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);\r
+      }\r
+    }\r
   }\r
 \r
   //\r