|
@@ -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,7 +77,7 @@ ENTRY(_blackfin_icache_flush_range)
|
|
|
*/
|
|
|
P0 = R0;
|
|
|
IFLUSH[P0];
|
|
|
- do_flush IFLUSH, , nop
|
|
|
+ do_flush IFLUSH
|
|
|
ENDPROC(_blackfin_icache_flush_range)
|
|
|
|
|
|
/* Throw away all D-cached data in specified region without any obligation to
|
|
@@ -91,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
|