aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2013-10-18 17:06:03 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-10-29 07:06:23 -0400
commit39792c7cf3111d69dc4aa0923859d8b929e9039f (patch)
tree97e96f823d34ba2324efeafa5541893b062f112c /arch/arm/include
parent3c8828f6a0cb3bf1bae04a98135da3c53e20c217 (diff)
ARM: 7861/1: cacheflush: consolidate single-CPU ARMv7 cache disabling code
This code is becoming duplicated in many places. So let's consolidate it into a handy macro that is known to be right and available for reuse. Signed-off-by: Nicolas Pitre <nico@linaro.org> Acked-by: Dave Martin <Dave.Martin@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/cacheflush.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 15f2d5bf8875..ee753f1749cd 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -435,4 +435,50 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
435#define sync_cache_w(ptr) __sync_cache_range_w(ptr, sizeof *(ptr)) 435#define sync_cache_w(ptr) __sync_cache_range_w(ptr, sizeof *(ptr))
436#define sync_cache_r(ptr) __sync_cache_range_r(ptr, sizeof *(ptr)) 436#define sync_cache_r(ptr) __sync_cache_range_r(ptr, sizeof *(ptr))
437 437
438/*
439 * Disabling cache access for one CPU in an ARMv7 SMP system is tricky.
440 * To do so we must:
441 *
442 * - Clear the SCTLR.C bit to prevent further cache allocations
443 * - Flush the desired level of cache
444 * - Clear the ACTLR "SMP" bit to disable local coherency
445 *
446 * ... and so without any intervening memory access in between those steps,
447 * not even to the stack.
448 *
449 * WARNING -- After this has been called:
450 *
451 * - No ldrex/strex (and similar) instructions must be used.
452 * - The CPU is obviously no longer coherent with the other CPUs.
453 * - This is unlikely to work as expected if Linux is running non-secure.
454 *
455 * Note:
456 *
457 * - This is known to apply to several ARMv7 processor implementations,
458 * however some exceptions may exist. Caveat emptor.
459 *
460 * - The clobber list is dictated by the call to v7_flush_dcache_*.
461 * fp is preserved to the stack explicitly prior disabling the cache
462 * since adding it to the clobber list is incompatible with having
463 * CONFIG_FRAME_POINTER=y. ip is saved as well if ever r12-clobbering
464 * trampoline are inserted by the linker and to keep sp 64-bit aligned.
465 */
466#define v7_exit_coherency_flush(level) \
467 asm volatile( \
468 "stmfd sp!, {fp, ip} \n\t" \
469 "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR \n\t" \
470 "bic r0, r0, #"__stringify(CR_C)" \n\t" \
471 "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR \n\t" \
472 "isb \n\t" \
473 "bl v7_flush_dcache_"__stringify(level)" \n\t" \
474 "clrex \n\t" \
475 "mrc p15, 0, r0, c1, c0, 1 @ get ACTLR \n\t" \
476 "bic r0, r0, #(1 << 6) @ disable local coherency \n\t" \
477 "mcr p15, 0, r0, c1, c0, 1 @ set ACTLR \n\t" \
478 "isb \n\t" \
479 "dsb \n\t" \
480 "ldmfd sp!, {fp, ip}" \
481 : : : "r0","r1","r2","r3","r4","r5","r6","r7", \
482 "r9","r10","lr","memory" )
483
438#endif 484#endif