diff options
Diffstat (limited to 'arch/blackfin/mach-common/cache.S')
| -rw-r--r-- | arch/blackfin/mach-common/cache.S | 46 | 
1 files changed, 15 insertions, 31 deletions
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S index aa0648c6a9f..d9666fe6c3d 100644 --- a/arch/blackfin/mach-common/cache.S +++ b/arch/blackfin/mach-common/cache.S @@ -15,6 +15,13 @@  .text +/* 05000443 - IFLUSH cannot be last instruction in hardware loop */ +#if ANOMALY_05000443 +# define BROK_FLUSH_INST "IFLUSH" +#else +# define BROK_FLUSH_INST "no anomaly! yeah!" +#endif +  /* Since all L1 caches work the same way, we use the same method for flushing   * them.  Only the actual flush instruction differs.  We write this in asm as   * GCC can be hard to coax into writing nice hardware loops. @@ -23,7 +30,7 @@   * R0 = start address   * R1 = end address   */ -.macro do_flush flushins:req optflushins optnopins label +.macro do_flush flushins:req label  	R2 = -L1_CACHE_BYTES; @@ -44,22 +51,15 @@  \label :  .endif  	P0 = R0; +  	LSETUP (1f, 2f) LC1 = P1;  1: -.ifnb \optflushins -	\optflushins [P0]; -.endif -#if ANOMALY_05000443 -.ifb \optnopins -2: -.endif +.ifeqs "\flushins", BROK_FLUSH_INST  	\flushins [P0++]; -.ifnb \optnopins -2:	\optnopins; -.endif -#else +2:	nop; +.else  2:	\flushins [P0++]; -#endif +.endif  	RTS;  .endm @@ -77,25 +77,9 @@ ENTRY(_blackfin_icache_flush_range)   */  	P0 = R0;  	IFLUSH[P0]; -	do_flush IFLUSH, , nop +	do_flush IFLUSH  ENDPROC(_blackfin_icache_flush_range) -/* Flush all cache lines assocoiated with this area of memory. */ -ENTRY(_blackfin_icache_dcache_flush_range) -/* - * Walkaround to avoid loading wrong instruction after invalidating icache - * and following sequence is met. - * - * 1) One instruction address is cached in the instruction cache. - * 2) This instruction in SDRAM is changed. - * 3) IFLASH[P0] is executed only once in blackfin_icache_flush_range(). - * 4) This instruction is executed again, but the old one is loaded. - */ -	P0 = R0; -	IFLUSH[P0]; -	do_flush FLUSH, IFLUSH -ENDPROC(_blackfin_icache_dcache_flush_range) -  /* Throw away all D-cached data in specified region without any obligation to   * write them back.  Since the Blackfin ISA does not have an "invalidate"   * instruction, we use flush/invalidate.  Perhaps as a speed optimization we @@ -107,7 +91,7 @@ ENDPROC(_blackfin_dcache_invalidate_range)  /* Flush all data cache lines assocoiated with this memory area */  ENTRY(_blackfin_dcache_flush_range) -	do_flush FLUSH, , , .Ldfr +	do_flush FLUSH, .Ldfr  ENDPROC(_blackfin_dcache_flush_range)  /* Our headers convert the page structure to an address, so just need to flush  |