[U-Boot] [PATCH] ARMv8: fix bug for flush data cache by set/way
Scott Wood
scottwood at freescale.com
Tue Apr 8 00:24:21 CEST 2014
On Mon, 2014-03-31 at 09:50 +0800, Leo Yan wrote:
> When flush the d$ with set/way instruction, it need calculate the way's
> offset = log2(Associativity); but in current uboot's code, it use below
> formula to calculate the offset: log2(Associativity * 2 - 1), so finally
> it cannot flush data cache properly.
More specifically, the "Associativity" above is actually "Associativity
- 1", and clz isn't quite log2().
> Signed-off-by: Leo Yan <leoy at marvell.com>
> ---
> arch/arm/cpu/armv8/cache.S | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S
> index 546a83e..256d2e2 100644
> --- a/arch/arm/cpu/armv8/cache.S
> +++ b/arch/arm/cpu/armv8/cache.S
> @@ -30,9 +30,7 @@ ENTRY(__asm_flush_dcache_level)
> add x2, x2, #4 /* x2 <- log2(cache line size) */
> mov x3, #0x3ff
> and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */
> - add w4, w3, w3
> - sub w4, w4, 1 /* round up log2(#ways + 1) */
> - clz w5, w4 /* bit position of #ways */
> + clz w5, w3 /* bit position of #ways */
> mov x4, #0x7fff
> and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */
> /* x1 <- cache level << 1 */
I believe the new code will fail on a cache with associativity 1. x3
would be 0, since it's actually associativity minus one, and thus w5
would be 32. w5 is later interpreted as x5, so it would actually do a
32-bit shift rather than whatever behavior ARM specifies for shift
counts larger than the word size.
-Scott
More information about the U-Boot
mailing list