ARM: mm: implement LoUIS API for cache maintenance ops
ARM v7 architecture introduced the concept of cache levels and related control registers. New processors like A7 and A15 embed an L2 unified cache controller that becomes part of the cache level hierarchy. Some operations in the kernel like cpu_suspend and __cpu_disable do not require a flush of the entire cache hierarchy to DRAM but just the cache levels belonging to the Level of Unification Inner Shareable (LoUIS), which in most of ARM v7 systems correspond to L1. The current cache flushing API used in cpu_suspend and __cpu_disable, flush_cache_all(), ends up flushing the whole cache hierarchy since for v7 it cleans and invalidates all cache levels up to Level of Coherency (LoC) which cripples system performance when used in hot paths like hotplug and cpuidle. Therefore a new kernel cache maintenance API must be added to cope with latest ARM system requirements. This patch adds flush_cache_louis() to the ARM kernel cache maintenance API. This function cleans and invalidates all data cache levels up to the Level of Unification Inner Shareable (LoUIS) and invalidates the instruction cache for processors that support it (> v7). This patch also creates an alias of the cache LoUIS function to flush_kern_all for all processor versions prior to v7, so that the current cache flushing behaviour is unchanged for those processors. v7 cache maintenance code implements a cache LoUIS function that cleans and invalidates the D-cache up to LoUIS and invalidates the I-cache, according to the new API. Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Tested-by: Shawn Guo <shawn.guo@linaro.org>
This commit is contained in:
parent
5698bd757d
commit
031bd879f7
24 changed files with 113 additions and 0 deletions
|
@ -49,6 +49,13 @@
|
|||
*
|
||||
* Unconditionally clean and invalidate the entire cache.
|
||||
*
|
||||
* flush_kern_louis()
|
||||
*
|
||||
* Flush data cache levels up to the level of unification
|
||||
* inner shareable and invalidate the I-cache.
|
||||
* Only needed from v7 onwards, falls back to flush_cache_all()
|
||||
* for all other processor versions.
|
||||
*
|
||||
* flush_user_all()
|
||||
*
|
||||
* Clean and invalidate all user space cache entries
|
||||
|
@ -97,6 +104,7 @@
|
|||
struct cpu_cache_fns {
|
||||
void (*flush_icache_all)(void);
|
||||
void (*flush_kern_all)(void);
|
||||
void (*flush_kern_louis)(void);
|
||||
void (*flush_user_all)(void);
|
||||
void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
|
||||
|
||||
|
@ -119,6 +127,7 @@ extern struct cpu_cache_fns cpu_cache;
|
|||
|
||||
#define __cpuc_flush_icache_all cpu_cache.flush_icache_all
|
||||
#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
|
||||
#define __cpuc_flush_kern_louis cpu_cache.flush_kern_louis
|
||||
#define __cpuc_flush_user_all cpu_cache.flush_user_all
|
||||
#define __cpuc_flush_user_range cpu_cache.flush_user_range
|
||||
#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
|
||||
|
@ -139,6 +148,7 @@ extern struct cpu_cache_fns cpu_cache;
|
|||
|
||||
extern void __cpuc_flush_icache_all(void);
|
||||
extern void __cpuc_flush_kern_all(void);
|
||||
extern void __cpuc_flush_kern_louis(void);
|
||||
extern void __cpuc_flush_user_all(void);
|
||||
extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
|
||||
extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
|
||||
|
@ -204,6 +214,11 @@ static inline void __flush_icache_all(void)
|
|||
__flush_icache_preferred();
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush caches up to Level of Unification Inner Shareable
|
||||
*/
|
||||
#define flush_cache_louis() __cpuc_flush_kern_louis()
|
||||
|
||||
#define flush_cache_all() __cpuc_flush_kern_all()
|
||||
|
||||
static inline void vivt_flush_cache_mm(struct mm_struct *mm)
|
||||
|
|
|
@ -132,6 +132,7 @@
|
|||
#ifndef MULTI_CACHE
|
||||
#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
|
||||
#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
|
||||
#define __cpuc_flush_kern_louis __glue(_CACHE,_flush_kern_cache_louis)
|
||||
#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
|
||||
#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
|
||||
#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
|
||||
|
|
|
@ -240,6 +240,9 @@ ENTRY(fa_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(fa_dma_unmap_area)
|
||||
|
||||
.globl fa_flush_kern_cache_louis
|
||||
.equ fa_flush_kern_cache_louis, fa_flush_kern_cache_all
|
||||
|
||||
__INITDATA
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
|
|
|
@ -128,6 +128,9 @@ ENTRY(v3_dma_map_area)
|
|||
ENDPROC(v3_dma_unmap_area)
|
||||
ENDPROC(v3_dma_map_area)
|
||||
|
||||
.globl v3_flush_kern_cache_louis
|
||||
.equ v3_flush_kern_cache_louis, v3_flush_kern_cache_all
|
||||
|
||||
__INITDATA
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
|
|
|
@ -140,6 +140,9 @@ ENTRY(v4_dma_map_area)
|
|||
ENDPROC(v4_dma_unmap_area)
|
||||
ENDPROC(v4_dma_map_area)
|
||||
|
||||
.globl v4_flush_kern_cache_louis
|
||||
.equ v4_flush_kern_cache_louis, v4_flush_kern_cache_all
|
||||
|
||||
__INITDATA
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
|
|
|
@ -251,6 +251,9 @@ ENTRY(v4wb_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(v4wb_dma_unmap_area)
|
||||
|
||||
.globl v4wb_flush_kern_cache_louis
|
||||
.equ v4wb_flush_kern_cache_louis, v4wb_flush_kern_cache_all
|
||||
|
||||
__INITDATA
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
|
|
|
@ -196,6 +196,9 @@ ENTRY(v4wt_dma_map_area)
|
|||
ENDPROC(v4wt_dma_unmap_area)
|
||||
ENDPROC(v4wt_dma_map_area)
|
||||
|
||||
.globl v4wt_flush_kern_cache_louis
|
||||
.equ v4wt_flush_kern_cache_louis, v4wt_flush_kern_cache_all
|
||||
|
||||
__INITDATA
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
|
|
|
@ -326,6 +326,9 @@ ENTRY(v6_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(v6_dma_unmap_area)
|
||||
|
||||
.globl v6_flush_kern_cache_louis
|
||||
.equ v6_flush_kern_cache_louis, v6_flush_kern_cache_all
|
||||
|
||||
__INITDATA
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
|
|
|
@ -33,6 +33,24 @@ ENTRY(v7_flush_icache_all)
|
|||
mov pc, lr
|
||||
ENDPROC(v7_flush_icache_all)
|
||||
|
||||
/*
|
||||
* v7_flush_dcache_louis()
|
||||
*
|
||||
* Flush the D-cache up to the Level of Unification Inner Shareable
|
||||
*
|
||||
* Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
|
||||
*/
|
||||
|
||||
ENTRY(v7_flush_dcache_louis)
|
||||
dmb @ ensure ordering with previous memory accesses
|
||||
mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr
|
||||
ands r3, r0, #0xe00000 @ extract LoUIS from clidr
|
||||
mov r3, r3, lsr #20 @ r3 = LoUIS * 2
|
||||
moveq pc, lr @ return if level == 0
|
||||
mov r10, #0 @ r10 (starting level) = 0
|
||||
b loop1 @ start flushing cache levels
|
||||
ENDPROC(v7_flush_dcache_louis)
|
||||
|
||||
/*
|
||||
* v7_flush_dcache_all()
|
||||
*
|
||||
|
@ -120,6 +138,24 @@ ENTRY(v7_flush_kern_cache_all)
|
|||
mov pc, lr
|
||||
ENDPROC(v7_flush_kern_cache_all)
|
||||
|
||||
/*
|
||||
* v7_flush_kern_cache_louis(void)
|
||||
*
|
||||
* Flush the data cache up to Level of Unification Inner Shareable.
|
||||
* Invalidate the I-cache to the point of unification.
|
||||
*/
|
||||
ENTRY(v7_flush_kern_cache_louis)
|
||||
ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
|
||||
THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
|
||||
bl v7_flush_dcache_louis
|
||||
mov r0, #0
|
||||
ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
|
||||
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
|
||||
ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
|
||||
THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
|
||||
mov pc, lr
|
||||
ENDPROC(v7_flush_kern_cache_louis)
|
||||
|
||||
/*
|
||||
* v7_flush_cache_all()
|
||||
*
|
||||
|
|
|
@ -368,6 +368,9 @@ ENTRY(arm1020_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm1020_dma_unmap_area)
|
||||
|
||||
.globl arm1020_flush_kern_cache_louis
|
||||
.equ arm1020_flush_kern_cache_louis, arm1020_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm1020
|
||||
|
||||
|
|
|
@ -354,6 +354,9 @@ ENTRY(arm1020e_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm1020e_dma_unmap_area)
|
||||
|
||||
.globl arm1020e_flush_kern_cache_louis
|
||||
.equ arm1020e_flush_kern_cache_louis, arm1020e_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm1020e
|
||||
|
||||
|
|
|
@ -343,6 +343,9 @@ ENTRY(arm1022_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm1022_dma_unmap_area)
|
||||
|
||||
.globl arm1022_flush_kern_cache_louis
|
||||
.equ arm1022_flush_kern_cache_louis, arm1022_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm1022
|
||||
|
||||
|
|
|
@ -337,6 +337,9 @@ ENTRY(arm1026_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm1026_dma_unmap_area)
|
||||
|
||||
.globl arm1026_flush_kern_cache_louis
|
||||
.equ arm1026_flush_kern_cache_louis, arm1026_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm1026
|
||||
|
||||
|
|
|
@ -319,6 +319,9 @@ ENTRY(arm920_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm920_dma_unmap_area)
|
||||
|
||||
.globl arm920_flush_kern_cache_louis
|
||||
.equ arm920_flush_kern_cache_louis, arm920_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm920
|
||||
#endif
|
||||
|
|
|
@ -321,6 +321,9 @@ ENTRY(arm922_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm922_dma_unmap_area)
|
||||
|
||||
.globl arm922_flush_kern_cache_louis
|
||||
.equ arm922_flush_kern_cache_louis, arm922_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm922
|
||||
#endif
|
||||
|
|
|
@ -376,6 +376,9 @@ ENTRY(arm925_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm925_dma_unmap_area)
|
||||
|
||||
.globl arm925_flush_kern_cache_louis
|
||||
.equ arm925_flush_kern_cache_louis, arm925_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm925
|
||||
|
||||
|
|
|
@ -339,6 +339,9 @@ ENTRY(arm926_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm926_dma_unmap_area)
|
||||
|
||||
.globl arm926_flush_kern_cache_louis
|
||||
.equ arm926_flush_kern_cache_louis, arm926_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm926
|
||||
|
||||
|
|
|
@ -267,6 +267,9 @@ ENTRY(arm940_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm940_dma_unmap_area)
|
||||
|
||||
.globl arm940_flush_kern_cache_louis
|
||||
.equ arm940_flush_kern_cache_louis, arm940_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm940
|
||||
|
||||
|
|
|
@ -310,6 +310,9 @@ ENTRY(arm946_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(arm946_dma_unmap_area)
|
||||
|
||||
.globl arm946_flush_kern_cache_louis
|
||||
.equ arm946_flush_kern_cache_louis, arm946_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions arm946
|
||||
|
||||
|
|
|
@ -415,6 +415,9 @@ ENTRY(feroceon_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(feroceon_dma_unmap_area)
|
||||
|
||||
.globl feroceon_flush_kern_cache_louis
|
||||
.equ feroceon_flush_kern_cache_louis, feroceon_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions feroceon
|
||||
|
||||
|
|
|
@ -299,6 +299,7 @@ ENTRY(\name\()_processor_functions)
|
|||
ENTRY(\name\()_cache_fns)
|
||||
.long \name\()_flush_icache_all
|
||||
.long \name\()_flush_kern_cache_all
|
||||
.long \name\()_flush_kern_cache_louis
|
||||
.long \name\()_flush_user_cache_all
|
||||
.long \name\()_flush_user_cache_range
|
||||
.long \name\()_coherent_kern_range
|
||||
|
|
|
@ -303,6 +303,9 @@ ENTRY(mohawk_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(mohawk_dma_unmap_area)
|
||||
|
||||
.globl mohawk_flush_kern_cache_louis
|
||||
.equ mohawk_flush_kern_cache_louis, mohawk_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions mohawk
|
||||
|
||||
|
|
|
@ -337,6 +337,9 @@ ENTRY(xsc3_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(xsc3_dma_unmap_area)
|
||||
|
||||
.globl xsc3_flush_kern_cache_louis
|
||||
.equ xsc3_flush_kern_cache_louis, xsc3_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions xsc3
|
||||
|
||||
|
|
|
@ -410,6 +410,9 @@ ENTRY(xscale_dma_unmap_area)
|
|||
mov pc, lr
|
||||
ENDPROC(xscale_dma_unmap_area)
|
||||
|
||||
.globl xscale_flush_kern_cache_louis
|
||||
.equ xscale_flush_kern_cache_louis, xscale_flush_kern_cache_all
|
||||
|
||||
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
|
||||
define_cache_functions xscale
|
||||
|
||||
|
|
Loading…
Reference in a new issue