I've been writing a number of device drivers that use DMA, and now I am trying to get them working properly with offchip (FlexBus) attached memory. It looks like in these processors the DMA is completely agnostic to the data cache. My question is what is the most efficient way to maintain cache coherency in general applications?
It looks like the steps I should take are the following:
For DMA write to memory:
1. Use "write-through" cache mode (instead of "write-back") which will immediately execute any write commits to memory and make sure there are no pending writes that may happen after DMA to a memory block is started.
2. Do DMA write
3. After the DMA operation is complete "invalidate" all cache lines that are in the memory region over which DMA occurred.
For DMA read from memory:
1. Use "write-through" cache mode.
2. Flush all cache lines that are in the memory region over which DMA will occur.
3. Do DMA read.
It seems like "write-back" cache mode is more or less incompatible with DMA, as this would require a cache flush before DMA and a cache invalidate after DMA, with the need to do this in an atomic fashion (disabling interrupts).
Is there a better way? It seems that with all the invalidation and flushing of the caches that you might be better off only DMA'ing to non-cacheable memory then using the CPU to copy to the cacheable region. All this manipulation of the caches sort of defeats the purpose of DMA however. Was it an issue to have DMA work with the cache in this processor? Any good application note that explains all of this?