[U-Boot] [PATCH v4] ARM926ejs: Add routines to invalidate D-Cache

Marek Vasut marek.vasut at gmail.com
Wed Aug 10 07:52:12 CEST 2011


On Wednesday, August 10, 2011 04:49:25 AM Hong Xu wrote:
> After DMA operation, we need to maintain D-Cache coherency.
> So that the DCache must be invalidated (hence CPU will fetch
> data written by DMA controller from RAM).
> 
> Tested on AT91SAM9261EK with Peripheral DMA controller.

Hi Hong,

one more thing, not that I want to disappoint you.

Try to take a look at arch/arm/cpu/armv7/cache_v7.c

Maybe we should do the same for arm926ejs -- have arch/arm/cpu/arm926ejs/cache.c 
-- containing arm926ejs specific cache management functions. That way, 
arch/arm/lib/cache.c won't become mess.

What do you think ?

> 
> Signed-off-by: Hong Xu <hong.xu at atmel.com>
> Tested-by: Elen Song <elen.song at atmel.com>
> CC: Albert Aribaud <albert.u.boot at aribaud.net>
> CC: Aneesh V <aneesh at ti.com>
> CC: Marek Vasut <marek.vasut at gmail.com>
> CC: Reinhard Meyer <u-boot at emk-elektronik.de>
> CC: Heiko Schocher <hs at denx.de>
> ---
> V2:
>   Per Albert's suggestion, add invalidate_dcache_range
> 
> V3:
>   invalidate_dcache_range emits warning when detecting unaligned buffer
> 
>   invalidate_dcache_range won't clean any adjacent cache line when
> detecting unaligned buffer and only round up/down the buffer address
> 
> v4:
>   invalidate_dcache_range will emit clearer warning message
> 
>   Per Albert's suggestion, if not alighed to cache line size, round up
>   start address, round down stop addres
> 
>   Per Marek Vasut's suggestion, use __func__ stated in C99
> 
>  arch/arm/lib/cache.c |   58
> ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 58
> insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
> index 92b61a2..4c8e160 100644
> --- a/arch/arm/lib/cache.c
> +++ b/arch/arm/lib/cache.c
> @@ -53,3 +53,61 @@ void	__flush_dcache_all(void)
>  }
>  void	flush_dcache_all(void)
>  	__attribute__((weak, alias("__flush_dcache_all")));
> +
> +/*
> + * The buffer range to be invalidated is [start, stop)
> + */
> +void __invalidate_dcache_range(unsigned long start, unsigned long stop)
> +{
> +	int cache_line_len;
> +	unsigned long mva;
> +
> +#ifdef CONFIG_ARM926EJS
> +#ifdef CONFIG_SYS_CACHELINE_SIZE
> +	cache_line_len = CONFIG_SYS_CACHELINE_SIZE;
> +#else
> +	/*
> +	 * ARM926EJ-S Technical Reference Manual, Chap 2.3.1 Table 2-9
> +	 * only b'10, aka. 32 bytes cache line len is valid
> +	 */
> +	cache_line_len = 32;
> +#endif
> +	mva = start;
> +	if ((mva & (cache_line_len - 1)) != 0) {
> +		printf("WARNING: %s - start address 0x%08x not aligned to"
> +			"cache line size(%d bytes)\n", __func__, start,
> +			cache_line_len);
> +		/* Round up starting address */
> +		mva = (mva | (cache_line_len - 1)) + 1;
> +	}
> +	if ((stop & (cache_line_len - 1)) != 0) {
> +		printf("WARNING: %s - stop address 0x%08x not aligned to"
> +			"cache line size(%d bytes)\n", __func__, stop,
> +			cache_line_len);
> +		/* Round down ending address */
> +		stop &= ~(cache_line_len - 1);
> +	}
> +
> +	while (mva < stop) {
> +		asm("mcr p15, 0, %0, c7, c6, 1" : : "r"(mva));
> +		mva += cache_line_len;
> +	}
> +
> +	/* Drain the WB */
> +	asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
> +#endif
> +
> +	return;
> +}
> +void invalidate_dcache_range(unsigned long start, unsigned long stop)
> +	__attribute__((weak, alias("__invalidate_dcache_range")));
> +
> +void __invalidate_dcache_all(void)
> +{
> +#ifdef CONFIG_ARM926EJS
> +	asm("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
> +#endif
> +	return;
> +}
> +void  invalidate_dcache_all(void)
> +	__attribute__((weak, alias("__invalidate_dcache_all")));


More information about the U-Boot mailing list