OvmfPkg/PlatformInitLib: Add PlatformGetLowMemoryCB

Add PlatformGetLowMemoryCB() callback function for use with
PlatformScanE820().  It stores the low memory size in
PlatformInfoHob->LowMemory.  This replaces calls to
PlatformScanOrAdd64BitE820Ram() with non-NULL LowMemory.

Write any actions done (setting LowMemory) to the firmware log
with INFO loglevel.

Also change PlatformGetSystemMemorySizeBelow4gb() to likewise set
PlatformInfoHob->LowMemory instead of returning the value.  Update
all Callers to the new convention.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
Gerd Hoffmann 2023-01-17 13:16:26 +01:00 committed by mergify[bot]
parent e037530468
commit 124b765051
6 changed files with 60 additions and 33 deletions

View File

@ -26,6 +26,7 @@ typedef struct {
BOOLEAN Q35SmramAtDefaultSmbase; BOOLEAN Q35SmramAtDefaultSmbase;
UINT16 Q35TsegMbytes; UINT16 Q35TsegMbytes;
UINT32 LowMemory;
UINT64 FirstNonAddress; UINT64 FirstNonAddress;
UINT8 PhysMemAddressWidth; UINT8 PhysMemAddressWidth;
UINT32 Uc32Base; UINT32 Uc32Base;
@ -144,7 +145,7 @@ PlatformQemuUc32BaseInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
); );
UINT32 VOID
EFIAPI EFIAPI
PlatformGetSystemMemorySizeBelow4gb ( PlatformGetSystemMemorySizeBelow4gb (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob

View File

@ -42,7 +42,8 @@ ConstructSecHobList (
ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob)); ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob));
PlatformInfoHob.HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID); PlatformInfoHob.HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
LowMemorySize = PlatformGetSystemMemorySizeBelow4gb (&PlatformInfoHob); PlatformGetSystemMemorySizeBelow4gb (&PlatformInfoHob);
LowMemorySize = PlatformInfoHob.LowMemory;
ASSERT (LowMemorySize != 0); ASSERT (LowMemorySize != 0);
LowMemoryStart = FixedPcdGet32 (PcdOvmfDxeMemFvBase) + FixedPcdGet32 (PcdOvmfDxeMemFvSize); LowMemoryStart = FixedPcdGet32 (PcdOvmfDxeMemFvBase) + FixedPcdGet32 (PcdOvmfDxeMemFvSize);
LowMemorySize -= LowMemoryStart; LowMemorySize -= LowMemoryStart;

View File

@ -41,8 +41,7 @@ InitializePlatform (
EFI_HOB_PLATFORM_INFO *PlatformInfoHob EFI_HOB_PLATFORM_INFO *PlatformInfoHob
) )
{ {
UINT32 LowerMemorySize; VOID *VariableStore;
VOID *VariableStore;
DEBUG ((DEBUG_INFO, "InitializePlatform in Pei-less boot\n")); DEBUG ((DEBUG_INFO, "InitializePlatform in Pei-less boot\n"));
PlatformDebugDumpCmos (); PlatformDebugDumpCmos ();
@ -70,14 +69,14 @@ InitializePlatform (
PlatformInfoHob->PcdCpuBootLogicalProcessorNumber PlatformInfoHob->PcdCpuBootLogicalProcessorNumber
)); ));
LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob); PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
PlatformQemuUc32BaseInitialization (PlatformInfoHob); PlatformQemuUc32BaseInitialization (PlatformInfoHob);
DEBUG (( DEBUG ((
DEBUG_INFO, DEBUG_INFO,
"Uc32Base = 0x%x, Uc32Size = 0x%x, LowerMemorySize = 0x%x\n", "Uc32Base = 0x%x, Uc32Size = 0x%x, LowerMemorySize = 0x%x\n",
PlatformInfoHob->Uc32Base, PlatformInfoHob->Uc32Base,
PlatformInfoHob->Uc32Size, PlatformInfoHob->Uc32Size,
LowerMemorySize PlatformInfoHob->LowMemory
)); ));
VariableStore = PlatformReserveEmuVariableNvStore (); VariableStore = PlatformReserveEmuVariableNvStore ();

View File

@ -51,18 +51,16 @@ PlatformQemuUc32BaseInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
) )
{ {
UINT32 LowerMemorySize;
if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) { if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
return; return;
} }
if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) { if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob); PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
ASSERT (PcdGet64 (PcdPciExpressBaseAddress) <= MAX_UINT32); ASSERT (PcdGet64 (PcdPciExpressBaseAddress) <= MAX_UINT32);
ASSERT (PcdGet64 (PcdPciExpressBaseAddress) >= LowerMemorySize); ASSERT (PcdGet64 (PcdPciExpressBaseAddress) >= PlatformInfoHob->LowMemory);
if (LowerMemorySize <= BASE_2GB) { if (PlatformInfoHob->LowMemory <= BASE_2GB) {
// Newer qemu with gigabyte aligned memory, // Newer qemu with gigabyte aligned memory,
// 32-bit pci mmio window is 2G -> 4G then. // 32-bit pci mmio window is 2G -> 4G then.
PlatformInfoHob->Uc32Base = BASE_2GB; PlatformInfoHob->Uc32Base = BASE_2GB;
@ -92,8 +90,8 @@ PlatformQemuUc32BaseInitialization (
// variable MTRR suffices by truncating the size to a whole power of two, // variable MTRR suffices by truncating the size to a whole power of two,
// while keeping the end affixed to 4GB. This will round the base up. // while keeping the end affixed to 4GB. This will round the base up.
// //
LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob); PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
PlatformInfoHob->Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize)); PlatformInfoHob->Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - PlatformInfoHob->LowMemory));
PlatformInfoHob->Uc32Base = (UINT32)(SIZE_4GB - PlatformInfoHob->Uc32Size); PlatformInfoHob->Uc32Base = (UINT32)(SIZE_4GB - PlatformInfoHob->Uc32Size);
// //
// Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB. // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB.
@ -101,13 +99,13 @@ PlatformQemuUc32BaseInitialization (
// //
ASSERT (PlatformInfoHob->Uc32Base >= BASE_2GB); ASSERT (PlatformInfoHob->Uc32Base >= BASE_2GB);
if (PlatformInfoHob->Uc32Base != LowerMemorySize) { if (PlatformInfoHob->Uc32Base != PlatformInfoHob->LowMemory) {
DEBUG (( DEBUG ((
DEBUG_VERBOSE, DEBUG_VERBOSE,
"%a: rounded UC32 base from 0x%x up to 0x%x, for " "%a: rounded UC32 base from 0x%x up to 0x%x, for "
"an UC32 size of 0x%x\n", "an UC32 size of 0x%x\n",
__FUNCTION__, __FUNCTION__,
LowerMemorySize, PlatformInfoHob->LowMemory,
PlatformInfoHob->Uc32Base, PlatformInfoHob->Uc32Base,
PlatformInfoHob->Uc32Size PlatformInfoHob->Uc32Size
)); ));
@ -280,6 +278,34 @@ PlatformGetFirstNonAddressCB (
} }
} }
/**
Store the low (below 4G) memory size in
PlatformInfoHob->LowMemory
**/
STATIC
VOID
PlatformGetLowMemoryCB (
IN EFI_E820_ENTRY64 *E820Entry,
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
UINT64 Candidate;
if (E820Entry->Type != EfiAcpiAddressRangeMemory) {
return;
}
Candidate = E820Entry->BaseAddr + E820Entry->Length;
if (Candidate >= BASE_4GB) {
return;
}
if (PlatformInfoHob->LowMemory < Candidate) {
DEBUG ((DEBUG_INFO, "%a: LowMemory=0x%Lx\n", __FUNCTION__, Candidate));
PlatformInfoHob->LowMemory = (UINT32)Candidate;
}
}
/** /**
Iterate over the entries in QEMU's fw_cfg E820 RAM map, call the Iterate over the entries in QEMU's fw_cfg E820 RAM map, call the
passed callback for each entry. passed callback for each entry.
@ -396,14 +422,13 @@ GetHighestSystemMemoryAddressFromPvhMemmap (
return HighestAddress; return HighestAddress;
} }
UINT32 VOID
EFIAPI EFIAPI
PlatformGetSystemMemorySizeBelow4gb ( PlatformGetSystemMemorySizeBelow4gb (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT64 LowerMemorySize = 0;
UINT8 Cmos0x34; UINT8 Cmos0x34;
UINT8 Cmos0x35; UINT8 Cmos0x35;
@ -411,12 +436,13 @@ PlatformGetSystemMemorySizeBelow4gb (
(CcProbe () != CcGuestTypeIntelTdx)) (CcProbe () != CcGuestTypeIntelTdx))
{ {
// Get the information from PVH memmap // Get the information from PVH memmap
return (UINT32)GetHighestSystemMemoryAddressFromPvhMemmap (TRUE); PlatformInfoHob->LowMemory = (UINT32)GetHighestSystemMemoryAddressFromPvhMemmap (TRUE);
return;
} }
Status = PlatformScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL); Status = PlatformScanE820 (PlatformGetLowMemoryCB, PlatformInfoHob);
if ((Status == EFI_SUCCESS) && (LowerMemorySize > 0)) { if (!EFI_ERROR (Status) && (PlatformInfoHob->LowMemory > 0)) {
return (UINT32)LowerMemorySize; return;
} }
// //
@ -431,7 +457,7 @@ PlatformGetSystemMemorySizeBelow4gb (
Cmos0x34 = (UINT8)PlatformCmosRead8 (0x34); Cmos0x34 = (UINT8)PlatformCmosRead8 (0x34);
Cmos0x35 = (UINT8)PlatformCmosRead8 (0x35); Cmos0x35 = (UINT8)PlatformCmosRead8 (0x35);
return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); PlatformInfoHob->LowMemory = (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
} }
STATIC STATIC
@ -967,7 +993,6 @@ PlatformQemuInitializeRam (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
) )
{ {
UINT64 LowerMemorySize;
UINT64 UpperMemorySize; UINT64 UpperMemorySize;
MTRR_SETTINGS MtrrSettings; MTRR_SETTINGS MtrrSettings;
EFI_STATUS Status; EFI_STATUS Status;
@ -977,7 +1002,7 @@ PlatformQemuInitializeRam (
// //
// Determine total memory size available // Determine total memory size available
// //
LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob); PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
if (PlatformInfoHob->BootMode == BOOT_ON_S3_RESUME) { if (PlatformInfoHob->BootMode == BOOT_ON_S3_RESUME) {
// //
@ -1011,14 +1036,14 @@ PlatformQemuInitializeRam (
UINT32 TsegSize; UINT32 TsegSize;
TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB; TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize); PlatformAddMemoryRangeHob (BASE_1MB, PlatformInfoHob->LowMemory - TsegSize);
PlatformAddReservedMemoryBaseSizeHob ( PlatformAddReservedMemoryBaseSizeHob (
LowerMemorySize - TsegSize, PlatformInfoHob->LowMemory - TsegSize,
TsegSize, TsegSize,
TRUE TRUE
); );
} else { } else {
PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize); PlatformAddMemoryRangeHob (BASE_1MB, PlatformInfoHob->LowMemory);
} }
// //
@ -1196,9 +1221,10 @@ PlatformQemuInitializeRamForS3 (
// Make sure the TSEG area that we reported as a reserved memory resource // Make sure the TSEG area that we reported as a reserved memory resource
// cannot be used for reserved memory allocations. // cannot be used for reserved memory allocations.
// //
PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB; TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
BuildMemoryAllocationHob ( BuildMemoryAllocationHob (
PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob) - TsegSize, PlatformInfoHob->LowMemory - TsegSize,
TsegSize, TsegSize,
EfiReservedMemoryType EfiReservedMemoryType
); );

View File

@ -128,7 +128,6 @@ PlatformMemMapInitialization (
{ {
UINT64 PciIoBase; UINT64 PciIoBase;
UINT64 PciIoSize; UINT64 PciIoSize;
UINT32 TopOfLowRam;
UINT64 PciExBarBase; UINT64 PciExBarBase;
UINT32 PciBase; UINT32 PciBase;
UINT32 PciSize; UINT32 PciSize;
@ -150,7 +149,7 @@ PlatformMemMapInitialization (
return; return;
} }
TopOfLowRam = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob); PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
PciExBarBase = 0; PciExBarBase = 0;
if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) { if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
// //
@ -158,11 +157,11 @@ PlatformMemMapInitialization (
// the base of the 32-bit PCI host aperture. // the base of the 32-bit PCI host aperture.
// //
PciExBarBase = PcdGet64 (PcdPciExpressBaseAddress); PciExBarBase = PcdGet64 (PcdPciExpressBaseAddress);
ASSERT (TopOfLowRam <= PciExBarBase); ASSERT (PlatformInfoHob->LowMemory <= PciExBarBase);
ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB); ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
PciBase = (UINT32)(PciExBarBase + SIZE_256MB); PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
} else { } else {
ASSERT (TopOfLowRam <= PlatformInfoHob->Uc32Base); ASSERT (PlatformInfoHob->LowMemory <= PlatformInfoHob->Uc32Base);
PciBase = PlatformInfoHob->Uc32Base; PciBase = PlatformInfoHob->Uc32Base;
} }

View File

@ -271,7 +271,8 @@ PublishPeiMemory (
UINT32 S3AcpiReservedMemoryBase; UINT32 S3AcpiReservedMemoryBase;
UINT32 S3AcpiReservedMemorySize; UINT32 S3AcpiReservedMemorySize;
LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob); PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
LowerMemorySize = PlatformInfoHob->LowMemory;
if (PlatformInfoHob->SmmSmramRequire) { if (PlatformInfoHob->SmmSmramRequire) {
// //
// TSEG is chipped from the end of low RAM // TSEG is chipped from the end of low RAM