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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox