[U-Boot] [PATCH RESEND v2] armv7: Disable D cache for goni target (s5p)

Linus Walleij linus.walleij at linaro.org
Sun Jul 31 10:18:17 CEST 2011


Hi Aneesh, thanks for taking time for this!

On Fri, Jul 29, 2011 at 12:13 PM, Aneesh V <aneesh at ti.com> wrote:

> 1. Drivers using DMA:
> i. Flush the buffer before initiating a memory to peripheral DMA.
> ii. Invalidate the buffer after a peripheral to memory DMA (before
> MPU reads it)

No problems with this. I only use the serial port and it's working
flawlessly downloading a uImage to target with caches enabled.

> 2. Cleanup before Linux:
> Flush the entire SDRAM and disable the cache.
>
> I think you are hit by not doing 2 properly. If you have dirty entries
> in the cache when Linux boots you will have coherency issues. I had
> faced similar issues when I had some issues in armv7
> cleanup_before_linux(). I had to do an extra invalidate to solve it.
> Please see how this has been done for armv7 in arch/arm/cpu/armv7/cpu.c
> in function cleanup_before_linux().

Yes, this is the problem. The problem is further that I've tried
several variants of code and of course following the ARM920T manual
on how to do this.

Actually I think the problem is really not with the cache *at all* but
with the MMU. The current ARM CP15 MMU code sets up an
identity mapping and it is always turned on/off in conjunction with
the cache.

The moste pedantic and careful code I have does this:

+#ifdef CONFIG_ARM920T
+       /* Flush all cache */
+       debug("FLUSH I-cache\n");
+       asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+       isb();
+       debug("FLUSH D-cache\n");
+       asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
+       isb();
+       debug("FLUSH all cache\n");
+       asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (0));
+       isb();
+       /* Flush I+D TLB */
+       debug("FLUSH I+D TLB\n");
+       asm volatile("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
+       isb();
+       /* Drain write buffer */
+       debug("Drain write buffer\n");
+       asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
+       isb();
+#endif

This is called in arch/arm/lib/cache.c generic CP15 code as it
calls __flush_cache before it turns off the MMU.

At this point the program counter goes astray and the machine
hangs :-(

It's something like removing the identity map is not good for the
CPU, it gets lost. I think. (Working hopothesis.)

I think actually all ARM920T machines are broken, they have just
not been tested yet.

> In some other cases there are problems due to (1) above. In any case,
> the starting point really is to make sure that you have the required
> set of maintenance functions for your architecture revision.

For the old CP15 caches it's quite simple, as can be seen from
Linux MM code you just invalidate all the cache:
asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (0));

Yours,
Linus Walleij


More information about the U-Boot mailing list