0

I am experimenting the DMA flow with and without SMMU on ARM. Our custom application requires kernel address, physical address and bus address.

With SMMU enabled, I managed to get the kernel address and bus address using dma_alloc_coherent(), but I could not get the physical address via virt_to_phys(). That made me replace dma_alloc_coherent() with dma_map_single as follows:

// Get kernel address
res->KernelAddress = (u64)kzalloc( size , GFP_KERNEL | GFP_DMA);

// Get bus address
res->BusAddress = (u64)dma_map_single(&DevExt->pdev->dev, &res->KernelAddress, size, PCI_DMA_BIDIRECTIONAL);

// Get physical address
res->PhysicalAddress = (u64)virt_to_phys( (void*)res->KernelAddress );

dma_sync_single_for_cpu(&DevExt->pdev->dev, res->BusAddress, size, PCI_DMA_BIDIRECTIONAL);

// Map physical address to virtual address in user space
if (remap_pfn_range(vma, vma->kern_addr, vma->phys_addr,size,vma->vm_page_prot));

There was no issue with the above flow. I managed to get 3 addresses but DMA write to the returned location failed. Are other DMA APIs required for the above flow to work?

It is better if any snippet is shared!

artless noise
  • 21,212
  • 6
  • 68
  • 105
PBang
  • 1
  • 1
  • `kzalloc` should work with `virt_to_phys`; something is wrong with your system if not. If you try `virt_to_phys` on another address range, it may not work. See: [Physical address of vector table](https://stackoverflow.com/questions/19275718/find-the-physical-address-of-exception-vector-table-from-kernel-module) for alternatives to `virt_to_phys`. – artless noise Nov 21 '18 at 14:10
  • Is the flow correct? Should remap_pfn_range be changed to dma_mmap_coherent? But, dma_mmap_coherent expects the bus address not the physical address, doesn't it? Does vma_area_struct maintain bus address (dma_addr_t) details? – PBang Nov 22 '18 at 10:26
  • Can you please comment on this? – PBang Nov 26 '18 at 10:05
  • I don’t see how you check for errors of DMA API calls. – 0andriy Dec 01 '18 at 10:27

0 Answers0