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 <l...@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


_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to