PCIe设备发现算法伪代码

时间:2017-01-18 18:46:39

标签: verilog system-verilog pci pci-e

我有一个用System Verilog编写的PCIe模型,虽然我认为这个问题与语言无关。该模型在仿真中完美地执行PCIe配置读写和内存读写。但是,我需要做的是“发现”我的PCIe设备并在模拟中配置我的配置空间寄存器。是否存在代表Linux PCIe枚举过程的锅炉板块伪代码,我可以添加自己的模型事务函数,以便我可以获得“总线步行”,然后进行BAR编程,如果发现了SR-IOV, MSIx配置?这似乎是PCIe设备的常见练习,所以可能有模型。

1 个答案:

答案 0 :(得分:3)

这样做并不是非常困难。基本上,您遍历配置空间,检查第一个根总线0上的每个可能设备。当找到设备时,根据其请求的大小为其分配一个内存空间,并相应地编程BAR。如果找到任何桥,则还可以配置和启用它们 - 此基本桥接寄存器是标准的。这包括分配上游和下游总线编号,然后允许您枚举新的下游总线,等等。

我必须这样做一次才能访问没有操作系统或其他软件环境的系统上的PCI I / O卡。它并不太糟糕,它来自两个供应商的两个桥接器,以及I / O卡寄存器和CPU总线根桥设置。这是PCI,而不是PCIe,但它会非常相似。如果硬件永远不会改变,你甚至可以用完全硬编码的数字来做,但在我的情况下有几个变种,所以我实际上不得不做一些简单的枚举来动态地找到设备号。一个问题是,在尝试访问它们之前,您可能需要延迟一点或重试,以便让所有设备有时间上线。

在这样做的过程中,我发现这本书非常宝贵PCI Express System Architecture (1st Edition)。我注意到还有一个PCIe版本:drivers/pci/pci.c。如果你还没有,我肯定会得到其中一个。这些书包含有关如何完成所有这些操作的详细算法和解释。当时我并没有真正使用或引用任何代码,但是......

我找到的最佳代码资源是U-Boot 。它以类似的低级别运行,并且完全独立,并且仍然相当小并且尽可能简单。例如,枚举似乎从函数pci_init()调用特定于板pci_xxx_init()开始。然后设置根网桥,然后在drivers/pci/pci_auto.c中调用pci_hose_scan_bus()来完成实际工作。另请查看{{3}}中的例程以及文件夹的其余部分。

对于您的任务,您可能只需要一个非常小的子集,并且可以将这些文件的一部分破解成一个简单的驱动程序。基本上是for()循环和一些pci_read / write_config()调用,用逻辑来识别你的设备和网桥ID。