diff options
| author | Marek Vasut <marex@denx.de> | 2012-03-15 18:33:17 +0000 | 
|---|---|---|
| committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2012-03-29 07:56:02 +0200 | 
| commit | a4aaad704827616a94c76f0a8efe06555c363545 (patch) | |
| tree | 7c041df914b4c37a15bbe679309ce117e941cf99 | |
| parent | 4af7692026ed23fc0424af7eb54595f05acedfce (diff) | |
| download | olio-uboot-2014.01-a4aaad704827616a94c76f0a8efe06555c363545.tar.xz olio-uboot-2014.01-a4aaad704827616a94c76f0a8efe06555c363545.zip | |
ARM926EJS: Implement cache operations
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Stefano Babic <sbabic@denx.de>
Acked-by: Stefano Babic <sbabic@denx.de>
| -rw-r--r-- | arch/arm/cpu/arm926ejs/cache.c | 66 | 
1 files changed, 54 insertions, 12 deletions
| diff --git a/arch/arm/cpu/arm926ejs/cache.c b/arch/arm/cpu/arm926ejs/cache.c index 504f60468..5b23e3a71 100644 --- a/arch/arm/cpu/arm926ejs/cache.c +++ b/arch/arm/cpu/arm926ejs/cache.c @@ -23,29 +23,71 @@  #include <common.h>  #ifndef CONFIG_SYS_DCACHE_OFF -static inline void dcache_noop(void) + +#ifndef CONFIG_SYS_CACHELINE_SIZE +#define CONFIG_SYS_CACHELINE_SIZE	32 +#endif + +void invalidate_dcache_all(void)  { -	if (dcache_status()) { -		puts("WARNING: cache operations are not implemented!\n" -		     "WARNING: disabling D-Cache now, you can re-enable it" -		     "later with 'dcache on' command\n"); -		dcache_disable(); -	} +	asm volatile("mcr p15, 0, %0, c7, c6, 0\n"::"r"(0));  } -void invalidate_dcache_all(void) +void flush_dcache_all(void)  { -	dcache_noop(); +	asm volatile( +		"0:" +		"mrc p15, 0, r15, c7, c14, 3\n" +		"bne 0b\n" +		"mcr p15, 0, %0, c7, c10, 4\n" +		::"r"(0):"memory" +	); +} + +static int check_cache_range(unsigned long start, unsigned long stop) +{ +	int ok = 1; + +	if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) +		ok = 0; + +	if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) +		ok = 0; + +	if (!ok) +		printf("CACHE: Misaligned operation at range [%08lx, %08lx]\n", +			start, stop); + +	return ok;  }  void invalidate_dcache_range(unsigned long start, unsigned long stop)  { -	dcache_noop(); +	if (!check_cache_range(start, stop)) +		return; + +	while (start < stop) { +		asm volatile("mcr p15, 0, %0, c7, c6, 1\n"::"r"(start)); +		start += CONFIG_SYS_CACHELINE_SIZE; +	}  }  void flush_dcache_range(unsigned long start, unsigned long stop)  { -	dcache_noop(); +	if (!check_cache_range(start, stop)) +		return; + +	while (start < stop) { +		asm volatile("mcr p15, 0, %0, c7, c14, 1\n"::"r"(start)); +		start += CONFIG_SYS_CACHELINE_SIZE; +	} + +	asm("mcr p15, 0, %0, c7, c10, 4\n"::"r"(0)); +} + +void flush_cache(unsigned long start, unsigned long size) +{ +	flush_dcache_range(start, start + size);  }  #else /* #ifndef CONFIG_SYS_DCACHE_OFF */  void invalidate_dcache_all(void) @@ -64,7 +106,7 @@ void flush_dcache_range(unsigned long start, unsigned long stop)  {  } -void  flush_cache(unsigned long start, unsigned long size) +void flush_cache(unsigned long start, unsigned long size)  {  }  #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ |