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 | ccf8f824ef67df028dedb29f8ea5d71a5a88d895 (patch) | |
| tree | b051a88092123b0877caa5aa0e5641282c2b99be | |
| parent | 2e0e5271aac917812a76c72030a2b2c6f1d3387d (diff) | |
| download | olio-uboot-2014.01-ccf8f824ef67df028dedb29f8ea5d71a5a88d895.tar.xz olio-uboot-2014.01-ccf8f824ef67df028dedb29f8ea5d71a5a88d895.zip | |
[MIPS] Implement flush_cache()
We do Hit_Writeback_Inv_D and Hit_Invalidate_I. You might think that you
don't need to do Hit_Invalidate_I, but flush_cache() needs it since this
function is used not only in U-Boot specfic programs but also at loading
target binaries.
Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
| -rw-r--r-- | cpu/mips/cpu.c | 22 | 
1 files changed, 22 insertions, 0 deletions
| diff --git a/cpu/mips/cpu.c b/cpu/mips/cpu.c index 7559ac657..de70c4d61 100644 --- a/cpu/mips/cpu.c +++ b/cpu/mips/cpu.c @@ -25,6 +25,17 @@  #include <command.h>  #include <asm/inca-ip.h>  #include <asm/mipsregs.h> +#include <asm/cacheops.h> + +#define cache_op(op,addr)						\ +	__asm__ __volatile__(						\ +	"	.set	push					\n"	\ +	"	.set	noreorder				\n"	\ +	"	.set	mips3\n\t				\n"	\ +	"	cache	%0, %1					\n"	\ +	"	.set	pop					\n"	\ +	:								\ +	: "i" (op), "R" (*(unsigned char *)(addr)))  int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  { @@ -41,6 +52,17 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  void flush_cache(ulong start_addr, ulong size)  { +	unsigned long lsize = CFG_CACHELINE_SIZE; +	unsigned long addr = start_addr & ~(lsize - 1); +	unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); + +	while (1) { +		cache_op(Hit_Writeback_Inv_D, start_addr); +		cache_op(Hit_Invalidate_I, start_addr); +		if (addr == aend) +			break; +		addr += lsize; +	}  }  void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) |