为32位PCI设备编写Windows 64位设备驱动程序

5
我正在评估将我几年前编写的设备驱动程序从32位移植到64位。物理设备是一张32位PCI卡。即,设备为32位,但我需要从Win7x64中访问它。该设备向Windows世界呈现一些寄存器,然后进行大量的总线主数据传输到驱动程序分配的内存块中。
我在Microsoft文档中读到,您可以发出信号来表示驱动程序是否支持64位DMA。如果不支持,则DMA是双缓冲的。但是,我不确定是否是这种情况。我的驱动程序可能是完整的64位驱动程序,因此它可以支持处理器地址空间中的64位地址,但实际的物理设备不支持它。实际上,设备BAR必须映射到4 GB以下,设备必须获得PC RAM地址以执行低于4 GB的总线主控制。这是否意味着我的驱动程序将始终通过双缓冲进行?这是一个非常性能敏感的过程,双缓冲可能会阻止整个系统工作。
当然,设计一个新的64位PCI(或PCI-E)板不在考虑之内。
除了微软页面外,有人可以为我提供一些资源吗?
非常感谢!
2个回答

0

这是一篇旧帖子,我希望答案仍然相关...

这里有两个部分,PCI目标和PCI主控访问。

PCI目标访问:驱动程序将PCI BAR映射到64位虚拟地址空间,驱动程序通过指针读取/写入。

PCI主控访问:您需要通过调用IoGetDmaAdapter()创建一个DmaAdapter对象。在创建时,您还描述了您的设备是32位(请参见DEVICE_DESCRIPTION参数)。然后,您调用DmaAdapter ::AllocateCommonBuffer()方法在PC RAM中分配一个连续的DMA缓冲区。

我不确定双缓冲是否可行。根据我的经验,双缓冲不常用,相反,如果无法分配满足DEVICE_DESCRIPTION(在您的情况下为32位dma寻址)的缓冲区,则DmaAdapter ::AllocateCommonBuffer()会失败。


0

对于只能进行32位PCI寻址的设备编写64位驱动程序没有问题。正如Alexey所指出的,您创建的DMA适配器对象指定了设备的硬件寻址能力。在分配DMA缓冲区时,操作系统会考虑到这一点,并确保在您的硬件可访问区域内分配这些缓冲区。Linux驱动程序的行为类似,其中您的驱动程序必须提供一个DMA地址掩码,以与稍后使用的DMA函数相关联。

您可能遇到的性能问题是,如果您的应用程序分配了需要进行DMA读写的缓冲区,则该缓冲区可能分散在整个内存中,其中包含在4G以上的内存页。如果您的驱动程序计划对这些进行DMA,则需要在DMA期间锁定RAM中的缓冲区页面,并基于页面位置为DMA引擎构建SGL。问题在于,对于那些在4G以上的页面,操作系统随后必须将它们复制/移动到4G以下的页面,以便您的DMA引擎能够访问它们。这就是潜在的性能问题所在。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接