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 <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
This commit is contained in:
Ard Biesheuvel 2016-05-11 10:38:47 +02:00
parent 14b2ebc30c
commit cf580da1bc
5 changed files with 43 additions and 11 deletions

View File

@ -183,13 +183,19 @@ ArmInvalidateDataCacheEntryByMVA (
VOID VOID
EFIAPI EFIAPI
ArmCleanDataCacheEntryToPoUByMVA( ArmCleanDataCacheEntryToPoUByMVA (
IN UINTN Address IN UINTN Address
); );
VOID VOID
EFIAPI EFIAPI
ArmCleanDataCacheEntryByMVA( ArmInvalidateInstructionCacheEntryToPoUByMVA (
IN UINTN Address
);
VOID
EFIAPI
ArmCleanDataCacheEntryByMVA (
IN UINTN Address IN UINTN Address
); );

View File

@ -17,15 +17,16 @@
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
STATIC
VOID VOID
CacheRangeOperation ( CacheRangeOperation (
IN VOID *Start, IN VOID *Start,
IN UINTN Length, IN UINTN Length,
IN LINE_OPERATION LineOperation IN LINE_OPERATION LineOperation,
IN UINTN LineLength
) )
{ {
UINTN ArmCacheLineLength = ArmDataCacheLineLength(); UINTN ArmCacheLineAlignmentMask = LineLength - 1;
UINTN ArmCacheLineAlignmentMask = ArmCacheLineLength - 1;
// Align address (rounding down) // Align address (rounding down)
UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask); UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);
@ -34,7 +35,7 @@ CacheRangeOperation (
// Perform the line operation on an address in each cache line // Perform the line operation on an address in each cache line
while (AlignedAddress < EndAddress) { while (AlignedAddress < EndAddress) {
LineOperation(AlignedAddress); LineOperation(AlignedAddress);
AlignedAddress += ArmCacheLineLength; AlignedAddress += LineLength;
} }
ArmDataSynchronizationBarrier (); ArmDataSynchronizationBarrier ();
} }
@ -64,8 +65,14 @@ InvalidateInstructionCacheRange (
IN UINTN Length IN UINTN Length
) )
{ {
CacheRangeOperation (Address, Length, ArmCleanDataCacheEntryToPoUByMVA); CacheRangeOperation (Address, Length, ArmCleanDataCacheEntryToPoUByMVA,
ArmInvalidateInstructionCache (); ArmDataCacheLineLength ());
CacheRangeOperation (Address, Length,
ArmInvalidateInstructionCacheEntryToPoUByMVA,
ArmInstructionCacheLineLength ());
ArmInstructionSynchronizationBarrier ();
return Address; return Address;
} }
@ -85,7 +92,8 @@ WriteBackInvalidateDataCacheRange (
IN UINTN Length IN UINTN Length
) )
{ {
CacheRangeOperation(Address, Length, ArmCleanInvalidateDataCacheEntryByMVA); CacheRangeOperation(Address, Length, ArmCleanInvalidateDataCacheEntryByMVA,
ArmDataCacheLineLength ());
return Address; return Address;
} }
@ -105,7 +113,8 @@ WriteBackDataCacheRange (
IN UINTN Length IN UINTN Length
) )
{ {
CacheRangeOperation(Address, Length, ArmCleanDataCacheEntryByMVA); CacheRangeOperation(Address, Length, ArmCleanDataCacheEntryByMVA,
ArmDataCacheLineLength ());
return Address; return Address;
} }
@ -116,6 +125,7 @@ InvalidateDataCacheRange (
IN UINTN Length IN UINTN Length
) )
{ {
CacheRangeOperation(Address, Length, ArmInvalidateDataCacheEntryByMVA); CacheRangeOperation(Address, Length, ArmInvalidateDataCacheEntryByMVA,
ArmDataCacheLineLength ());
return Address; return Address;
} }

View File

@ -23,6 +23,7 @@ GCC_ASM_EXPORT (ArmInvalidateInstructionCache)
GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA)
GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA)
GCC_ASM_EXPORT (ArmCleanDataCacheEntryToPoUByMVA) GCC_ASM_EXPORT (ArmCleanDataCacheEntryToPoUByMVA)
GCC_ASM_EXPORT (ArmInvalidateInstructionCacheEntryToPoUByMVA)
GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA)
GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay) GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay)
GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay) GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay)
@ -80,6 +81,10 @@ ASM_PFX(ArmCleanDataCacheEntryToPoUByMVA):
dc cvau, x0 // Clean single data cache line to PoU dc cvau, x0 // Clean single data cache line to PoU
ret ret
ASM_PFX(ArmInvalidateInstructionCacheEntryToPoUByMVA):
ic ivau, x0 // Invalidate single instruction cache line to PoU
ret
ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA): ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):
dc civac, x0 // Clean and invalidate single data cache line dc civac, x0 // Clean and invalidate single data cache line

View File

@ -18,6 +18,7 @@
GCC_ASM_EXPORT (ArmInvalidateInstructionCache) GCC_ASM_EXPORT (ArmInvalidateInstructionCache)
GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA)
GCC_ASM_EXPORT (ArmInvalidateInstructionCacheEntryToPoUByMVA)
GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA)
GCC_ASM_EXPORT (ArmCleanDataCacheEntryToPoUByMVA) GCC_ASM_EXPORT (ArmCleanDataCacheEntryToPoUByMVA)
GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA) GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA)
@ -74,6 +75,10 @@ ASM_PFX(ArmCleanDataCacheEntryToPoUByMVA):
mcr p15, 0, r0, c7, c11, 1 @clean single data cache line to PoU mcr p15, 0, r0, c7, c11, 1 @clean single data cache line to PoU
bx lr bx lr
ASM_PFX(ArmInvalidateInstructionCacheEntryToPoUByMVA):
mcr p15, 0, r0, c7, c5, 1 @Invalidate single instruction cache line to PoU
mcr p15, 0, r0, c7, c5, 7 @Invalidate branch predictor
bx lr
ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA): ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):
mcr p15, 0, r0, c7, c14, 1 @clean and invalidate single data cache line mcr p15, 0, r0, c7, c14, 1 @clean and invalidate single data cache line

View File

@ -34,6 +34,12 @@ CTRL_I_BIT EQU (1 << 12)
bx lr bx lr
RVCT_ASM_EXPORT ArmInvalidateInstructionCacheEntryToPoUByMVA
mcr p15, 0, r0, c7, c5, 1 ; invalidate single instruction cache line to PoU
mcr p15, 0, r0, c7, c5, 7 ; invalidate branch predictor
bx lr
RVCT_ASM_EXPORT ArmCleanDataCacheEntryToPoUByMVA RVCT_ASM_EXPORT ArmCleanDataCacheEntryToPoUByMVA
mcr p15, 0, r0, c7, c11, 1 ; clean single data cache line to PoU mcr p15, 0, r0, c7, c11, 1 ; clean single data cache line to PoU
bx lr bx lr