对于将值写入PCIe卡内存所涉及的一系列步骤,我感到非常困惑。很难理解你在互联网上读到的东西的精确的含义,所以我希望有人能读懂我关于发生什么的理论,并指出任何错误。
设置
假设我有一张PCIe卡,上面有一些内存。为了便于讨论,假设以下具体设置:
它有4MB可以通过基本地址寄存器0访问(不管这意味着什么),它是整个系统中唯一的connected?)
我们还将讨论术语:
H 229H 130栏(基本地址寄存器)是PCIe设备配置空间内的字段H 231H 132一个条形空间是指示的地址空间(?)按条形图中的值计算.我对正在发生的事情的理论
在引导时,Linux开始探测不同的地址,以查看那里是否有任何内容。- Since the PCIe bus wires are only connected to the system bus wires via a bridge (i.e. the PCIe controller on the system bus) Linux must know how to interact with the PCIe controller.
- Linux sends special commands to the PCIe controller (through memory-mapped IO?) that end up triggering the correct series of voltages on the PCIe wires
- If it gets a response, it will fill in a `pci_dev` struct with other information in the configuration space
- At some point in the future (when?) the kernel will iterate through the list of PCI drivers to try and match them to devices
当Linux检测到设备时,
会将其条形空间映射到系统总线中。(这是怎么做到的?)假设它将BAR0空间映射为将0x55500000地址映射到系统总线上的0x5550FFFF。Linux必须告诉根目录才能侦听这些地址,并且它们与它检测到的bother?)卡相对应。顺便说一句,Linux将在我们的卡上设置基本地址寄存器0,以使基本地址字段中有0x55500000 (为什么是
)。
随后在0x55500000和0x5550FFFF之间的系统总线上写的东西被根复合体“捕获”,并分发给PCIe卡,根复合体实质上将构建一个数据包,所有的头和校验和等等,并将它们通过主板的铜线发送到PCIe 0x5550FFFF。
假设CPU在系统总线上写了0xDEADBEEF以寻址0x55501230,并且根复合体将数据包发送到PCIe卡,卡接收数据包并在本地4MB内存中将0xDEADBEEF写入0x01230。
那么,这其中哪些部分是正确的,哪些是错误的?
发布于 2019-11-01 17:01:35
我的经验是英特尔处理器,所以下面的一些细节可能是专门针对英特尔处理器,但它大多是通用的。另外,我不知道Linux如何识别每个设备要加载的驱动程序的细节,所以我跳过了这个问题。
现代CPU没有系统总线(除了隐藏在CPU内部)。它们有内存通道、PCIe根端口和连接到芯片组(也称为外围控制器集线器)的DMI端口。PCH包含额外的设备,并且可能有额外的根端口。根复合体包括集成到CPU和PCH中的电路。(一些CPU SoC没有DMI或PCH,所有根复杂电路都在CPU SoC中。)
即使您的卡是整个系统中唯一的PCIe卡,也有其他PCIe设备集成到根复杂(称为RCIEP或根复杂集成端点)中。它们可能在CPU内部或在PCH中。
连接到PCIe根端口的设备将在某个非零总线号上配置为设备0。总线号取决于设备连接到的PCIe根端口(即插槽)以及PCIe总线的配置方式。(相同的插槽通常具有相同的总线号,但可能不是,这取决于连接到其他PCIe根端口的内容。)
您的其他假设和术语都很好。
软件可以使用I/O端口0xcf8和0xcfc的输入/输出指令,或者使用内存映射的配置空间来访问PCI配置空间。PCI配置空间的内存地址范围由BIOS设置。软件通过查看ACPI表来查找地址。这些I/O或内存访问转换为PCIe信号的机制完全在根复杂硬件中。
该偏移量进入PCI配置空间地址范围,控制设备/寄存器软件正在访问的设备/寄存器。例如,对MMCFG +0的访问访问设备0:0.0的寄存器偏移量0。对MMCFG + 0x1000的访问访问设备0:0.1的寄存器偏移量0,对MMCFG + 0x102000的访问访问设备1:0.2的寄存器偏移量0。
软件在每个设备地址的偏移量3:0处读取供应商id /设备id寄存器,以检测该设备地址上是否存在设备。如果没有设备,PCI控制器将返回0 0xffffffff。如果存在设备,则设备返回供应商id和设备id,允许软件确定设备的类型。
每个设备都有6个条形寄存器,偏移量为0x10、0x14、. 0x24。如果设备支持64位条,则使用两个相邻的条形寄存器来配置单个区域.通常,BIOS配置每个设备的条,还配置根复合体中的其他(隐藏)寄存器,使其能够将内存访问路由到适当的设备。软件通常只写入条形寄存器以检测区域大小,然后还原BIOS设置的值。取决于根复杂的硬件,软件可能能够或可能无法更改条形图值,并且仍然具有正确的访问权限。
https://stackoverflow.com/questions/58443506
复制相似问题