2009年6月24日 星期三

[ARM] Buffer allocation for device DMA and DCache coherence

For more detailed description, refer Documentation/DMA-mapping.txt.

  • Consistent DMA mappings
    • Synchronous, coherent
    • No cache coherence issue
    • Limited resource, CONSISTENT_DMA_SIZE(usually 2MB)
    • Slow in access, access to memory directly
    • Non-cacheable, Non-bufferable(NCNB)
    • Function
      • Buffer allocation/free: pci_alloc_consistent/pci_free_consistent, dma_alloc_coherent/dma_free_coherent
    * Never use dma_sync_single/dma_map_single on a NCNB memory address, or you will get a BUG().

  • Streaming DMA mappings
    • Cacheable, Bufferable buffer
    • faster, more in quantity (compare to Consistent DMA mappings)
    • Has cache coherence issue
      • Flush the cache, write data to memory (PCI_DMA_TODEVICE) when:
        • After software changes the content of the DMA buffer
        • Before DMA start
      • Invalidate the cache, read data from memory (PCI_DMA_FROMDEVICE) when:
        • Before reading the DMA buffer
        • After DMA stop
    • Function
      • Buffer allocation/free: kmalloc/kfree
      • Map/Unmap: pci_map_single/pci_unmap_single, dma_map_single/dma_unmap_single
      • Cache coherence : dma_sync_single/pci_dma_sync_single/... (PCI_DMA_TODEVICE/PCI_DMA_FROMDEVICE)
    * memory allocated by kmalloc(GPF_DMA) is still cacheable buffer, which would require cache flush/invalidate. (by experience)

    * It seems that cache invalidate will NOT clean the cached write buffer; if there are memory writes without cache flush, even cache invalidation is done after device DMA, the data read may still be the previous cached memory write. So ensure the cache is flushed properly before device starting DMA. (by experience, ARM11MPCore)

沒有留言: