我正在尝试理解PCI Express的工作原理,以便编写可以读写没有板载内存的自定义PCI Express设备的Windows驱动程序。
我了解PCIE配置空间中的基址寄存器(BAR)保存了PCI Express应该响应/允许写入的内存地址。 (这样理解是否正确?)
我的问题如下:
- 在谈论PCIE时,“总线特定地址”与物理地址有何区别?
- BAR何时以及如何填充地址? 驱动程序负责分配内存并将地址写入外围BAR吗?
- 在从外围到主机内存传输数据时是否使用DMA?
感谢您的时间。
此致敬礼,
我正在尝试理解PCI Express的工作原理,以便编写可以读写没有板载内存的自定义PCI Express设备的Windows驱动程序。
我了解PCIE配置空间中的基址寄存器(BAR)保存了PCI Express应该响应/允许写入的内存地址。 (这样理解是否正确?)
我的问题如下:
感谢您的时间。
此致敬礼,
我也在为自定义板卡编写设备驱动(尽管是在Linux上)。这是我对你的问题的回答:
BAR代表主机系统(CPU)用于与设备通信的内存窗口。设备不会向该窗口中写入数据,而只是响应TLP(Transaction Layer Packets)请求(MRd*,MWr*)。
如果您的架构没有总线层翻译机制,我会说“总线特定”=“物理”地址。查看此线程获取更多信息。
在我使用的所有x86消费级PC中,BAR地址似乎都是由BIOS或在操作系统引导时分配的。驱动程序必须使用已分配的任何地址进行工作。
DMA术语似乎被滥用,我认为总线主控才是PCIe中正确的术语。在PCIe中,每个设备都可以是总线主控(如果其命令寄存器第2位允许)。它通过向总线上的其他设备(但通常向系统内存)发送MRd、MWr TLP并向CPU发出中断信号来实现。
根据您的查询,您想为PCIe从设备编写驱动程序。要了解PCIe传输背后发生的事情,互联网上有大量资料可供参考(例如PCIe总线枚举、外围地址映射到内存等)。
是的,关于将PCIe寄存器映射到内存中的理解是正确的,您可以进行读/写操作。(例如,在Linux PCIe设备驱动程序中,您可以使用“ioremap”来完成此操作)。
地址总线用于指定物理地址。当处理器或DMA启用的设备需要读取或写入内存位置时,它在地址总线上指定该内存位置。没有更多需要补充的内容。 “PCIe总线枚举”主题将回答您的第二个问题。
您的第三个问题比较含糊。您是指从设备的PCIe?假设是这样的话,是的,您可以使用DMA控制器在从设备的PCIe和主机之间传输数据。我正在一项涉及与主机通过PCIe总线连接的“PCIe-DMA”的项目上工作。实际上,这取决于您的设计和实现。因此,在我的情况下,“PCIe-DMA”本身是目标板上连接到主机的从设备的PCIe。
以下是您疑问/问题的澄清。
1> 有许多设备坐在总线上,例如PCI,它们以与物理地址不同的术语查看内存,这些被称为总线地址。例如,如果您从坐在总线上的设备向系统的主存储器(Memory)启动DMA,则目标地址应为相应的物理地址在内存中对应的总线地址。
2> BARS在枚举时填充,在典型的PC中,当您的PCI感知固件枚举插槽上存在的PCI设备并将地址和大小分配给BARS时,这是在引导时进行的。
3> 是的,您可以在这些BARS上使用DMA启动或CPU启动操作。
-- flyinghigh