PCI Express BAR内存映射的基本理解

23

我正在尝试理解PCI Express的工作原理,以便编写可以读写没有板载内存的自定义PCI Express设备的Windows驱动程序。

我了解PCIE配置空间中的基址寄存器(BAR)保存了PCI Express应该响应/允许写入的内存地址。 (这样理解是否正确?)

我的问题如下:

  • 在谈论PCIE时,“总线特定地址”与物理地址有何区别?
  • BAR何时以及如何填充地址? 驱动程序负责分配内存并将地址写入外围BAR吗?
  • 在从外围到主机内存传输数据时是否使用DMA?

感谢您的时间。

此致敬礼,

3个回答

25

我也在为自定义板卡编写设备驱动(尽管是在Linux上)。这是我对你的问题的回答:

BAR代表主机系统(CPU)用于与设备通信的内存窗口。设备不会向该窗口中写入数据,而只是响应TLP(Transaction Layer Packets)请求(MRd*,MWr*)。

如果您的架构没有总线层翻译机制,我会说“总线特定”=“物理”地址。查看此线程获取更多信息。

在我使用的所有x86消费级PC中,BAR地址似乎都是由BIOS或在操作系统引导时分配的。驱动程序必须使用已分配的任何地址进行工作。

DMA术语似乎被滥用,我认为总线主控才是PCIe中正确的术语。在PCIe中,每个设备都可以是总线主控(如果其命令寄存器第2位允许)。它通过向总线上的其他设备(但通常向系统内存)发送MRd、MWr TLP并向CPU发出中断信号来实现。


1
感谢您的澄清。 - user3156702
1
嗨Claudio,这个BAR窗口在一个PCI卡和另一个PCI卡之间会发生变化吗?我想它不会改变,因为这是CPU用来访问PCI卡物理地址的窗口,对吧? - ransh
1
嗨@ransh,BAR窗口的大小由PCI卡定义。该BAR的位置由软件(BIOS或操作系统)设置。例如,一个PCI卡可以有1MB大小的BAR0,另一个PCI卡可以有16kB大小的BAR0。 - Claudio
1
嗨Claudio,谢谢。如果我理解正确的话,那么PCI配置空间中的“基地址寄存器”(指定从CPU角度访问设备内存的物理地址的寄存器)在更换一个PCI卡片时可能是相同的,只有根据PCI设备特定寄存器和内存映射的内容+大小不同。如果我错了,请纠正我。非常感谢! - ransh
5
你好ransh,也许还存在一些困惑。PCI配置空间(其中包括BAR寄存器)通常通过特殊寻址方式进行访问,这种寻址方式采用总线/设备/功能形式或在Linux中(使用lspci命令)为bus:slot.func(例如00:01.0)。PCIe协议使用特殊数据包进行此类寻址(Config Type 0/1 Read/Write Requests)。这些不是内存或IO空间访问(虽然访问它们的机制可能是...另一回事)。因此,如果你用另一个PCI卡替换原先的卡(放在同一插槽上),它们可能会使用相同的bus:slot地址。希望对你有所帮助。Claudio - Claudio

18

根据您的查询,您想为PCIe从设备编写驱动程序。要了解PCIe传输背后发生的事情,互联网上有大量资料可供参考(例如PCIe总线枚举、外围地址映射到内存等)。

是的,关于将PCIe寄存器映射到内存中的理解是正确的,您可以进行读/写操作。(例如,在Linux PCIe设备驱动程序中,您可以使用“ioremap”来完成此操作)。

地址总线用于指定物理地址。当处理器或DMA启用的设备需要读取或写入内存位置时,它在地址总线上指定该内存位置。没有更多需要补充的内容。 “PCIe总线枚举”主题将回答您的第二个问题。

您的第三个问题比较含糊。您是指从设备的PCIe?假设是这样的话,是的,您可以使用DMA控制器在从设备的PCIe和主机之间传输数据。我正在一项涉及与主机通过PCIe总线连接的“PCIe-DMA”的项目上工作。实际上,这取决于您的设计和实现。因此,在我的情况下,“PCIe-DMA”本身是目标板上连接到主机的从设备的PCIe。


1
你好,非常感谢你的回答。所以,“总线特定地址”与物理地址相同。例如,它们从主机和从属PCIe设备看到的是相同的。 - user3156702
1
非常欢迎。是的。您只需要关注PCIe从设备数据表中指定的寄存器地址。因此,一旦将这些寄存器地址映射到系统内存中,您就可以通过访问(读/写)映射的系统内存来访问PCIe设备寄存器。 - Sumeet_Jain
1
嗨@sumeet,这个BAR窗口在不同的PCI卡之间会发生变化吗?我认为它不会改变,因为这是CPU用来访问PCI卡物理地址的窗口,对吧? - ransh

9

以下是您疑问/问题的澄清。

1> 有许多设备坐在总线上,例如PCI,它们以与物理地址不同的术语查看内存,这些被称为总线地址。例如,如果您从坐在总线上的设备向系统的主存储器(Memory)启动DMA,则目标地址应为相应的物理地址在内存中对应的总线地址。

2> BARS在枚举时填充,在典型的PC中,当您的PCI感知固件枚举插槽上存在的PCI设备并将地址和大小分配给BARS时,这是在引导时进行的。

3> 是的,您可以在这些BARS上使用DMA启动或CPU启动操作。

-- flyinghigh


1
感谢您的时间 - 非常感谢 - user3156702
2
谁负责给定的BAR地址?这取决于PCI卡吗?还是CPU选择地址(这样,如果我用另一张卡替换一张卡,我可能会得到相同的地址)? - ransh

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