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 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; |
48 | 1: | 56 | 1: |
49 | .ifnb \optflushins | 57 | .ifeqs "\flushins", BROK_FLUSH_INST |
50 | \optflushins [P0]; | ||
51 | .endif | ||
52 | #if ANOMALY_05000443 | ||
53 | .ifb \optnopins | ||
54 | 2: | ||
55 | .endif | ||
56 | \flushins [P0++]; | 58 | \flushins [P0++]; |
57 | .ifnb \optnopins | 59 | 2: nop; |
58 | 2: \optnopins; | 60 | .else |
59 | .endif | ||
60 | #else | ||
61 | 2: \flushins [P0++]; | 61 | 2: \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 |
81 | ENDPROC(_blackfin_icache_flush_range) | 81 | ENDPROC(_blackfin_icache_flush_range) |
82 | 82 | ||
83 | /* Flush all cache lines assocoiated with this area of memory. */ | ||
84 | ENTRY(_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 | ||
97 | ENDPROC(_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 */ |
109 | ENTRY(_blackfin_dcache_flush_range) | 93 | ENTRY(_blackfin_dcache_flush_range) |
110 | do_flush FLUSH, , , .Ldfr | 94 | do_flush FLUSH, .Ldfr |
111 | ENDPROC(_blackfin_dcache_flush_range) | 95 | ENDPROC(_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 |