diff options
Diffstat (limited to 'arch/arm/mm/cache-v6.S')
-rw-r--r-- | arch/arm/mm/cache-v6.S | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 2c6c2a7c05a0..8f5c13f4c936 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -20,6 +20,31 @@ #define D_CACHE_LINE_SIZE 32 #define BTB_FLUSH_SIZE 8 +#ifdef CONFIG_ARM_ERRATA_411920 +/* + * Invalidate the entire I cache (this code is a workaround for the ARM1136 + * erratum 411920 - Invalidate Instruction Cache operation can fail. This + * erratum is present in 1136, 1156 and 1176. It does not affect the MPCore. + * + * Registers: + * r0 - set to 0 + * r1 - corrupted + */ +ENTRY(v6_icache_inval_all) + mov r0, #0 + mrs r1, cpsr + cpsid ifa @ disable interrupts + mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache + mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache + mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache + mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache + msr cpsr_cx, r1 @ restore interrupts + .rept 11 @ ARM Ltd recommends at least + nop @ 11 NOPs + .endr + mov pc, lr +#endif + /* * v6_flush_cache_all() * @@ -31,8 +56,12 @@ ENTRY(v6_flush_kern_cache_all) mov r0, #0 #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c14, 0 @ D cache clean+invalidate +#ifndef CONFIG_ARM_ERRATA_411920 mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate #else + b v6_icache_inval_all +#endif +#else mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate #endif mov pc, lr @@ -103,8 +132,12 @@ ENTRY(v6_coherent_user_range) mov r0, #0 #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c10, 4 @ drain write buffer +#ifndef CONFIG_ARM_ERRATA_411920 mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate #else + b v6_icache_inval_all +#endif +#else mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB #endif mov pc, lr |