Re: [edk2] [PATCH v2] ArmPkg/ArmLib: don't invalidate entire I-cache on range operation
On 11 May 2016 at 11:13, Ard Biesheuvelwrote: > Instead of cleaning the data cache to the PoU by virtual address and > subsequently invalidating the entire I-cache, invalidate only the > range that we just cleaned. This way, we don't invalidate other > cachelines unnecessarily. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Ard Biesheuvel Reviewed-by: Leif Lindholm > --- > v2: > - use correct stride for Icache maintenance by VA > - issue an ISB after completing the Icache maintenance > > ArmPkg/Include/Library/ArmLib.h| 10 +++-- > ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c | 23 > +++- > ArmPkg/Library/ArmLib/AArch64/AArch64Support.S | 5 + > ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S | 5 + > ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm | 6 + > 5 files changed, 41 insertions(+), 8 deletions(-) > > diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h > index 1689f0072db6..4608b0cc 100644 > --- a/ArmPkg/Include/Library/ArmLib.h > +++ b/ArmPkg/Include/Library/ArmLib.h > @@ -183,13 +183,19 @@ ArmInvalidateDataCacheEntryByMVA ( > > VOID > EFIAPI > -ArmCleanDataCacheEntryToPoUByMVA( > +ArmCleanDataCacheEntryToPoUByMVA ( >IN UINTN Address >); > > VOID > EFIAPI > -ArmCleanDataCacheEntryByMVA( > +ArmInvalidateInstructionCacheEntryToPoUByMVA ( > + IN UINTN Address > + ); > + > +VOID > +EFIAPI > +ArmCleanDataCacheEntryByMVA ( > IN UINTN Address > ); > > diff --git a/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c > b/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c > index 1045f9068f4d..f7667b8552d2 100644 > --- a/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c > +++ b/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c > @@ -17,11 +17,13 @@ > #include > #include > > +STATIC > VOID > CacheRangeOperation ( >IN VOID*Start, >IN UINTN Length, > - IN LINE_OPERATION LineOperation > + IN LINE_OPERATION LineOperation, > + IN UINTN LineLength >) > { >UINTN ArmCacheLineLength = ArmDataCacheLineLength(); > @@ -64,8 +66,14 @@ InvalidateInstructionCacheRange ( >IN UINTN Length >) > { > - CacheRangeOperation (Address, Length, ArmCleanDataCacheEntryToPoUByMVA); > - ArmInvalidateInstructionCache (); > + CacheRangeOperation (Address, Length, ArmCleanDataCacheEntryToPoUByMVA, > +ArmDataCacheLineLength ()); > + CacheRangeOperation (Address, Length, > +ArmInvalidateInstructionCacheEntryToPoUByMVA, > +ArmInstructionCacheLineLength ()); > + > + ArmInstructionSynchronizationBarrier (); > + >return Address; > } > > @@ -85,7 +93,8 @@ WriteBackInvalidateDataCacheRange ( >IN UINTN Length >) > { > - CacheRangeOperation(Address, Length, > ArmCleanInvalidateDataCacheEntryByMVA); > + CacheRangeOperation(Address, Length, ArmCleanInvalidateDataCacheEntryByMVA, > +ArmDataCacheLineLength ()); >return Address; > } > > @@ -105,7 +114,8 @@ WriteBackDataCacheRange ( >IN UINTN Length >) > { > - CacheRangeOperation(Address, Length, ArmCleanDataCacheEntryByMVA); > + CacheRangeOperation(Address, Length, ArmCleanDataCacheEntryByMVA, > +ArmDataCacheLineLength ()); >return Address; > } > > @@ -116,6 +126,7 @@ InvalidateDataCacheRange ( >IN UINTN Length >) > { > - CacheRangeOperation(Address, Length, ArmInvalidateDataCacheEntryByMVA); > + CacheRangeOperation(Address, Length, ArmInvalidateDataCacheEntryByMVA, > +ArmDataCacheLineLength ()); >return Address; > } > diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S > b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S > index 43f7a795acec..9441f47e30ba 100644 > --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S > +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S > @@ -23,6 +23,7 @@ GCC_ASM_EXPORT (ArmInvalidateInstructionCache) > GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA) > GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA) > GCC_ASM_EXPORT (ArmCleanDataCacheEntryToPoUByMVA) > +GCC_ASM_EXPORT (ArmInvalidateInstructionCacheEntryToPoUByMVA) > GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA) > GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay) > GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay) > @@ -80,6 +81,10 @@ ASM_PFX(ArmCleanDataCacheEntryToPoUByMVA): >dc cvau, x0// Clean single data cache line to PoU >ret > > +ASM_PFX(ArmInvalidateInstructionCacheEntryToPoUByMVA): > + ic ivau, x0// Invalidate single instruction cache line to PoU > + ret > + > > ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA): >dc civac, x0 // Clean and
[edk2] [PATCH v2] ArmPkg/ArmLib: don't invalidate entire I-cache on range operation
Instead of cleaning the data cache to the PoU by virtual address and subsequently invalidating the entire I-cache, invalidate only the range that we just cleaned. This way, we don't invalidate other cachelines unnecessarily. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel--- v2: - use correct stride for Icache maintenance by VA - issue an ISB after completing the Icache maintenance ArmPkg/Include/Library/ArmLib.h| 10 +++-- ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c | 23 +++- ArmPkg/Library/ArmLib/AArch64/AArch64Support.S | 5 + ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S | 5 + ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm | 6 + 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h index 1689f0072db6..4608b0cc 100644 --- a/ArmPkg/Include/Library/ArmLib.h +++ b/ArmPkg/Include/Library/ArmLib.h @@ -183,13 +183,19 @@ ArmInvalidateDataCacheEntryByMVA ( VOID EFIAPI -ArmCleanDataCacheEntryToPoUByMVA( +ArmCleanDataCacheEntryToPoUByMVA ( IN UINTN Address ); VOID EFIAPI -ArmCleanDataCacheEntryByMVA( +ArmInvalidateInstructionCacheEntryToPoUByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmCleanDataCacheEntryByMVA ( IN UINTN Address ); diff --git a/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c b/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c index 1045f9068f4d..f7667b8552d2 100644 --- a/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c +++ b/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c @@ -17,11 +17,13 @@ #include #include +STATIC VOID CacheRangeOperation ( IN VOID*Start, IN UINTN Length, - IN LINE_OPERATION LineOperation + IN LINE_OPERATION LineOperation, + IN UINTN LineLength ) { UINTN ArmCacheLineLength = ArmDataCacheLineLength(); @@ -64,8 +66,14 @@ InvalidateInstructionCacheRange ( IN UINTN Length ) { - CacheRangeOperation (Address, Length, ArmCleanDataCacheEntryToPoUByMVA); - ArmInvalidateInstructionCache (); + CacheRangeOperation (Address, Length, ArmCleanDataCacheEntryToPoUByMVA, +ArmDataCacheLineLength ()); + CacheRangeOperation (Address, Length, +ArmInvalidateInstructionCacheEntryToPoUByMVA, +ArmInstructionCacheLineLength ()); + + ArmInstructionSynchronizationBarrier (); + return Address; } @@ -85,7 +93,8 @@ WriteBackInvalidateDataCacheRange ( IN UINTN Length ) { - CacheRangeOperation(Address, Length, ArmCleanInvalidateDataCacheEntryByMVA); + CacheRangeOperation(Address, Length, ArmCleanInvalidateDataCacheEntryByMVA, +ArmDataCacheLineLength ()); return Address; } @@ -105,7 +114,8 @@ WriteBackDataCacheRange ( IN UINTN Length ) { - CacheRangeOperation(Address, Length, ArmCleanDataCacheEntryByMVA); + CacheRangeOperation(Address, Length, ArmCleanDataCacheEntryByMVA, +ArmDataCacheLineLength ()); return Address; } @@ -116,6 +126,7 @@ InvalidateDataCacheRange ( IN UINTN Length ) { - CacheRangeOperation(Address, Length, ArmInvalidateDataCacheEntryByMVA); + CacheRangeOperation(Address, Length, ArmInvalidateDataCacheEntryByMVA, +ArmDataCacheLineLength ()); return Address; } diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 43f7a795acec..9441f47e30ba 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -23,6 +23,7 @@ GCC_ASM_EXPORT (ArmInvalidateInstructionCache) GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmCleanDataCacheEntryToPoUByMVA) +GCC_ASM_EXPORT (ArmInvalidateInstructionCacheEntryToPoUByMVA) GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay) GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay) @@ -80,6 +81,10 @@ ASM_PFX(ArmCleanDataCacheEntryToPoUByMVA): dc cvau, x0// Clean single data cache line to PoU ret +ASM_PFX(ArmInvalidateInstructionCacheEntryToPoUByMVA): + ic ivau, x0// Invalidate single instruction cache line to PoU + ret + ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA): dc civac, x0 // Clean and invalidate single data cache line diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S index 50c760f335de..c765032c9e4d 100644 --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S @@ -18,6 +18,7 @@ GCC_ASM_EXPORT (ArmInvalidateInstructionCache) GCC_ASM_EXPORT