Skip to content

Commit e6ea146

Browse files
ardbiesheuvelmergify[bot]
authored andcommitted
OvmfPkg/PlatformPei: Revert "stop using cmos for memory detection"
This reverts commit 41d8bb3, as it breaks Cloud Hypervisor. Reported-by: Sebastien Boeuf <sebastien.boeuf@intel.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 4de8d61 commit e6ea146

File tree

1 file changed

+55
-4
lines changed

1 file changed

+55
-4
lines changed

OvmfPkg/PlatformPei/MemDetect.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Module Name:
3838
#include <Library/QemuFwCfgSimpleParserLib.h>
3939

4040
#include "Platform.h"
41+
#include "Cmos.h"
4142

4243
UINT8 mPhysMemAddressWidth;
4344

@@ -321,11 +322,51 @@ GetSystemMemorySizeBelow4gb (
321322
{
322323
EFI_STATUS Status;
323324
UINT64 LowerMemorySize = 0;
325+
UINT8 Cmos0x34;
326+
UINT8 Cmos0x35;
324327

325328
Status = ScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL);
326-
ASSERT_EFI_ERROR (Status);
327-
ASSERT (LowerMemorySize > 0);
328-
return (UINT32)LowerMemorySize;
329+
if ((Status == EFI_SUCCESS) && (LowerMemorySize > 0)) {
330+
return (UINT32)LowerMemorySize;
331+
}
332+
333+
//
334+
// CMOS 0x34/0x35 specifies the system memory above 16 MB.
335+
// * CMOS(0x35) is the high byte
336+
// * CMOS(0x34) is the low byte
337+
// * The size is specified in 64kb chunks
338+
// * Since this is memory above 16MB, the 16MB must be added
339+
// into the calculation to get the total memory size.
340+
//
341+
342+
Cmos0x34 = (UINT8)CmosRead8 (0x34);
343+
Cmos0x35 = (UINT8)CmosRead8 (0x35);
344+
345+
return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
346+
}
347+
348+
STATIC
349+
UINT64
350+
GetSystemMemorySizeAbove4gb (
351+
)
352+
{
353+
UINT32 Size;
354+
UINTN CmosIndex;
355+
356+
//
357+
// CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
358+
// * CMOS(0x5d) is the most significant size byte
359+
// * CMOS(0x5c) is the middle size byte
360+
// * CMOS(0x5b) is the least significant size byte
361+
// * The size is specified in 64kb chunks
362+
//
363+
364+
Size = 0;
365+
for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
366+
Size = (UINT32)(Size << 8) + (UINT32)CmosRead8 (CmosIndex);
367+
}
368+
369+
return LShiftU64 (Size, 16);
329370
}
330371

331372
/**
@@ -355,9 +396,12 @@ GetFirstNonAddress (
355396
// If QEMU presents an E820 map, then get the highest exclusive >=4GB RAM
356397
// address from it. This can express an address >= 4GB+1TB.
357398
//
399+
// Otherwise, get the flat size of the memory above 4GB from the CMOS (which
400+
// can only express a size smaller than 1TB), and add it to 4GB.
401+
//
358402
Status = ScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);
359403
if (EFI_ERROR (Status)) {
360-
FirstNonAddress = BASE_4GB;
404+
FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
361405
}
362406

363407
//
@@ -729,6 +773,7 @@ QemuInitializeRam (
729773
)
730774
{
731775
UINT64 LowerMemorySize;
776+
UINT64 UpperMemorySize;
732777
MTRR_SETTINGS MtrrSettings;
733778
EFI_STATUS Status;
734779

@@ -787,6 +832,12 @@ QemuInitializeRam (
787832
// memory size read from the CMOS.
788833
//
789834
Status = ScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
835+
if (EFI_ERROR (Status)) {
836+
UpperMemorySize = GetSystemMemorySizeAbove4gb ();
837+
if (UpperMemorySize != 0) {
838+
AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
839+
}
840+
}
790841
}
791842

792843
//

0 commit comments

Comments
 (0)