前言
当我为PCI express编写Xillybus IP核时,我很快发现很难开始:在线资源和官方规格用关于螺母和螺栓的血腥细节轰炸你,但对机器应该做什么却很少说。因此,一旦我努力自己弄清楚这一点,我就决定写这个小指南,希望能帮助其他人获得一个更温和的开始。这基于官方的 PCI Express 规范 1.1,但非常适用于更高版本。不过,阅读原始规范是无可替代的。游戏的名称,如果获得正确的细节,以便设备在手头没有测试的环境中正常工作。
不要因为我没有描述全貌或使用不准确的定义而挑剔我。准确是规范的目的。我在这里要做的就是让它更人性化。我还发布了一个会话的 TLP 嗅探转储示例,这可能有助于了解该机制的工作原理。
PCI Express 不是总线
关于PCI express(以下简称PCIe),首先要意识到它不是PCI-X或任何其他PCI版本。以前的PCI版本(包括PCI-X)是真正的总线:有并行的铜轨物理到达外围卡的多个插槽。PCIe更像是一个网络,每个卡都通过一组专用的电线连接到网络交换机。与本地以太网网络完全一样,每个卡都有自己的与交换机结构的物理连接。相似之处更进一步:通信采用通过这些专用线路传输的数据包的形式,具有流量控制、错误检测和重传功能。没有 MAC 地址,但我们有卡的物理(“地理”)位置来定义它,然后再分配高级寻址方法(I/O 和地址空间中的块)。
事实上,最小的(1x)PCIe连接仅由四根用于数据传输的电线(每个方向两根差分对)和另一对电线组成,用于为卡提供参考时钟。就是这样。
另一方面,PCIe标准被故意设计为与经典PCI非常相似。尽管它是一个基于数据包的网络,但它都是关于地址、读取、写入中断的。
仍然完成了即插即用配置,并且像以前一样,在读取和写入地址和 I/O 空间方面访问卡。仍然有供应商/产品 ID,以及一些模仿旧行为的机制。长话短说,PCIe标准对于一个不了解PCIe的操作系统来说,看起来像是老式的PCI。
因此,PCIe是伪造传统PCI总线的分组网络。它的整个设计使得在不对软件进行任何更改的情况下将PCI设备迁移到PCIe和/或在PCI和PCIe之间透明地桥接而不会丢失任何功能。
简单的总线事务
为了了解整个事情,让我们看看当 PC 的 CPU 想要将 32 位字写入 PCIe 外围设备时会发生什么。为了简单起见,在下面的描述中故意省略了一些细节和可能性。
由于它是一台 PC,因此 CPU 本身很可能在自己的总线上执行简单的写入操作,并且连接到 CPU 总线的内存控制器芯片组直接连接到 PCIe 总线。因此,芯片组(在PCIe术语中充当根复合体)会生成一个内存写入数据包,用于通过总线传输。此数据包由一个标头组成,该标头的长度为 3 或 4 个 32 位字(取决于使用的是 32 位还是 64 位寻址)和一个包含要写入的字的 32 位字。这个数据包只是说“将此数据写入此地址”。
然后,该数据包在芯片组的PCIe端口上传输(如果有多个端口,则为其中一个端口)。目标外设可以直接连接到芯片组,或者它们之间可能存在交换网络。以这种方式或另一种方式,数据包被路由到外围设备,解码,并通过执行所需的写入操作来执行。
细究
这种简单化的观点忽略了几个细节。例如,底层通信机制,它由三层组成:事务层、数据链路层和物理层。上面对数据包的描述被定义为事务层数据包 (TLP),它与 PCIe 的最上层有关。
数据链路层负责确保每个 TLP 正确到达其目的地。它使