diff options
| author | Shinya Kuribayashi <skuribay@ruby.dti.ne.jp> | 2008-03-25 21:30:06 +0900 | 
|---|---|---|
| committer | Shinya Kuribayashi <skuribay@ruby.dti.ne.jp> | 2008-03-25 21:30:06 +0900 | 
| commit | 2e0e5271aac917812a76c72030a2b2c6f1d3387d (patch) | |
| tree | d2f724aa31ea7d3696170910069b6168437c7b0f | |
| parent | 1898840797c7f50799377bd5b285a8a93a82c419 (diff) | |
| download | olio-uboot-2014.01-2e0e5271aac917812a76c72030a2b2c6f1d3387d.tar.xz olio-uboot-2014.01-2e0e5271aac917812a76c72030a2b2c6f1d3387d.zip | |
[MIPS] Fix I-/D-cache initialization loops
Currently we 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're encouraged to use three separate loops rather than combining
them *for both I- and D-cache*. This patch tries to fix this.
In accordance with fixing above, mips_init_[id]cache are separated from
mips_cache_reset(), and rewrite cache loops are completely rewritten with
useful macros.
Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
| -rw-r--r-- | 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 6d39ba9aa..bb4261692 100644 --- a/cpu/mips/cache.S +++ b/cpu/mips/cache.S @@ -30,11 +30,23 @@  #include <asm/addrspace.h>  #include <asm/cacheops.h> +#define RA		t8 +  	/* 16KB is the maximum size of instruction and data caches on  	 * MIPS 4K.  	 */  #define MIPS_MAX_CACHE_SIZE	0x4000 +#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   * 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 +	jr	RA  	END(mips_cache_reset)  /******************************************************************************* |