【问题标题】:PCIe device discovery algorithm pseudo codePCIe设备发现算法伪代码
【发布时间】:2017-01-18 18:46:39
【问题描述】:
我有一个用 System Verilog 编写的 PCIe 模型,尽管我认为这个问题与语言无关。该模型在仿真中完美地执行 PCIe 配置读写和内存读写。但是,我需要做的是“发现”我的 PCIe 设备并在模拟中配置我的配置空间寄存器。是否有代表 Linux PCIe 枚举过程的样板代码块,我也可以添加我自己的模型事务函数,这样我就可以获得“巴士步行”,然后是 BAR 编程,如果发现则启用 SR-IOV, MSIx 配置?这似乎是 PCIe 设备的常见练习,所以也许有模型。
【问题讨论】:
标签:
verilog
system-verilog
pci
pci-e
【解决方案1】:
这并不难做到。基本上,您循环遍历配置空间,检查第一个根总线 0 上的每个可能设备。找到设备后,您根据其请求的大小为其分配内存空间并相应地对 BAR 进行编程。如果您发现任何网桥,您还可以配置和启用它们 - 用于此的基本网桥寄存器是标准的。这包括分配上游和下游总线编号,然后允许您枚举新的下游总线,等等。
我必须这样做一次才能访问没有操作系统或其他软件环境的系统上的 PCI I/O 卡。还不错,跨越两个供应商的两个桥,以及 I/O 卡寄存器和 CPU 总线根桥设置。这是 PCI,不是 PCIe,但它会非常相似。如果硬件从未改变,你甚至可以使用完全硬编码的数字来完成,但在我的例子中,有几个变体,所以我实际上必须做一些简单的枚举来动态查找设备编号。一个问题是,您可能需要稍等片刻或重试,以便让所有设备有时间在线,然后再尝试访问它们。
在此过程中,我发现这本书非常宝贵:PCI System Architecture (4th Edition)。我注意到还有一个 PCIe 版本:PCI Express System Architecture (1st Edition)。如果你还没有,我肯定会得到其中之一。这些书包含有关如何完成所有这些的详细算法和解释。当时我并没有真正使用或参考任何代码可言,但是......
我找到的最好的代码资源是 U-Boot。它在类似的低级别上运行,完全独立,并且仍然相当小且尽可能简单。例如,枚举似乎以函数pci_init() 开始调用特定于板的pci_xxx_init()。然后设置根桥,然后在drivers/pci/pci.c 中调用pci_hose_scan_bus() 来完成真正的工作。还要查看drivers/pci/pci_auto.c 中的例程以及文件夹的其余部分。
对于您的任务,您可能只需要一个非常小的子集,并且可以将这些文件的一部分拆分为一个简单的驱动程序。基本上是一个 for() 循环和一些 pci_read/write_config() 调用,其中包含识别您的设备和桥 ID 的逻辑。