aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/cache.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common/cache.S')
-rw-r--r--arch/blackfin/mach-common/cache.S46
1 files changed, 15 insertions, 31 deletions
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S
index aa0648c6a9fe..d9666fe6c3d6 100644
--- a/arch/blackfin/mach-common/cache.S
+++ b/arch/blackfin/mach-common/cache.S
@@ -15,6 +15,13 @@
15 15
16.text 16.text
17 17
18/* 05000443 - IFLUSH cannot be last instruction in hardware loop */
19#if ANOMALY_05000443
20# define BROK_FLUSH_INST "IFLUSH"
21#else
22# define BROK_FLUSH_INST "no anomaly! yeah!"
23#endif
24
18/* Since all L1 caches work the same way, we use the same method for flushing 25/* Since all L1 caches work the same way, we use the same method for flushing
19 * them. Only the actual flush instruction differs. We write this in asm as 26 * them. Only the actual flush instruction differs. We write this in asm as
20 * GCC can be hard to coax into writing nice hardware loops. 27 * GCC can be hard to coax into writing nice hardware loops.
@@ -23,7 +30,7 @@
23 * R0 = start address 30 * R0 = start address
24 * R1 = end address 31 * R1 = end address
25 */ 32 */
26.macro do_flush flushins:req optflushins optnopins label 33.macro do_flush flushins:req label
27 34
28 R2 = -L1_CACHE_BYTES; 35 R2 = -L1_CACHE_BYTES;
29 36
@@ -44,22 +51,15 @@
44\label : 51\label :
45.endif 52.endif
46 P0 = R0; 53 P0 = R0;
54
47 LSETUP (1f, 2f) LC1 = P1; 55 LSETUP (1f, 2f) LC1 = P1;
481: 561:
49.ifnb \optflushins 57.ifeqs "\flushins", BROK_FLUSH_INST
50 \optflushins [P0];
51.endif
52#if ANOMALY_05000443
53.ifb \optnopins
542:
55.endif
56 \flushins [P0++]; 58 \flushins [P0++];
57.ifnb \optnopins 592: nop;
582: \optnopins; 60.else
59.endif
60#else
612: \flushins [P0++]; 612: \flushins [P0++];
62#endif 62.endif
63 63
64 RTS; 64 RTS;
65.endm 65.endm
@@ -77,25 +77,9 @@ ENTRY(_blackfin_icache_flush_range)
77 */ 77 */
78 P0 = R0; 78 P0 = R0;
79 IFLUSH[P0]; 79 IFLUSH[P0];
80 do_flush IFLUSH, , nop 80 do_flush IFLUSH
81ENDPROC(_blackfin_icache_flush_range) 81ENDPROC(_blackfin_icache_flush_range)
82 82
83/* Flush all cache lines assocoiated with this area of memory. */
84ENTRY(_blackfin_icache_dcache_flush_range)
85/*
86 * Walkaround to avoid loading wrong instruction after invalidating icache
87 * and following sequence is met.
88 *
89 * 1) One instruction address is cached in the instruction cache.
90 * 2) This instruction in SDRAM is changed.
91 * 3) IFLASH[P0] is executed only once in blackfin_icache_flush_range().
92 * 4) This instruction is executed again, but the old one is loaded.
93 */
94 P0 = R0;
95 IFLUSH[P0];
96 do_flush FLUSH, IFLUSH
97ENDPROC(_blackfin_icache_dcache_flush_range)
98
99/* Throw away all D-cached data in specified region without any obligation to 83/* Throw away all D-cached data in specified region without any obligation to
100 * write them back. Since the Blackfin ISA does not have an "invalidate" 84 * write them back. Since the Blackfin ISA does not have an "invalidate"
101 * instruction, we use flush/invalidate. Perhaps as a speed optimization we 85 * instruction, we use flush/invalidate. Perhaps as a speed optimization we
@@ -107,7 +91,7 @@ ENDPROC(_blackfin_dcache_invalidate_range)
107 91
108/* Flush all data cache lines assocoiated with this memory area */ 92/* Flush all data cache lines assocoiated with this memory area */
109ENTRY(_blackfin_dcache_flush_range) 93ENTRY(_blackfin_dcache_flush_range)
110 do_flush FLUSH, , , .Ldfr 94 do_flush FLUSH, .Ldfr
111ENDPROC(_blackfin_dcache_flush_range) 95ENDPROC(_blackfin_dcache_flush_range)
112 96
113/* Our headers convert the page structure to an address, so just need to flush 97/* Our headers convert the page structure to an address, so just need to flush