From 5aaf33cba626c68357129a0df4e703ad6eb630cf Mon Sep 17 00:00:00 2001 From: Bret Barkelew Date: Thu, 16 Aug 2018 20:53:32 +0000 Subject: [PATCH] MdeModulePkg: Add Mu DxeCapsuleLib changes and CapsulePersistLib - Move Capsule infrastructure to TianoCore libs rather than private. - Add the CapsulePersistLib and remove references to MsCapsuleUpdatePkg. - Add CapsulePersistLib support to DxeCapsuleLib instance. - Modify DxeCapsuleProcessLib so that UpdateImageProgress() returns sucess - Switch debug print to DEBUG_ERROR during capsule processing --- .../Include/Library/CapsulePersistLib.h | 53 ++++++++ .../CapsulePersistLibNull.c | 57 +++++++++ .../CapsulePersistLibNull.inf | 36 ++++++ .../Library/DxeCapsuleLibFmp/DxeCapsuleLib.c | 45 ++++++- .../DxeCapsuleLibFmp/DxeCapsuleLib.inf | 4 + .../DxeCapsuleLibFmp/DxeCapsuleProcessLib.c | 115 +++++++++++++++--- .../DxeCapsuleProcessLibNull.c | 22 ++++ .../DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf | 2 + MdeModulePkg/MdeModulePkg.dec | 7 ++ MdeModulePkg/MdeModulePkg.dsc | 2 + 10 files changed, 326 insertions(+), 17 deletions(-) create mode 100644 MdeModulePkg/Include/Library/CapsulePersistLib.h create mode 100644 MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.c create mode 100644 MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.inf diff --git a/MdeModulePkg/Include/Library/CapsulePersistLib.h b/MdeModulePkg/Include/Library/CapsulePersistLib.h new file mode 100644 index 00000000000..3f0d5743ac6 --- /dev/null +++ b/MdeModulePkg/Include/Library/CapsulePersistLib.h @@ -0,0 +1,53 @@ +/** @file -- CapsulePersistLib.h +A public library interface for persisting Capsules across reset. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef CAPSULE_PERSIST_LIB_H_ +#define CAPSULE_PERSIST_LIB_H_ + +/** + Persist a Capsule across reset. + + @param[in] CapsuleHeader EFI_CAPSULE_HEADER pointing to Capsule Image to persist. + + @retval EFI_SUCCESS Capsule was successfully persisted. + @retval EFI_DEVICE_ERROR Something went wrong while trying to persist the capsule. + +**/ +EFI_STATUS +EFIAPI +PersistCapsule ( + IN EFI_CAPSULE_HEADER *CapsuleHeader + ); + +/** + Returns a pointer to a buffer of capsules. + + If no persisted capsules present, CapsuleArray is not modified, and CapsuleArraySize will be set to zero. + + Removes the persistent capsules from whatever the medium of persistence is. + Note: if return is something other than EFI_SUCESS or EFI_BUFFER_TOO_SMALL, removal of all persistent + capsules from persistence is not guaranteed. + + + @param[out] CapsuleArray Pointer to a buffer to hold the capsules. + @param[out] CapsuleArraySize On input, size of CapsuleArray allocation. + On output, size of actual buffer of capsules. + + @retval EFI_SUCCESS Capsules were de-perisisted, and ouptut data is valid. + @retval EFI_BUFFER_TOO_SMALL CapsuleArray buffer is too small to hold all the data. + @retval EFI_DEVICE_ERROR Something went wrong while trying to retrive the capsule. + +**/ +EFI_STATUS +EFIAPI +GetPersistedCapsules ( + OUT EFI_CAPSULE_HEADER *CapsuleArray, + OUT UINTN *CapsuleArraySize + ); + +#endif // CAPSULE_PERSIST_LIB_H_ diff --git a/MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.c b/MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.c new file mode 100644 index 00000000000..70bac35adb1 --- /dev/null +++ b/MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.c @@ -0,0 +1,57 @@ +/** @file -- CapsulePersistLibNull.c +A null implementation of the CapsulePersistLib + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +/** + Persist a Capsule across reset. + + @param[in] CapsuleHeader EFI_CAPSULE_HEADER pointing to Capsule Image to persist. + + @retval EFI_SUCCESS Capsule was successfully persisted. + @retval EFI_DEVICE_ERROR Something went wrong while trying to persist the blob. + +**/ +EFI_STATUS +EFIAPI +PersistCapsule ( + IN EFI_CAPSULE_HEADER *CapsuleHeader + ) +{ + return EFI_SUCCESS; +} + +/** + Returns a pointer to a buffer of capsules. + + If no persisted capsules present, CapsuleArray is not modified, and CapsuleArraySize will be set to zero. + + Removes the persistent capsules from whatever the medium of persistence is. + Note: if return is something other than EFI_SUCESS or EFI_BUFFER_TOO_SMALL, removal of all persistent + capsules from persistence is not guaranteed. + + + @param[out] CapsuleArray Pointer to a buffer to hold the capsules. + @param[out] CapsuleArraySize On input, size of CapsuleArray allocation. + On output, size of actual buffer of capsules. + + @retval EFI_SUCCESS Capsules were de-perisisted, and ouptut data is valid. + @retval EFI_BUFFER_TOO_SMALL CapsuleArray buffer is too small to hold all the data. + @retval EFI_DEVICE_ERROR Something went wrong while trying to retrive the capsule. + +**/ +EFI_STATUS +EFIAPI +GetPersistedCapsules ( + OUT EFI_CAPSULE_HEADER *CapsuleArray, + OUT UINTN *CapsuleArraySize + ) +{ + *CapsuleArraySize = 0; + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.inf b/MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.inf new file mode 100644 index 00000000000..16c03ea4ab3 --- /dev/null +++ b/MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.inf @@ -0,0 +1,36 @@ +## @file CapsulePersistLibNull.inf +# A null implementation of the CapsulePersistLib +# +## +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = CapsulePersistLibNull + FILE_GUID = 96AAE710-21AB-4881-9D92-8AD19479BB36 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_RUNTIME_DRIVER + LIBRARY_CLASS = CapsulePersistLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + + +[Sources] + CapsulePersistLibNull.c + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +[LibraryClasses] + diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c index 01c7fb7184f..47b4e95196f 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c @@ -27,6 +27,7 @@ #include #include #include +#include // MU_CHANGE - Support ConnectAll after loading. #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include // MU_CHANGE - Enable Capsule Persist Lib. #include #include @@ -251,6 +253,16 @@ ValidateFmpCapsule ( FmpCapsuleHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER) + sizeof (UINT64)*ItemNum; + // MU_CHANGE [BEGIN] + // Currently we do not support Embedded Drivers. + // This opens up concerns about validating the driver as we can't trust secure boot chain (pk) + if (FmpCapsuleHeader->EmbeddedDriverCount != 0) { + DEBUG ((DEBUG_ERROR, "%a - FMP Capsule contains an embedded driver. This is not supported by this implementation\n", __FUNCTION__)); + return EFI_UNSUPPORTED; + } + + // MU_CHANGE [END] + // Check ItemOffsetList for (Index = 0; Index < ItemNum; Index++) { if (ItemOffsetList[Index] >= FmpCapsuleSize) { @@ -1219,6 +1231,16 @@ ProcessFmpCapsuleImage ( BOOLEAN NotReady; BOOLEAN Abort; + // MU_CHANGE [BEGIN] + // Validate the capsule (perhaps again) before processing in case some one calls + // ProcessFmpCapsuleImage() before or without calling ValidateFmpCapsule() + Status = ValidateFmpCapsule (CapsuleHeader, NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + // MU_CHANGE [END] + if (!IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) { return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), CapFileName, ResetRequired); } @@ -1245,6 +1267,14 @@ ProcessFmpCapsuleImage ( return EFI_SUCCESS; } + // MU_CHANGE [BEGIN] + // ConnectAll to ensure + // All the communication protocol required by driver in capsule installed + // All FMP protocols are installed + // + EfiBootManagerConnectAll (); + // MU_CHANGE [END] + // // 1. Try to load & start all the drivers within capsule // @@ -1270,6 +1300,15 @@ ProcessFmpCapsuleImage ( } } + // MU_CHANGE [BEGIN] + // Connnect all again to connect drivers within capsule + // + if (FmpCapsuleHeader->EmbeddedDriverCount > 0) { + EfiBootManagerConnectAll (); + } + + // MU_CHANGE [END] + // // 2. Route payload to right FMP instance // @@ -1630,7 +1669,11 @@ StageCapsuleImage ( IN EFI_CAPSULE_HEADER *CapsuleHeader ) { - return EFI_SUCCESS; + if (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS) { + return EFI_UNSUPPORTED; + } + + return PersistCapsule (CapsuleHeader); } // MU_CHANGE - END diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf index 095e062a6ee..16d41292032 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf @@ -4,6 +4,7 @@ # Capsule library instance for DXE_DRIVER module types. # # Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -52,6 +53,8 @@ FileHandleLib UefiBootManagerLib VariablePolicyHelperLib + ResetUtilityLib ## MU_CHANGE - Use the enhanced reset subtype. + CapsulePersistLib ## MU_CHANGE - Enable Capsule Persist Lib. [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleMax ## CONSUMES @@ -97,6 +100,7 @@ ## SOMETIMES_PRODUCES ## Variable:L"BootNext" gEfiGlobalVariableGuid gEdkiiCapsuleOnDiskNameGuid ## SOMETIMES_CONSUMES ## GUID + gCapsuleUpdateCompleteResetGuid ## MU_CHANGE - Use the enhanced reset subtype. [Depex] gEfiVariableWriteArchProtocolGuid diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c index 2a38a3d95bc..3115eaaf29f 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c @@ -30,6 +30,8 @@ #include #include #include +#include // MU_CHANGE - Use the enhanced reset subtype. +#include // MU_CHANGE - Enable Capsule Persist Lib. #include @@ -125,10 +127,11 @@ ValidateCapsuleNameCapsuleIntegrity ( extern BOOLEAN mDxeCapsuleLibEndOfDxe; BOOLEAN mNeedReset = FALSE; -VOID **mCapsulePtr; -CHAR16 **mCapsuleNamePtr; -EFI_STATUS *mCapsuleStatusArray; -UINT32 mCapsuleTotalNumber; +VOID **mCapsulePtr; +CHAR16 **mCapsuleNamePtr; +EFI_STATUS *mCapsuleStatusArray; +UINT32 mCapsuleTotalNumber; +EFI_CAPSULE_HEADER *mPersistedCapsules; // MU_CHANGE - Enable Capsule Persist Lib. /** The firmware implements to process the capsule image. @@ -203,9 +206,14 @@ UpdateImageProgress ( } } + // MU_CHANGE - Return success on Progress Display Error to allow capsule to proceed in the face of progress errors. Status = DisplayUpdateProgress (Completion, Color); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "DisplayUpdateProgress returned %r\n", Status)); + } - return Status; + return EFI_SUCCESS; + // MU_CHANGE - Return success on Progress Display Error to allow capsule to proceed in the face of progress errors.END } /** @@ -225,12 +233,49 @@ InitCapsulePtr ( UINTN CapsuleNameCapsuleTotalNumber; VOID **CapsuleNameCapsulePtr; EFI_PHYSICAL_ADDRESS *CapsuleNameAddress; + // MU_CHANGE - Enable Capsule Persist Lib. + EFI_STATUS PersistStatus; + UINTN PersistedCapsuleBufferSize; + EFI_CAPSULE_HEADER *CurrentPersistedCapsule; CapsuleNameNumber = 0; CapsuleNameTotalNumber = 0; CapsuleNameCapsuleTotalNumber = 0; CapsuleNameCapsulePtr = NULL; + // MU_CHANGE [BEGIN] - Enable Capsule Persist Lib. + // + // Find all persisted capsules + // + mPersistedCapsules = NULL; + PersistedCapsuleBufferSize = 0; + PersistStatus = GetPersistedCapsules (mPersistedCapsules, &PersistedCapsuleBufferSize); + if (PersistStatus == EFI_BUFFER_TOO_SMALL) { + mPersistedCapsules = AllocatePool (PersistedCapsuleBufferSize); + if (mPersistedCapsules != NULL) { + // if allocation succeeds, go grab all the capsules. Otherwise, just pass. + // maybe the HOB Capsules will still work. + PersistStatus = GetPersistedCapsules (mPersistedCapsules, &PersistedCapsuleBufferSize); + } + } + + // success from first call just means no capsules to look at, and PersistedCapusleBufferSize is 0. + // Failure to allocate means mPersistedCapsules = NULL, so no capsules to look at. + if (!EFI_ERROR (PersistStatus) && (mPersistedCapsules != NULL) && (PersistedCapsuleBufferSize > 0)) { + CurrentPersistedCapsule = mPersistedCapsules; + while ((UINT8 *)CurrentPersistedCapsule < ((UINT8 *)mPersistedCapsules + PersistedCapsuleBufferSize)) { + if (CurrentPersistedCapsule->CapsuleImageSize == 0) { + // Avoid an infinite loop in the case where corrupted capsule has CapsuleImageSize = 0. + break; + } + + mCapsuleTotalNumber++; + CurrentPersistedCapsule = (EFI_CAPSULE_HEADER *)((UINT8 *)CurrentPersistedCapsule + CurrentPersistedCapsule->CapsuleImageSize); + } + } + + // MU_CHANGE [END] - Enable Capsule Persist Lib. + // // Find all capsule images from hob // @@ -269,6 +314,13 @@ InitCapsulePtr ( if (mCapsuleStatusArray == NULL) { DEBUG ((DEBUG_ERROR, "Allocate mCapsuleStatusArray fail!\n")); FreePool (mCapsulePtr); + // MU_CHANGE - Enable Capsule Persist Lib. + if (mPersistedCapsules != NULL) { + FreePool (mPersistedCapsules); + mPersistedCapsules = NULL; + } + + // MU_CHANGE - Enable Capsule Persist Lib End mCapsulePtr = NULL; mCapsuleTotalNumber = 0; return; @@ -303,6 +355,22 @@ InitCapsulePtr ( HobPointer.Raw = GET_NEXT_HOB (HobPointer); } + // MU_CHANGE [BEGIN] - Enable Capsule Persist Lib. + if (!EFI_ERROR (PersistStatus) && (mPersistedCapsules != NULL) && (PersistedCapsuleBufferSize > 0)) { + CurrentPersistedCapsule = mPersistedCapsules; + while ((UINT8 *)CurrentPersistedCapsule < ((UINT8 *)mPersistedCapsules + PersistedCapsuleBufferSize)) { + if (CurrentPersistedCapsule->CapsuleImageSize == 0) { + // Avoid an infinite loop in the case where corrupted capsule has CapsuleImageSize = 0. + break; + } + + mCapsulePtr[Index++] = (VOID *)CurrentPersistedCapsule; + CurrentPersistedCapsule = (EFI_CAPSULE_HEADER *)((UINT8 *)CurrentPersistedCapsule + CurrentPersistedCapsule->CapsuleImageSize); + } + } + + // MU_CHANGE [END] - Enable Capsule Persist Lib + // // Find Capsule On Disk Names // @@ -519,8 +587,9 @@ ProcessTheseCapsules ( // // We didn't find a hob, so had no errors. // - DEBUG ((DEBUG_ERROR, "We can not find capsule data in capsule update boot mode.\n")); - mNeedReset = TRUE; + // MU_CHANGE: switch from error to info below, adjust print string + DEBUG ((DEBUG_INFO, "%a - Can not find capsule data\n", __FUNCTION__)); + // mNeedReset = TRUE; // MU_CHANGE - turn off needing the reset return EFI_SUCCESS; } @@ -554,7 +623,9 @@ ProcessTheseCapsules ( } } - DEBUG ((DEBUG_INFO, "Updating the firmware ......\n")); + // MU_CHANGE - Printing to the screen is unacceptable in production FW. + // Even if the graphics capsule didn't exist. + // DEBUG ((DEBUG_INFO, "Updating the firmware ......\n")); // // All capsules left are recognized by platform. @@ -635,7 +706,10 @@ DoResetSystem ( REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE | PcdGet32 (PcdStatusCodeSubClassCapsule) | PcdGet32 (PcdCapsuleStatusCodeResettingSystem))); - gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + // MU_CHANGE - Use the enhanced reset subtype so that this reset can be filtered/handled + // in a platform-specific way. + // gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + ResetSystemWithSubtype (EfiResetCold, &gCapsuleUpdateCompleteResetGuid); CpuDeadLoop (); } @@ -679,6 +753,12 @@ ProcessCapsules ( { EFI_STATUS Status; + // MU_CHANGE [BEGIN] + // TEMP CHANGE - BDS is not currently wired to call this twice + // and 1) we block embedded drivers and 2) this all falls + // within our trust model, so we can execute in a single pass. + + /* if (!mDxeCapsuleLibEndOfDxe) { Status = ProcessTheseCapsules (TRUE); @@ -690,14 +770,17 @@ ProcessCapsules ( DoResetSystem (); } } else { - Status = ProcessTheseCapsules (FALSE); - // - // Reboot System if required after all capsule processed - // - if (mNeedReset) { - DoResetSystem (); - } + */ + // Status = ProcessTheseCapsules(FALSE); + Status = ProcessTheseCapsules (TRUE); + // + // Reboot System if required after all capsule processed + // + if (mNeedReset) { + DoResetSystem (); } + // } + // MU_CHANGE [END] return Status; } diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c index 9054ae446ee..2838c6a9c4a 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c @@ -68,3 +68,25 @@ ProcessCapsules ( { return EFI_UNSUPPORTED; } + +// MU_CHANGE [BEGIN] - This implementation is BootServices/Runtime specific. +// Move most business logic into specific Dxe vs RuntimeDxe libs. + +/** + Function indicate the current completion progress of the firmware + update. Platform may override with own specific progress function. + + @param[in] Completion A value between 1 and 100 indicating the current completion progress of the firmware update + + @retval EFI_SUCESS Input capsule is a correct FMP capsule. +**/ +EFI_STATUS +EFIAPI +Update_Image_Progress ( + IN UINTN Completion + ) +{ + return EFI_SUCCESS; +} + +// MU_CHANGE [END] diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf index bf56f4623f8..e65d95d46db 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf @@ -49,6 +49,8 @@ PrintLib HobLib BmpSupportLib + UefiBootManagerLib ## MU_CHANGE - Enable ConnectAll before capsule processing. + CapsulePersistLib ## MU_CHANGE - Enable Capsule Persist Lib. [Protocols] diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index c7d9e852473..fd74fe492eb 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -187,6 +187,13 @@ ## @libraryclass This library is used to report memory type information change ## across a reboot. MemoryTypeInformationChangeLib|Include/Library/MemoryTypeInformationChangeLib.h + + ## MU_CHANGE + ## @libraryclass A public library interface for persisting Capsules across reset. + # This provides platform-defined support for persistence on architectures + # that may not support "persist in RAM" across a reset. + # + CapsulePersistLib|Include/Library/CapsulePersistLib.h ## MU_CHANGE - Add DeviceStateLib to MdeModulePkg ## @libraryclass Provides a way to store and update the current device state diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 8783c37542d..f63d76c97c0 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -74,6 +74,7 @@ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + CapsulePersistLib|MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.inf ## MU_CHANGE PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf @@ -235,6 +236,7 @@ MdeModulePkg/Library/ParallelLzmaCustomDecompressLib/ParallelLzmaCustomDecompressLib.inf ## MU_CHANGE MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf MdeModulePkg/Library/MemoryTypeInformationChangeLibNull/MemoryTypeInformationChangeLibNull.inf ## MU_CHANGE + MdeModulePkg/Library/CapsulePersistLibNull/CapsulePersistLibNull.inf ## MU_CHANGE MdeModulePkg/Library/SecurityLockAuditDebugMessageLib/SecurityLockAuditDebugMessageLib.inf ## MU_CHANGE MdeModulePkg/Library/SecurityLockAuditLibNull/SecurityLockAuditLibNull.inf ## MU_CHANGE MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf