
Hi Aneesh, thanks for taking time for this!
On Fri, Jul 29, 2011 at 12:13 PM, Aneesh V aneesh@ti.com wrote:
- 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.
- 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