[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