From 2091e449f17936175a043a067b99595fb1c9789d Mon Sep 17 00:00:00 2001 From: Levi Yun Date: Thu, 9 Jan 2025 10:17:27 +0000 Subject: [PATCH] StandaloneMmPkg: Introduce a PCD to disable shadow boot FV On some Arm platforms the boot firmware volume passed in the HOB by the secure world firmware (TF-A) is never freed and is always mapped as read-only. On such platforms the heap memory can be saved by disabling the shadow copy of the boot firmware volume. This is useful as on some platforms the amount of memory available is limited. Therefore, introduce a PCD PcdShadowBfv that platforms can configure to disable the shadow boot FV. This PCD is set to TRUE by default. Signed-off-by: Levi Yun --- StandaloneMmPkg/Core/FwVol.c | 42 +++++++++++++++++------ StandaloneMmPkg/Core/StandaloneMmCore.inf | 1 + StandaloneMmPkg/StandaloneMmPkg.dec | 7 ++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/StandaloneMmPkg/Core/FwVol.c b/StandaloneMmPkg/Core/FwVol.c index 9559581e74..d5dfdacbf0 100644 --- a/StandaloneMmPkg/Core/FwVol.c +++ b/StandaloneMmPkg/Core/FwVol.c @@ -270,18 +270,36 @@ MmDispatchFvs ( DEBUG ((DEBUG_INFO, "%a: FV[%d] address - 0x%x\n", __func__, Index, FvHob.FirmwareVolume->BaseAddress)); DEBUG ((DEBUG_INFO, "%a: FV[%d] size - 0x%x\n", __func__, Index, FvHob.FirmwareVolume->Length)); - Fv = AllocatePool (FvHob.FirmwareVolume->Length); - if (Fv == NULL) { - DEBUG ((DEBUG_ERROR, "Fail to allocate memory for Fv\n")); - CpuDeadLoop (); - return; + + if (FvHob.FirmwareVolume->Length == 0x00) { + DEBUG (( + DEBUG_INFO, + "%a: Skip invalid FV[%d]- 0x%x/0x%x\n", + __func__, + Index, + FvHob.FirmwareVolume->BaseAddress, + FvHob.FirmwareVolume->Length + )); + continue; + } + + if (!FixedPcdGetBool (PcdShadowBfv)) { + Fv = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvHob.FirmwareVolume->BaseAddress); + } else { + Fv = AllocatePool (FvHob.FirmwareVolume->Length); + if (Fv == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to allocate memory for Fv\n")); + CpuDeadLoop (); + return; + } + + CopyMem ( + (VOID *)Fv, + (VOID *)(UINTN)FvHob.FirmwareVolume->BaseAddress, + FvHob.FirmwareVolume->Length + ); } - CopyMem ( - (VOID *)Fv, - (VOID *)(UINTN)FvHob.FirmwareVolume->BaseAddress, - FvHob.FirmwareVolume->Length - ); MmCoreFfsFindMmDriver (Fv, 0); mMmFv[Index++] = Fv; @@ -307,6 +325,10 @@ MmFreeShadowedFvs ( { UINTN Index; + if (!FixedPcdGetBool (PcdShadowBfv)) { + return; + } + for (Index = 0; Index < ARRAY_SIZE (mMmFv); Index++) { if (mMmFv[Index] != NULL) { FreePool (mMmFv[Index]); diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index f5ecda3a06..aca21a7e20 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -85,6 +85,7 @@ [Pcd] gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered ##CONSUMES + gStandaloneMmPkgTokenSpaceGuid.PcdShadowBfv ##CONSUMES # # This configuration fails for CLANGPDB, which does not support PIE in the GCC diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec index 72a54979a4..ca8ce715d9 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dec +++ b/StandaloneMmPkg/StandaloneMmPkg.dec @@ -55,6 +55,13 @@ # @Prompt Maximum permitted FwVol section nesting depth (exclusive) in MM. gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth|0x10|UINT32|0x00000001 + ## Option to make shadow copy of boot firmware volume while loading drivers. + # This options is useful when the BFV is not located in the Flash area + # but is in the RAM instead and therefore no shadow copy is needed. + # TRUE - Default. Make a shadow copy of the boot firmware volume. + # FALSE - Disable shadow copy of the boot firmware volume. + gStandaloneMmPkgTokenSpaceGuid.PcdShadowBfv|TRUE|BOOLEAN|0x00000003 + [PcdsFeatureFlag] ## Indicates if restart MM Dispatcher once MM Entry Point is registered.

# TRUE - Restart MM Dispatcher once MM Entry Point is registered.