Skip to content

Commit

Permalink
MdeModulePkg: Support customized FV Migration Information
Browse files Browse the repository at this point in the history
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4533

There are use cases which not all FVs need be migrated from TempRam to
permanent memory before TempRam tears down. This new guid is introduced
to avoid unnecessary FV migration to improve boot performance. Platform
can publish MigrationInfo hob with this guid to customize FV migration
info, and PeiCore will only migrate FVs indicated by this Hob info.

This is a backwards compatible change, PeiCore will check MigrationInfo
hob before migration. If MigrationInfo hobs exists, only migrate FVs
recorded by hobs. If MigrationInfo hobs not exists, migrate all FVs to
permanent memory.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Cheng Sun <chengx.sun@intel.com>
  • Loading branch information
chengsux authored and srilathasridharan committed May 2, 2024
1 parent e71838a commit 6233cc5
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 75 deletions.
84 changes: 62 additions & 22 deletions MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -1534,7 +1534,12 @@ EvacuateTempRam (

PEI_CORE_FV_HANDLE PeiCoreFvHandle;
EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;
EFI_PEI_HOB_POINTERS Hob;
EDKII_MIGRATION_INFO *MigrationInfo;
TO_MIGRATE_FV_INFO *ToMigrateFvInfo;
UINT32 FvMigrationFlags;
EDKII_MIGRATED_FV_INFO MigratedFvInfo;
UINTN Index;

ASSERT (Private->PeiMemoryInstalled);

Expand All @@ -1561,6 +1566,13 @@ EvacuateTempRam (

ConvertPeiCorePpiPointers (Private, &PeiCoreFvHandle);

Hob.Raw = GetFirstGuidHob (&gEdkiiMigrationInfoGuid);
if (Hob.Raw != NULL) {
MigrationInfo = GET_GUID_HOB_DATA (Hob);
} else {
MigrationInfo = NULL;
}

for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
FvHeader = Private->Fv[FvIndex].FvHeader;
ASSERT (FvHeader != NULL);
Expand All @@ -1574,28 +1586,42 @@ EvacuateTempRam (
)
)
{
//
// Allocate page to save the rebased PEIMs, the PEIMs will get dispatched later.
//
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES ((UINTN)FvHeader->FvLength),
&FvHeaderAddress
);
ASSERT_EFI_ERROR (Status);
MigratedFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHeaderAddress;
if ((MigrationInfo == NULL) || (MigrationInfo->MigrateAll == TRUE)) {
//
// Migrate all FVs and copy raw data
//
FvMigrationFlags = FLAGS_FV_RAW_DATA_COPY;
} else {
for (Index = 0; Index < MigrationInfo->ToMigrateFvCount; Index++) {
ToMigrateFvInfo = ((TO_MIGRATE_FV_INFO *)(MigrationInfo + 1)) + Index;
if (ToMigrateFvInfo->FvOrgBaseOnTempRam == (UINT32)(UINTN)FvHeader) {
//
// This FV is to migrate
//
FvMigrationFlags = ToMigrateFvInfo->FvMigrationFlags;
break;
}
}

if (Index == MigrationInfo->ToMigrateFvCount) {
//
// This FV is not expected to migrate
//
continue;
}
}

//
// Allocate pool to save the raw PEIMs, which is used to keep consistent context across
// multiple boot and PCR0 will keep the same no matter if the address of allocated page is changed.
// Allocate pages to save the rebased PEIMs, the PEIMs will get dispatched later.
//
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES ((UINTN)FvHeader->FvLength),
&FvHeaderAddress
);
ASSERT_EFI_ERROR (Status);
RawDataFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHeaderAddress;
MigratedFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHeaderAddress;
CopyMem (MigratedFvHeader, FvHeader, (UINTN)FvHeader->FvLength);

DEBUG ((
DEBUG_VERBOSE,
Expand All @@ -1606,17 +1632,33 @@ EvacuateTempRam (
));

//
// Copy the context to the rebased pages and raw pages, and create hob to save the
// information. The MigratedFvInfo HOB will never be produced when
// PcdMigrateTemporaryRamFirmwareVolumes is FALSE, because the PCD control the
// feature.
// Create hob to save MigratedFvInfo, this hob will only be produced when
// Migration feature PCD PcdMigrateTemporaryRamFirmwareVolumes is set to TRUE.
//
CopyMem (MigratedFvHeader, FvHeader, (UINTN)FvHeader->FvLength);
CopyMem (RawDataFvHeader, MigratedFvHeader, (UINTN)FvHeader->FvLength);
MigratedFvInfo.FvOrgBase = (UINT32)(UINTN)FvHeader;
MigratedFvInfo.FvNewBase = (UINT32)(UINTN)MigratedFvHeader;
MigratedFvInfo.FvDataBase = (UINT32)(UINTN)RawDataFvHeader;
MigratedFvInfo.FvDataBase = 0;
MigratedFvInfo.FvLength = (UINT32)(UINTN)FvHeader->FvLength;

//
// When FLAGS_FV_RAW_DATA_COPY bit is set, copy the context to the raw pages and
// reset raw data base address in MigratedFvInfo hob.
//
if ((FvMigrationFlags & FLAGS_FV_RAW_DATA_COPY) == FLAGS_FV_RAW_DATA_COPY) {
//
// Allocate pages to save the raw PEIMs
//
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES ((UINTN)FvHeader->FvLength),
&FvHeaderAddress
);
ASSERT_EFI_ERROR (Status);
RawDataFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHeaderAddress;
CopyMem (RawDataFvHeader, MigratedFvHeader, (UINTN)FvHeader->FvLength);
MigratedFvInfo.FvDataBase = (UINT32)(UINTN)RawDataFvHeader;
}

BuildGuidDataHob (&gEdkiiMigratedFvInfoGuid, &MigratedFvInfo, sizeof (MigratedFvInfo));

//
Expand Down Expand Up @@ -1680,8 +1722,6 @@ EvacuateTempRam (
}
}

RemoveFvHobsInTemporaryMemory (Private);

return Status;
}

Expand Down
40 changes: 0 additions & 40 deletions MdeModulePkg/Core/Pei/Memory/MemoryServices.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,46 +166,6 @@ MigrateMemoryPages (
Private->FreePhysicalMemoryTop = NewMemPagesBase;
}

/**
Removes any FV HOBs whose base address is not in PEI installed memory.
@param[in] Private Pointer to PeiCore's private data structure.
**/
VOID
RemoveFvHobsInTemporaryMemory (
IN PEI_CORE_INSTANCE *Private
)
{
EFI_PEI_HOB_POINTERS Hob;
EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;

DEBUG ((DEBUG_INFO, "Removing FVs in FV HOB not already migrated to permanent memory.\n"));

for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
if ((GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) || (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) || (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3)) {
FirmwareVolumeHob = Hob.FirmwareVolume;
DEBUG ((DEBUG_INFO, " Found FV HOB.\n"));
DEBUG ((
DEBUG_INFO,
" BA=%016lx L=%016lx\n",
FirmwareVolumeHob->BaseAddress,
FirmwareVolumeHob->Length
));
if (
!(
((EFI_PHYSICAL_ADDRESS)(UINTN)FirmwareVolumeHob->BaseAddress >= Private->PhysicalMemoryBegin) &&
(((EFI_PHYSICAL_ADDRESS)(UINTN)FirmwareVolumeHob->BaseAddress + (FirmwareVolumeHob->Length - 1)) < Private->FreePhysicalMemoryTop)
)
)
{
DEBUG ((DEBUG_INFO, " Removing FV HOB to an FV in T-RAM (was not migrated).\n"));
Hob.Header->HobType = EFI_HOB_TYPE_UNUSED;
}
}
}
}

/**
Migrate the base address in firmware volume allocation HOBs
from temporary memory to PEI installed memory.
Expand Down
11 changes: 0 additions & 11 deletions MdeModulePkg/Core/Pei/PeiMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -1074,17 +1074,6 @@ MigrateMemoryPages (
IN BOOLEAN TemporaryRamMigrated
);

/**
Removes any FV HOBs whose base address is not in PEI installed memory.
@param[in] Private Pointer to PeiCore's private data structure.
**/
VOID
RemoveFvHobsInTemporaryMemory (
IN PEI_CORE_INSTANCE *Private
);

/**
Migrate the base address in firmware volume allocation HOBs
from temporary memory to PEI installed memory.
Expand Down
1 change: 1 addition & 0 deletions MdeModulePkg/Core/Pei/PeiMain.inf
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
gEfiFirmwareFileSystem3Guid
gStatusCodeCallbackGuid
gEdkiiMigratedFvInfoGuid ## SOMETIMES_PRODUCES ## HOB
gEdkiiMigrationInfoGuid ## SOMETIMES_CONSUMES ## HOB
gEfiFirmwarePerformanceGuid # MS_CHANGE_161871 - needed to build SEC perf HOB
gEfiDelayedDispatchTableGuid # MSCHANGE

Expand Down
42 changes: 41 additions & 1 deletion MdeModulePkg/Include/Guid/MigratedFvInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,53 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#ifndef __EDKII_MIGRATED_FV_INFO_GUID_H__
#define __EDKII_MIGRATED_FV_INFO_GUID_H__

//
// FLAGS_FV_RAW_DATA_COPY indicates FV raw data will be copied to permanent memory
// or not. When FV is migrated to permanent memory, it will be rebased and raw
// data will be lost. This bit can be configured as below values:
// 0: FV raw data will not be used in later phase, and the copy will be skipped to
// optimize boot performance.
// 1: FV raw data will be copied to permanent memory for later phase use (such as
// FV measurement).
//
#define FLAGS_FV_RAW_DATA_COPY BIT0

///
/// In real use cases, not all FVs need migrate to permanent memory before TempRam tears
/// down. EDKII_MIGRATION_INFO hob should be published by platform to indicate which
/// FVs need migration to optimize boot performance. If this hob is not detected by Pei
/// Core, all FVs on TempRam will be migrated and FV raw data will also be copied.
/// Only one EDKII_MIGRATION_INFO hob should be published by platform, and this hob will
/// take effect only when migration feature is enabled by PCD.
///
typedef struct {
UINT32 FvOrgBaseOnTempRam; // Original FV address on Temporary Ram
//
// FV Migration Flags:
// Bit0: Indicate to copy FV raw data or not
// Others: Reserved bits
//
UINT32 FvMigrationFlags;
} TO_MIGRATE_FV_INFO;

typedef struct {
BOOLEAN MigrateAll; // Migrate all FVs and also copy FV raw data
//
// ToMigrateFvCount and ToMigrateFvInfo array indicate which FVs need be migrated, and
// these info should be ignored when MigrateAll field is set to TRUE.
//
UINT32 ToMigrateFvCount;
// TO_MIGRATE_FV_INFO ToMigrateFvInfo[];
} EDKII_MIGRATION_INFO;

typedef struct {
UINT32 FvOrgBase; // original FV address
UINT32 FvNewBase; // new FV address
UINT32 FvDataBase; // original FV data
UINT32 FvDataBase; // original FV data, 0 means raw data is not copied
UINT32 FvLength; // Fv Length
} EDKII_MIGRATED_FV_INFO;

extern EFI_GUID gEdkiiMigrationInfoGuid;
extern EFI_GUID gEdkiiMigratedFvInfoGuid;

#endif // #ifndef __EDKII_MIGRATED_FV_INFO_GUID_H__
3 changes: 2 additions & 1 deletion MdeModulePkg/MdeModulePkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,8 @@
gEdkiiCapsuleOnDiskNameGuid = { 0x98c80a4f, 0xe16b, 0x4d11, { 0x93, 0x9a, 0xab, 0xe5, 0x61, 0x26, 0x3, 0x30 } }

## Include/Guid/MigratedFvInfo.h
gEdkiiMigratedFvInfoGuid = { 0xc1ab12f7, 0x74aa, 0x408d, { 0xa2, 0xf4, 0xc6, 0xce, 0xfd, 0x17, 0x98, 0x71 } }
gEdkiiMigrationInfoGuid = { 0xb4b140a5, 0x72f6, 0x4c21, { 0x93, 0xe4, 0xac, 0xc4, 0xec, 0xcb, 0x23, 0x23 } }
gEdkiiMigratedFvInfoGuid = { 0xc1ab12f7, 0x74aa, 0x408d, { 0xa2, 0xf4, 0xc6, 0xce, 0xfd, 0x17, 0x98, 0x71 } }

## Include/Guid/RngAlgorithm.h
gEdkiiRngAlgorithmUnSafe = { 0x869f728c, 0x409d, 0x4ab4, {0xac, 0x03, 0x71, 0xd3, 0x09, 0xc1, 0xb3, 0xf4 }}
Expand Down

0 comments on commit 6233cc5

Please sign in to comment.