2009年6月24日 星期三

[ARM] Buffer allocated by dma_alloc_coherent cannot be invalidated/cleaned/flushed by dma_cache_maint

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)

沒有留言: