2

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

在 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)
4

1 回答 1

3

我找到了解决方案!

正如一位同事所建议的那样,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;

实际上不确定是否需要所有标志,但是,嘿,它有效!

于 2012-10-17T08:21:46.113 回答