2012-10-16 89 views
2

我有一个PCI设备,它的Linux驱动程序和一个用户空间应用程序。应用程序mmap通过驱动程序是PCI设备的第一个BAR。所有访问都是通过32位整数完成的,这很重要,因为读/写寄存器可能有副作用(启动操作等)。Linux PCI驱动程序,mmap预取

在x86平台上,这很有效。不过,我只是移动到ARM平台,我有一个奇怪的现象:

  • 读取来自驱动器/写入行为正确
  • 从用户空间读取触发一个64个字节的PCI读请求,哪些不能由我的设备来完成,因为它只接受32位访问(+因为副作用,我不想那样)。

我认为问题在于mmap想要预取一些数据并发出这64字节的读数。 我是否缺少一个标志或可能会禁用某种mmap预取的东西?在驾驶员侧

我目前的mmap实现仅仅是

vma->vm_flags |= VM_RESERVED; 
remap_pfn_range(vma,vma->vm_start, pfn, Size_UL, vma->vm_page_prot) 
+0

您的PCI设备是否将自己宣传为可预取? (Memory BAR中的位3) –

+0

不,PCI标志是0x0040200,(根据我的标题,PREFETCHABLE标志是0x2000) – Julien

回答

2

我找到了解决办法!

正如一位同事建议的那样,64字节是一个缓存行,这可能是一个忽略我的“非预取”信息的缓存机制,因为它在mmap()期间丢失了(虽然保存在x86上) ),所以我不得不对那些标志添加到VMA以防止缓存:

vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot) | L_PTE_PRESENT | 
         L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY; 

实际上没有确定所有的标志都需要,但是,嘿,它的工作原理!