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

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)
/*******************************************************************************
participants (1)
-
Shinya Kuribayashi