OvmfPkg: PlatformPei: Add PEI Memory Bin Support

This commit enables PEI memory bins in OVMF IA32X64 and
OVMF X64.

OVMF supports many different boot flows. The variable PEIM
is only dispatched when SMM_REQUIRE is TRUE. The early variable
store is not set up otherwise.

The PlatformPei PEIM requires the variable PPI be available
before creating the gEfiMemoryTypeInformationGuid HOB, in order
to use the BDS advertised bin sizes. If SMM_REQUIRE is FALSE,
it just produces the HOB.

PEI Core requires that the gEfiMemoryTypeInformationGuid HOB be
produced pre-mem PEI in order to set up the memory bins at the
start of post-mem PEI. PlatformPei is also the PEIM that installs
permanent memory.

As such, a depex on the variable PPI cannot be used, to support
the different flows. So, this commit splits the PlatformPei
initialization flow into two phases. The first phase completes
until memory bin initialization. If that returns success (either
because SMM_REQUIRE is FALSE or because the variable PPI was
already installed), phase 2 init is completed immediately and
no callback is created. If that fails, a callback is created
for the variable read PPI and phase 2 initialization is completed
after that.

Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
This commit is contained in:
Oliver Smith-Denny 2026-01-29 10:12:40 -08:00 committed by mergify[bot]
parent 1b39cb1d81
commit efc3d6a417
5 changed files with 89 additions and 38 deletions

View file

@ -497,6 +497,7 @@
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootSupported|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdRequireSelfSignedPk|FALSE
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiMemoryBinsEnable|TRUE
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1

View file

@ -577,6 +577,7 @@
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootSupported|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdRequireSelfSignedPk|FALSE
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiMemoryBinsEnable|TRUE
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1

View file

@ -183,10 +183,15 @@ OnReadOnlyVariable2Available (
IN VOID *Ppi
)
{
EFI_HOB_GUID_TYPE *GuidHob;
DEBUG ((DEBUG_VERBOSE, "%a\n", __func__));
RefreshMemTypeInfo (Ppi);
BuildMemTypeInfoHob ();
GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);
CompleteInitialization ((EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob), (CONST EFI_PEI_SERVICES **)PeiServices);
return EFI_SUCCESS;
}
@ -201,12 +206,13 @@ STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mReadOnlyVariable2Notify = {
OnReadOnlyVariable2Available // Notify
};
VOID
EFI_STATUS
MemTypeInfoInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
EFI_STATUS Status;
EFI_STATUS Status;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
if (!PlatformInfoHob->SmmSmramRequire) {
//
@ -214,7 +220,23 @@ MemTypeInfoInitialization (
// the default memory type information HOB right away.
//
BuildMemTypeInfoHob ();
return;
return EFI_SUCCESS;
}
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **)&ReadOnlyVariable2
);
if (!EFI_ERROR (Status)) {
//
// EFI_PEI_READ_ONLY_VARIABLE2_PPI is already available; use it now.
//
RefreshMemTypeInfo (ReadOnlyVariable2);
BuildMemTypeInfoHob ();
return EFI_SUCCESS;
}
Status = PeiServicesNotifyPpi (&mReadOnlyVariable2Notify);
@ -228,4 +250,7 @@ MemTypeInfoInitialization (
ASSERT (FALSE);
CpuDeadLoop ();
}
// Return that we're not ready yet so that the dispatcher can dispatch the variable PEIM first
return EFI_NOT_READY;
}

View file

@ -294,6 +294,50 @@ BuildPlatformInfoHob (
return (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob);
}
VOID
CompleteInitialization (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
PublishPeiMemory (PlatformInfoHob);
PlatformQemuUc32BaseInitialization (PlatformInfoHob);
InitializeRamRegions (PlatformInfoHob);
if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
PeiFvInitialization (PlatformInfoHob);
MemMapInitialization (PlatformInfoHob);
NoexecDxeInitialization (PlatformInfoHob);
}
InstallClearCacheCallback ();
AmdSevInitialize (PlatformInfoHob);
if (PlatformInfoHob->HostBridgeDevId == 0xffff) {
MiscInitializationForMicrovm (PlatformInfoHob);
} else {
MiscInitialization (PlatformInfoHob);
PlatformIdInitialization (PeiServices);
}
IntelTdxInitialize ();
InstallFeatureControlCallback (PlatformInfoHob);
if (PlatformInfoHob->SmmSmramRequire) {
RelocateSmBase ();
}
//
// Performed after CoCo (SEV/TDX) initialization to allow the memory
// used to be validated before being used.
//
if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
if (!PlatformInfoHob->SmmSmramRequire) {
ReserveEmuVariableNvStore ();
}
}
}
/**
Perform Platform PEI initialization.
@ -357,43 +401,17 @@ InitializePlatform (
Q35SmramAtDefaultSmbaseInitialization (PlatformInfoHob);
}
PublishPeiMemory (PlatformInfoHob);
PlatformQemuUc32BaseInitialization (PlatformInfoHob);
InitializeRamRegions (PlatformInfoHob);
if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
PeiFvInitialization (PlatformInfoHob);
MemTypeInfoInitialization (PlatformInfoHob);
MemMapInitialization (PlatformInfoHob);
NoexecDxeInitialization (PlatformInfoHob);
}
InstallClearCacheCallback ();
AmdSevInitialize (PlatformInfoHob);
if (PlatformInfoHob->HostBridgeDevId == 0xffff) {
MiscInitializationForMicrovm (PlatformInfoHob);
} else {
MiscInitialization (PlatformInfoHob);
PlatformIdInitialization (PeiServices);
}
IntelTdxInitialize ();
InstallFeatureControlCallback (PlatformInfoHob);
if (PlatformInfoHob->SmmSmramRequire) {
RelocateSmBase ();
}
//
// Performed after CoCo (SEV/TDX) initialization to allow the memory
// used to be validated before being used.
//
if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
if (!PlatformInfoHob->SmmSmramRequire) {
ReserveEmuVariableNvStore ();
Status = MemTypeInfoInitialization (PlatformInfoHob);
if (EFI_ERROR (Status)) {
// Failing here is okay, it just means that the variable read PPI wasn't found, so
// we need to return EFI_SUCCESS here and let the dispatcher dispatch the variable PEIM first
// and then we'll get called back to finish initialization.
return EFI_SUCCESS;
}
}
CompleteInitialization (PlatformInfoHob, PeiServices);
return EFI_SUCCESS;
}

View file

@ -62,7 +62,7 @@ PeiFvInitialization (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
);
VOID
EFI_STATUS
MemTypeInfoInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
);
@ -109,3 +109,9 @@ VOID
SevInitializeRam (
VOID
);
VOID
CompleteInitialization (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob,
IN CONST EFI_PEI_SERVICES **PeiServices
);