2

I have a somewhat unusual situation where I'm developing a simulation module for an Ethernet device. Ideally, the simulation layer would just be identical to the real hardware with regard to the register set. The issue I've run into is that the DMA registers in the hardware are loaded with the DMA mapping (physical) address of the data. I need to use those physical addresses to copy the data from the Tx buffer on the source device to the Rx buffer on the destination device. To do that in module code, I need pointers to virtual memory. I looked at phys_to_virt() and I didn't understand this comment in the man page:

This function does not handle bus mappings for DMA transfers.

Does this mean that a physical address that is retrieved via dma_map_single cannot be converted back to a virtual address using phys_to_virt()? Is there another way to accomplish this conversion?

jhd1013
  • 98
  • 1
  • 4

3 Answers3

0

I am not too clear about this question but if you are using "phys_to_virt()" may be the reason that address available on the bus can not be coverted to virtual by this function. I am not sure just try bus_to_virt(bus_addr); function

Community
  • 1
  • 1
suneet saini
  • 592
  • 3
  • 16
  • Thanks for trying to answer. Turns out my original question didn't really make much sense. Since I'm attempting to simulate hardware, there is no real bus underneath. Without some sort of bus underneath for the kernel to map to, I wouldn't get the DMA address to begin with. – jhd1013 Feb 25 '13 at 07:46
0

There is not any general way to map a DMA address to a virtual address. The dma_map_single() function might be programming an IOMMU (eg VT-d on an Intel x86 system), which results in a DMA address that is completely unrelated to the original physical or virtual address. However this presentation and the linked slides gives one approach to hooking an emulated hardware model up to a real driver (basically, use virtualization).

Roland
  • 6,227
  • 23
  • 29
0

Try dma_virt = virt_to_phys(bus_to_virt(dma_handle))

it worked for me. It gives the same virtual address that was mapped by dma_coherent_alloc().