summaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2009-03-05 18:26:59 +0800
committerBryan Wu <cooloney@kernel.org>2009-03-05 18:26:59 +0800
commitd7ff1a90b2d3d122b896056d63db919617e9b6cd (patch)
tree5edcc57036c26f41fad67884267f0e2aa2f3d021 /arch/blackfin
parentc19577e34e641f802ad35fc0204ff68ea16fe7a3 (diff)
Blackfin arch: Fix bug - KGDB single step into the middle of a 4 bytes instruction on bf561 after soft bp is hit
Run IFLUSH twice to avoid loading wrong instruction after invalidating icache and following sequence is met. 1) The one instruction address is cached in the icache. 2) This instruction in SDRAM is changed. 3) IFLASH[P0] is executed only once in lackfin_icache_flush_range(). 4) This instruction is executed again, but not the changed new one. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/mach-common/cache.S22
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S
index 3c98dacbf28..aa0648c6a9f 100644
--- a/arch/blackfin/mach-common/cache.S
+++ b/arch/blackfin/mach-common/cache.S
@@ -66,11 +66,33 @@
/* Invalidate all instruction cache lines assocoiated with this memory area */
ENTRY(_blackfin_icache_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 IFLUSH, , nop
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)