Buffer allocated by dma_alloc_coherent cannot be invalidated/cleaned/flushed by dma_cache_maint, or you will get an BUG()
Buffer allocated by dma_alloc_coherent will have address at 0xfXXX_XXXX
arch/arm/mm/consistent.c
/*
* Make an area consistent for devices.
* Note: Drivers should NOT use this function directly, as it will break
* platforms with CONFIG_DMABOUNCE.
* Use the driver DMA support - see dma-mapping.h (dma_sync_*)
*/
void dma_cache_maint(const void *start, size_t size, int direction)
{
const void *end = start + size;
BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end - 1));
switch (direction) {
case DMA_FROM_DEVICE: /* invalidate only */
dmac_inv_range(start, end);
outer_inv_range(__pa(start), __pa(end));
break;
case DMA_TO_DEVICE: /* writeback only */
dmac_clean_range(start, end);
outer_clean_range(__pa(start), __pa(end));
break;
case DMA_BIDIRECTIONAL: /* writeback and invalidate */
dmac_flush_range(start, end);
outer_flush_range(__pa(start), __pa(end));
break;
default:
BUG();
}
}
EXPORT_SYMBOL(dma_cache_maint);
arch/arm/include/asm/memory.h
#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
PAGE_OFFSET=0xc000_0000
high_memory=0xd000_0000
PAGE_OFFSET(0xc000_0000) < addr < high_memory(0xd000_0000)
沒有留言:
張貼留言