summaryrefslogtreecommitdiffstats
path: root/arch/mips/boot/compressed/cache.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/boot/compressed/cache.S')
-rw-r--r--arch/mips/boot/compressed/cache.S162
1 files changed, 162 insertions, 0 deletions
diff --git a/arch/mips/boot/compressed/cache.S b/arch/mips/boot/compressed/cache.S
new file mode 100644
index 000000000..8e7fff0c1
--- /dev/null
+++ b/arch/mips/boot/compressed/cache.S
@@ -0,0 +1,162 @@
+/*
+ * arch/mips/boot/compressed/cache.S
+ *
+ * Copyright (C) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle
+ *
+ * Flush instruction/data caches
+ *
+ * Parameters: a0 - starting address to flush
+ * a1 - size of area to be flushed
+ * a2 - which caches to be flushed
+ *
+ * FIXME: - ignores parameters in a0/a1
+ * - doesn't know about second level caches
+ */
+#include <linux/autoconf.h>
+
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/mipsregs.h>
+#include <asm/segment.h>
+
+#ifdef __R4000__
+
+/*
+ * Some bits in the config register
+ */
+#define CONFIG_IB (1<<5)
+#define CONFIG_DB (1<<4)
+
+ /*
+ * Flush instruction/data caches
+ *
+ * Parameters: a0 - starting address to flush
+ * a1 - size of area to be flushed
+ * a2 - which caches to be flushed
+ *
+ */
+
+ .text
+
+ .set noreorder
+ LEAF(cacheflush)
+ andi t1,a2,DCACHE
+ beqz t1,do_icache
+ li t0,KSEG0 # delay slot
+
+ /*
+ * Writeback data cache, even lines
+ */
+ li t1,CACHELINES-1
+1: cache Index_Writeback_Inv_D,0(t0)
+ cache Index_Writeback_Inv_D,32(t0)
+ cache Index_Writeback_Inv_D,64(t0)
+ cache Index_Writeback_Inv_D,96(t0)
+ cache Index_Writeback_Inv_D,128(t0)
+ cache Index_Writeback_Inv_D,160(t0)
+ cache Index_Writeback_Inv_D,192(t0)
+ cache Index_Writeback_Inv_D,224(t0)
+ cache Index_Writeback_Inv_D,256(t0)
+ cache Index_Writeback_Inv_D,288(t0)
+ cache Index_Writeback_Inv_D,320(t0)
+ cache Index_Writeback_Inv_D,352(t0)
+ cache Index_Writeback_Inv_D,384(t0)
+ cache Index_Writeback_Inv_D,416(t0)
+ cache Index_Writeback_Inv_D,448(t0)
+ cache Index_Writeback_Inv_D,480(t0)
+ addiu t0,512
+ bnez t1,1b
+ subu t1,1
+
+ /*
+ * Writeback data cache, odd lines
+ * Only needed for 16 byte line size
+ */
+ mfc0 t1,CP0_CONFIG
+ andi t1,CONFIG_IB
+ bnez t1,do_icache
+ li t1,CACHELINES-1
+1: cache Index_Writeback_Inv_D,16(t0)
+ cache Index_Writeback_Inv_D,48(t0)
+ cache Index_Writeback_Inv_D,80(t0)
+ cache Index_Writeback_Inv_D,112(t0)
+ cache Index_Writeback_Inv_D,144(t0)
+ cache Index_Writeback_Inv_D,176(t0)
+ cache Index_Writeback_Inv_D,208(t0)
+ cache Index_Writeback_Inv_D,240(t0)
+ cache Index_Writeback_Inv_D,272(t0)
+ cache Index_Writeback_Inv_D,304(t0)
+ cache Index_Writeback_Inv_D,336(t0)
+ cache Index_Writeback_Inv_D,368(t0)
+ cache Index_Writeback_Inv_D,400(t0)
+ cache Index_Writeback_Inv_D,432(t0)
+ cache Index_Writeback_Inv_D,464(t0)
+ cache Index_Writeback_Inv_D,496(t0)
+ addiu t0,512
+ bnez t1,1b
+ subu t1,1
+
+do_icache: andi t1,a2,ICACHE
+ beqz t1,done
+
+ /*
+ * Flush instruction cache, even lines
+ */
+ lui t0,0x8000
+ li t1,CACHELINES-1
+1: cache Index_Invalidate_I,0(t0)
+ cache Index_Invalidate_I,32(t0)
+ cache Index_Invalidate_I,64(t0)
+ cache Index_Invalidate_I,96(t0)
+ cache Index_Invalidate_I,128(t0)
+ cache Index_Invalidate_I,160(t0)
+ cache Index_Invalidate_I,192(t0)
+ cache Index_Invalidate_I,224(t0)
+ cache Index_Invalidate_I,256(t0)
+ cache Index_Invalidate_I,288(t0)
+ cache Index_Invalidate_I,320(t0)
+ cache Index_Invalidate_I,352(t0)
+ cache Index_Invalidate_I,384(t0)
+ cache Index_Invalidate_I,416(t0)
+ cache Index_Invalidate_I,448(t0)
+ cache Index_Invalidate_I,480(t0)
+ addiu t0,512
+ bnez t1,1b
+ subu t1,1
+
+ /*
+ * Flush instruction cache, even lines
+ * Only needed for 16 byte line size
+ */
+ mfc0 t1,CP0_CONFIG
+ andi t1,CONFIG_DB
+ bnez t1,done
+ li t1,CACHELINES-1
+1: cache Index_Invalidate_I,16(t0)
+ cache Index_Invalidate_I,48(t0)
+ cache Index_Invalidate_I,80(t0)
+ cache Index_Invalidate_I,112(t0)
+ cache Index_Invalidate_I,144(t0)
+ cache Index_Invalidate_I,176(t0)
+ cache Index_Invalidate_I,208(t0)
+ cache Index_Invalidate_I,240(t0)
+ cache Index_Invalidate_I,272(t0)
+ cache Index_Invalidate_I,304(t0)
+ cache Index_Invalidate_I,336(t0)
+ cache Index_Invalidate_I,368(t0)
+ cache Index_Invalidate_I,400(t0)
+ cache Index_Invalidate_I,432(t0)
+ cache Index_Invalidate_I,464(t0)
+ cache Index_Invalidate_I,496(t0)
+ addiu t0,512
+ bnez t1,1b
+ subu t1,1
+
+done: j ra
+ nop
+ END(sys_cacheflush)
+
+#else /* !defined (__R4000__) */
+#error "No R3000 cacheflushing implemented yet!"
+#endif /* !defined (__R4000__) */