2

I have a PCI device which exposes a BAR and few offsets in the bar for accessing the device. On one of the Bar offset, i need to program a 64KB allocated memory. In my Linux driver, i allocate a 64KB of memory using kmalloc() which as i know returns virtual address. If this is programmed into the offset, HW won't be able to see the same. How do i convert this virtual address to physical ? When i Google, i see few links pointing to virt_to_phys() but few responses says this doesn't work well with kmalloc(). Any idea how to go about this?

pkumarn
  • 1,383
  • 4
  • 22
  • 29
  • You probably should use something like `dma_alloc_coherent` instead of `kmalloc`. – zch May 18 '13 at 10:34
  • Like zch said, or some other DMA mechanism. You should read up on DMA in the LDD3. It's section is still relevant. http://tjworld.net/books/ldd3/#DirectMemoryAccess – Benjamin Leinweber May 20 '13 at 21:54

2 Answers2

0

You normally use pci_resource_start() / pci_resource_end() from within a kernel driver. I assume you are writing a device driver ?

I won't map the memory yourself : That's where the kernel functions are for. That way, you're sure it works on all platforms. That 64k block I assume is some memory map that is provided by the PCI device ? if yes, then the above is correct. If no, please give more information.

Igmar Palsenberg
  • 637
  • 4
  • 10
  • Here is what's happening. I have a busif driver which maps the PCI space as mentioned and also stores the physical as follows : base_addr = pci_resource_start(). Now this again gets maps to virtual address using ioremap_nocache(). On top of bus layer, i have another module which is responsible to read/write to registers using write()/read() calls. Also i need to program few Bar offsets with a physical memory location for HW to to DMA operations, put in requests from user, etc... As HW needs 64K of page, i do a kmalloc() and the physical address of this needs to go to offset... – pkumarn May 18 '13 at 12:08
0

Rather than using kmalloc() , use alloc_pages() function.

struct page* alloc_pages(gfp_t gfp_mask, 4 );

one page is of 4K, so it will allocate 2^4=16 pages which is equal to 16 * 4K = 64K memory and returns physical address.

Vikrant Patel
  • 17
  • 1
  • 7
  • Thanks for all the replies. My only concern is are all these memory allocated DMA'able ? After further reading, i have decided to use pc_alloc_consistent() which allocates a page and also DMA'able. Can any thwo some light on why pages allocated using kmalloc(), __get_free_pages() etc (any other function which gives kernel virtual address) and when converted to physical address is not recommended for DMA? I have a solution but i am not clear why? – pkumarn May 21 '13 at 10:50
  • Because your requirement is to deal with physical address space. so this functions gives fulfil your needs. – Vikrant Patel May 21 '13 at 11:13
  • And what do you mean by DMA'ble?? – Vikrant Patel May 21 '13 at 11:14
  • DMA'ble means HW can do DMA transfer on the allocated region. My HW needs to DMA userland data to this location for driver to pick up and process it. – pkumarn May 24 '13 at 09:04
  • ok. I don't have much knowledge on that. But what i know is that if you want to access physical address then use page_alloc() function rather than kmalloc() if it will helpful and solve your problem. – Vikrant Patel May 24 '13 at 09:40