diff options
Diffstat (limited to 'arch/arm/mm/cache-v7.S')
| -rw-r--r-- | arch/arm/mm/cache-v7.S | 46 | 
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 7539ec27506..15451ee4acc 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -19,6 +19,52 @@  #include "proc-macros.S"  /* + * The secondary kernel init calls v7_flush_dcache_all before it enables + * the L1; however, the L1 comes out of reset in an undefined state, so + * the clean + invalidate performed by v7_flush_dcache_all causes a bunch + * of cache lines with uninitialized data and uninitialized tags to get + * written out to memory, which does really unpleasant things to the main + * processor.  We fix this by performing an invalidate, rather than a + * clean + invalidate, before jumping into the kernel. + * + * This function is cloned from arch/arm/mach-tegra/headsmp.S, and needs + * to be called for both secondary cores startup and primary core resume + * procedures. + */ +ENTRY(v7_invalidate_l1) +       mov     r0, #0 +       mcr     p15, 2, r0, c0, c0, 0 +       mrc     p15, 1, r0, c0, c0, 0 + +       ldr     r1, =0x7fff +       and     r2, r1, r0, lsr #13 + +       ldr     r1, =0x3ff + +       and     r3, r1, r0, lsr #3      @ NumWays - 1 +       add     r2, r2, #1              @ NumSets + +       and     r0, r0, #0x7 +       add     r0, r0, #4      @ SetShift + +       clz     r1, r3          @ WayShift +       add     r4, r3, #1      @ NumWays +1:     sub     r2, r2, #1      @ NumSets-- +       mov     r3, r4          @ Temp = NumWays +2:     subs    r3, r3, #1      @ Temp-- +       mov     r5, r3, lsl r1 +       mov     r6, r2, lsl r0 +       orr     r5, r5, r6      @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) +       mcr     p15, 0, r5, c7, c6, 2 +       bgt     2b +       cmp     r2, #0 +       bgt     1b +       dsb +       isb +       mov     pc, lr +ENDPROC(v7_invalidate_l1) + +/*   *	v7_flush_icache_all()   *   *	Flush the whole I-cache.  |