summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2021-12-15 17:48:58 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-12-15 18:03:26 +0000
commite6ea1464a846b3f012a9ca07d92924c2e1b88334 (patch)
treed90f021dddbb2f376eed30f30097c124cd102341
parent4de8d61bcec02a13ceed84f92b0cf3ea58adf9c5 (diff)
downloadedk2-e6ea1464a846b3f012a9ca07d92924c2e1b88334.tar.gz
edk2-e6ea1464a846b3f012a9ca07d92924c2e1b88334.tar.bz2
edk2-e6ea1464a846b3f012a9ca07d92924c2e1b88334.zip
OvmfPkg/PlatformPei: Revert "stop using cmos for memory detection"
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>
-rw-r--r--OvmfPkg/PlatformPei/MemDetect.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index fb38e3c39d..1bcb5a08bc 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -38,6 +38,7 @@ Module Name:
#include <Library/QemuFwCfgSimpleParserLib.h>
#include "Platform.h"
+#include "Cmos.h"
UINT8 mPhysMemAddressWidth;
@@ -321,11 +322,51 @@ GetSystemMemorySizeBelow4gb (
{
EFI_STATUS Status;
UINT64 LowerMemorySize = 0;
+ UINT8 Cmos0x34;
+ UINT8 Cmos0x35;
Status = ScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL);
- ASSERT_EFI_ERROR (Status);
- ASSERT (LowerMemorySize > 0);
- return (UINT32)LowerMemorySize;
+ if ((Status == EFI_SUCCESS) && (LowerMemorySize > 0)) {
+ return (UINT32)LowerMemorySize;
+ }
+
+ //
+ // CMOS 0x34/0x35 specifies the system memory above 16 MB.
+ // * CMOS(0x35) is the high byte
+ // * CMOS(0x34) is the low byte
+ // * The size is specified in 64kb chunks
+ // * Since this is memory above 16MB, the 16MB must be added
+ // into the calculation to get the total memory size.
+ //
+
+ Cmos0x34 = (UINT8)CmosRead8 (0x34);
+ Cmos0x35 = (UINT8)CmosRead8 (0x35);
+
+ return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
+}
+
+STATIC
+UINT64
+GetSystemMemorySizeAbove4gb (
+ )
+{
+ UINT32 Size;
+ UINTN CmosIndex;
+
+ //
+ // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
+ // * CMOS(0x5d) is the most significant size byte
+ // * CMOS(0x5c) is the middle size byte
+ // * CMOS(0x5b) is the least significant size byte
+ // * The size is specified in 64kb chunks
+ //
+
+ Size = 0;
+ for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
+ Size = (UINT32)(Size << 8) + (UINT32)CmosRead8 (CmosIndex);
+ }
+
+ return LShiftU64 (Size, 16);
}
/**
@@ -355,9 +396,12 @@ GetFirstNonAddress (
// If QEMU presents an E820 map, then get the highest exclusive >=4GB RAM
// address from it. This can express an address >= 4GB+1TB.
//
+ // Otherwise, get the flat size of the memory above 4GB from the CMOS (which
+ // can only express a size smaller than 1TB), and add it to 4GB.
+ //
Status = ScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);
if (EFI_ERROR (Status)) {
- FirstNonAddress = BASE_4GB;
+ FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
}
//
@@ -729,6 +773,7 @@ QemuInitializeRam (
)
{
UINT64 LowerMemorySize;
+ UINT64 UpperMemorySize;
MTRR_SETTINGS MtrrSettings;
EFI_STATUS Status;
@@ -787,6 +832,12 @@ QemuInitializeRam (
// memory size read from the CMOS.
//
Status = ScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ UpperMemorySize = GetSystemMemorySizeAbove4gb ();
+ if (UpperMemorySize != 0) {
+ AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
+ }
+ }
}
//