All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] [MIPS] Fix I-/D-cache initialization loops
Date: Mon, 17 Mar 2008 23:47:39 +0900	[thread overview]
Message-ID: <47DE848B.7050300@ruby.dti.ne.jp> (raw)

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@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)
 
 /*******************************************************************************

                 reply	other threads:[~2008-03-17 14:47 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47DE848B.7050300@ruby.dti.ne.jp \
    --to=skuribay@ruby.dti.ne.jp \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.