diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 9da1bbc9f2..cfb6fe6024 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -99,6 +99,8 @@ # Include/Guid/ArmMpCoreInfo.h gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} } + gArmMmuReplaceLiveTranslationEntryFuncGuid = { 0xa8b50ff3, 0x08ec, 0x4dd3, {0xbf, 0x04, 0x28, 0xbf, 0x71, 0x75, 0xc7, 0x4a} } + [Protocols.common] ## Arm System Control and Management Interface(SCMI) Base protocol ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index ae59e9a7d0..764c7d362e 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -10,6 +10,7 @@ **/ #include +#include #include #include #include @@ -120,14 +121,14 @@ ReplaceTableEntry ( // use an ordinary break before make. Otherwise, we will need to // temporarily disable the MMU. DisableMmu = FALSE; - if ((((RegionStart ^ (UINTN)ArmReplaceLiveTranslationEntry) & ~BlockMask) == 0) || + if ((((RegionStart ^ (UINTN)mReplaceLiveEntryFunc) & ~BlockMask) == 0) || (((RegionStart ^ (UINTN)Entry) & ~BlockMask) == 0)) { DisableMmu = TRUE; DEBUG ((DEBUG_WARN, "%a: splitting block entry with MMU disabled\n", __FUNCTION__)); } - ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart, DisableMmu); + mReplaceLiveEntryFunc (Entry, Value, RegionStart, DisableMmu); } } @@ -747,15 +748,21 @@ ArmMmuBaseLibConstructor ( ) { extern UINT32 ArmReplaceLiveTranslationEntrySize; + VOID *Hob; - // - // The ArmReplaceLiveTranslationEntry () helper function may be invoked - // with the MMU off so we have to ensure that it gets cleaned to the PoC - // - WriteBackDataCacheRange ( - (VOID *)(UINTN)ArmReplaceLiveTranslationEntry, - ArmReplaceLiveTranslationEntrySize - ); + Hob = GetFirstGuidHob (&gArmMmuReplaceLiveTranslationEntryFuncGuid); + if (Hob != NULL) { + mReplaceLiveEntryFunc = *(VOID **)GET_GUID_HOB_DATA (Hob); + } else { + // + // The ArmReplaceLiveTranslationEntry () helper function may be invoked + // with the MMU off so we have to ensure that it gets cleaned to the PoC + // + WriteBackDataCacheRange ( + (VOID *)(UINTN)ArmReplaceLiveTranslationEntry, + ArmReplaceLiveTranslationEntrySize + ); + } return RETURN_SUCCESS; } diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c index caace2c17c..5f50a605a3 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c @@ -12,6 +12,7 @@ #include #include #include +#include EFI_STATUS EFIAPI @@ -21,6 +22,8 @@ ArmMmuPeiLibConstructor ( ) { extern UINT32 ArmReplaceLiveTranslationEntrySize; + VOID *ArmReplaceLiveTranslationEntryFunc; + VOID *Hob; EFI_FV_FILE_INFO FileInfo; EFI_STATUS Status; @@ -42,6 +45,20 @@ ArmMmuPeiLibConstructor ( (UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize)) { DEBUG ((DEBUG_INFO, "ArmMmuLib: skipping cache maintenance on XIP PEIM\n")); + + // + // Expose the XIP version of the ArmReplaceLiveTranslationEntry() routine + // via a HOB so we can fall back to it later when we need to split block + // mappings in a way that adheres to break-before-make requirements. + // + ArmReplaceLiveTranslationEntryFunc = ArmReplaceLiveTranslationEntry; + + Hob = BuildGuidDataHob ( + &gArmMmuReplaceLiveTranslationEntryFuncGuid, + &ArmReplaceLiveTranslationEntryFunc, + sizeof ArmReplaceLiveTranslationEntryFunc + ); + ASSERT (Hob != NULL); } else { DEBUG ((DEBUG_INFO, "ArmMmuLib: performing cache maintenance on shadowed PEIM\n")); // diff --git a/ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf b/ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf index 3d78e7dabf..57cb71f90e 100644 --- a/ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf +++ b/ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf @@ -36,7 +36,11 @@ [LibraryClasses] ArmLib CacheMaintenanceLib + HobLib MemoryAllocationLib +[Guids] + gArmMmuReplaceLiveTranslationEntryFuncGuid + [Pcd.ARM] gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride diff --git a/ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf b/ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf index ce9674ea99..02f874a1a9 100644 --- a/ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf +++ b/ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf @@ -29,4 +29,8 @@ [LibraryClasses] ArmLib CacheMaintenanceLib + HobLib MemoryAllocationLib + +[Guids] + gArmMmuReplaceLiveTranslationEntryFuncGuid