[U-Boot-Users] [MIPS] Fix I-/D-cache initialization loops

Shinya Kuribayashi skuribay at ruby.dti.ne.jp
Mon Mar 17 15:47:39 CET 2008


We currently do 1) Index_Store_Tag_I, 2) Fill and 3) Index_Store_Tag_I
again per a loop for I-cache initialization. But according to 'See MIPS
Run', we are encouraged to use three separate loops rather than combining
them for both I- and D-cache. This patch tries to fix that.

In accordance with fixing above, mips_init_[id]cache are now separated
from mips_cache_reset() and cache loops are completely rewritten with
useful macros.

Signed-off-by: Shinya Kuribayashi <skuribay at ruby.dti.ne.jp>
---

 cpu/mips/cache.S |  115 ++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 76 insertions(+), 39 deletions(-)


diff --git a/cpu/mips/cache.S b/cpu/mips/cache.S
index d260e28..0842093 100644
--- a/cpu/mips/cache.S
+++ b/cpu/mips/cache.S
@@ -30,11 +30,23 @@
 #include <asm/addrspace.h>
 #include <asm/cacheops.h>
 
+#define t8		RA
+
 	/* 16KB is the maximum size of instruction and data caches on
 	 * MIPS 4K.
 	 */
 #define MIPS_MAX_CACHE_SIZE	0x4000
 
+#define INDEX_BASE	CKSEG0
+
+	.macro	cache_op op addr
+	.set	push
+	.set	noreorder
+	.set	mips3
+	cache	\op, 0(\addr)
+	.set	pop
+	.endm
+
 /*
  * cacheop macro to automate cache operations
  * first some helpers...
@@ -125,6 +137,56 @@
 #endif
 	.endm
 
+/*
+ * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
+ */
+LEAF(mips_init_icache)
+	blez	a1, 9f
+	mtc0	zero, CP0_TAGLO
+	/* clear tag to invalidate */
+	PTR_LI		t0, INDEX_BASE
+	PTR_ADDU	t1, t0, a1
+1:	cache_op	Index_Store_Tag_I t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 1b
+	/* fill once, so data field parity is correct */
+	PTR_LI		t0, INDEX_BASE
+2:	cache_op	Fill t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 2b
+	/* invalidate again - prudent but not strictly neccessary */
+	PTR_LI		t0, INDEX_BASE
+1:	cache_op	Index_Store_Tag_I t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 1b
+9:	jr	ra
+	END(mips_init_icache)
+
+/*
+ * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
+ */
+LEAF(mips_init_dcache)
+	blez	a1, 9f
+	mtc0	zero, CP0_TAGLO
+	/* clear all tags */
+	PTR_LI		t0, INDEX_BASE
+	PTR_ADDU	t1, t0, a1
+1:	cache_op	Index_Store_Tag_D t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 1b
+	/* load from each line (in cached space) */
+	PTR_LI		t0, INDEX_BASE
+2:	LONG_L		zero, 0(t0)
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 2b
+	/* clear all tags */
+	PTR_LI		t0, INDEX_BASE
+1:	cache_op	Index_Store_Tag_D t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 1b
+9:	jr	ra
+	END(mips_init_dcache)
+
 /*******************************************************************************
 *
 * mips_cache_reset - low level initialisation of the primary caches
@@ -142,6 +204,7 @@
 *
 */
 NESTED(mips_cache_reset, 0, ra)
+	move	RA, ra
 	li	t2, CFG_ICACHE_SIZE
 	li	t3, CFG_DCACHE_SIZE
 	li	t4, CFG_CACHELINE_SIZE
@@ -158,57 +221,31 @@ NESTED(mips_cache_reset, 0, ra)
 	f_fill64	a0, -64, zero
 	bne		a0, a1, 2b
 
-	/* Set invalid tag.
-	 */
-
-	mtc0	zero, CP0_TAGLO
-
 	/*
 	 * The caches are probably in an indeterminate state,
 	 * so we force good parity into them by doing an
 	 * invalidate, load/fill, invalidate for each line.
 	 */
 
-	/* Assume bottom of RAM will generate good parity for the cache.
-	 */
-
-	li	a0, K0BASE
-	move	a2, t2		# icacheSize
-	move	a3, t4		# icacheLineSize
-	move	a1, a2
-	icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill))
-
-	/* To support Orion/R4600, we initialise the data cache in 3 passes.
-	 */
-
-	/* 1: initialise dcache tags.
+	/*
+	 * Assume bottom of RAM will generate good parity for the cache.
 	 */
 
-	li	a0, K0BASE
-	move	a2, t3		# dcacheSize
-	move	a3, t5		# dcacheLineSize
-	move	a1, a2
-	icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
-
-	/* 2: fill dcache.
+	/*
+	 * Initialize the I-cache first,
 	 */
+	move	a1, t2
+	move	a2, t4
+	bal	mips_init_icache
 
-	li	a0, K0BASE
-	move	a2, t3		# dcacheSize
-	move	a3, t5		# dcacheLineSize
-	move	a1, a2
-	icacheopn(a0,a1,a2,a3,1lw,(dummy))
-
-	/* 3: clear dcache tags.
+	/*
+	 * then initialize D-cache.
 	 */
+	move	a1, t3
+	move	a2, t5
+	bal	mips_init_dcache
 
-	li	a0, K0BASE
-	move	a2, t3		# dcacheSize
-	move	a3, t5		# dcacheLineSize
-	move	a1, a2
-	icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
-
-	j	ra
+	j	RA
 	END(mips_cache_reset)
 
 /*******************************************************************************




More information about the U-Boot mailing list