* [U-Boot-Users] [MIPS] Fix I-/D-cache initialization loops
@ 2008-03-17 14:47 Shinya Kuribayashi
0 siblings, 0 replies; only message in thread
From: Shinya Kuribayashi @ 2008-03-17 14:47 UTC (permalink / raw)
To: u-boot
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)
/*******************************************************************************
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2008-03-17 14:47 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-17 14:47 [U-Boot-Users] [MIPS] Fix I-/D-cache initialization loops Shinya Kuribayashi
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.