diff options
Diffstat (limited to 'cpu/mips/cache.S')
-rw-r--r-- | cpu/mips/cache.S | 209 |
1 files changed, 129 insertions, 80 deletions
diff --git a/cpu/mips/cache.S b/cpu/mips/cache.S index 443240e..89ada71 100644 --- a/cpu/mips/cache.S +++ b/cpu/mips/cache.S @@ -1,5 +1,5 @@ /* - * Cache-handling routined for MIPS 4K CPUs + * Cache-handling routined for MIPS CPUs * * Copyright (c) 2003 Wolfgang Denk <wd@denx.de> * @@ -24,15 +24,32 @@ #include <config.h> #include <version.h> +#include <asm/asm.h> #include <asm/regdef.h> #include <asm/mipsregs.h> #include <asm/addrspace.h> #include <asm/cacheops.h> - /* 16KB is the maximum size of instruction and data caches on - * MIPS 4K. - */ -#define MIPS_MAX_CACHE_SIZE 0x4000 +#define RA t8 + +/* + * 16kB is the maximum size of instruction and data caches on MIPS 4K, + * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience. + * + * Note that the above size is the maximum size of primary cache. U-Boot + * doesn't have L2 cache support for now. + */ +#define MIPS_MAX_CACHE_SIZE 0x10000 + +#define INDEX_BASE KSEG0 + + .macro cache_op op addr + .set push + .set noreorder + .set mips3 + cache \op, 0(\addr) + .set pop + .endm /* * cacheop macro to automate cache operations @@ -103,6 +120,77 @@ #define icacheop(kva, n, cacheSize, cacheLineSize, op) \ icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op)) + .macro f_fill64 dst, offset, val + LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 2 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 3 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 4 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 5 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 6 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 7 * LONGSIZE)(\dst) +#if LONGSIZE == 4 + LONG_S \val, (\offset + 8 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 9 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 10 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 11 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 12 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 13 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 14 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 15 * LONGSIZE)(\dst) +#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 @@ -119,10 +207,8 @@ * RETURNS: N/A * */ - .globl mips_cache_reset - .ent mips_cache_reset -mips_cache_reset: - +NESTED(mips_cache_reset, 0, ra) + move RA, ra li t2, CFG_ICACHE_SIZE li t3, CFG_DCACHE_SIZE li t4, CFG_CACHELINE_SIZE @@ -130,27 +216,14 @@ mips_cache_reset: li v0, MIPS_MAX_CACHE_SIZE - /* Now clear that much memory starting from zero. - */ - - li a0, KSEG1 - addu a1, a0, v0 -2: - sw zero, 0(a0) - sw zero, 4(a0) - sw zero, 8(a0) - sw zero, 12(a0) - sw zero, 16(a0) - sw zero, 20(a0) - sw zero, 24(a0) - sw zero, 28(a0) - addu a0, 32 - bltu a0, a1, 2b - - /* Set invalid tag. + /* + * Now clear that much memory starting from zero. */ - - mtc0 zero, CP0_TAGLO + PTR_LI a0, KSEG1 + PTR_ADDU a1, a0, v0 +2: PTR_ADDIU a0, 64 + f_fill64 a0, -64, zero + bne a0, a1, 2b /* * The caches are probably in an indeterminate state, @@ -158,48 +231,26 @@ mips_cache_reset: * 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 - - .end mips_cache_reset + jr RA + END(mips_cache_reset) /******************************************************************************* * @@ -208,15 +259,15 @@ mips_cache_reset: * RETURNS: 0 - cache disabled; 1 - cache enabled * */ - .globl dcache_status - .ent dcache_status -dcache_status: - - mfc0 v0, CP0_CONFIG - andi v0, v0, 1 - j ra - - .end dcache_status +LEAF(dcache_status) + mfc0 t0, CP0_CONFIG + li t1, CONF_CM_UNCACHED + andi t0, t0, CONF_CM_CMASK + move v0, zero + beq t0, t1, 2f + li v0, 1 +2: jr ra + END(dcache_status) /******************************************************************************* * @@ -225,19 +276,16 @@ dcache_status: * RETURNS: N/A * */ - .globl dcache_disable - .ent dcache_disable -dcache_disable: - +LEAF(dcache_disable) mfc0 t0, CP0_CONFIG li t1, -8 and t0, t0, t1 ori t0, t0, CONF_CM_UNCACHED mtc0 t0, CP0_CONFIG j ra + END(dcache_disable) - .end dcache_disable - +#ifdef CFG_INIT_RAM_LOCK_MIPS /******************************************************************************* * * mips_cache_lock - lock RAM area pointed to by a0 in cache. @@ -263,3 +311,4 @@ mips_cache_lock: j ra .end mips_cache_lock +#endif /* CFG_INIT_RAM_LOCK_MIPS */ |