PCI总线到底是什么?如何理解这个机制?

PCI总线到底是什么?如何理解这个机制?

PCI总线,这是啥玩意呢?现在大部分人只知道这货是PCIe总线的前身,而且是已被淘汰了十多年的总线,为什么还要拿出来讲呢?

记得那是12年的时候,Intel出了最后一代支持PCI总线的X86(记得似乎是Ivy Bridge),我还为之焦虑了一阵;因为在我们的硬件方案中X86与CPLD是通过PCI总线连接的(更早之前用的 Motorola(Freescale的前身)PowerPC CPU是用Local Bus扩展的),如果只剩下了PCIe接口,而CPLD又不支持PCIe,那只能自己硬着头皮写一个LPC总线的CPLD接口来实现(最后自己还真用Verilog写了一个LPC接口)。

当年CPLD代码中用的PCI接口模块是部门共用模块,但如果CPLD逻辑出问题了,还是得自己定位,没办法只能一边看代码,一边看PCI总线协议的内容,把这部分协议了解个7788;过了几年又参与到了NVME(PCIe3.0接口固态硬盘)项目中去,这次PCIe应用就复杂的太多,各种各样稀奇古怪的问题频出:兼容性的、热插拔的、丢包的、协商出错的……;Intel这个商用标准的协议,要搞出工业标准要求的可靠性应用,难度真的不小,不过那又是另外一个故事了。

废话了这么多,其实我想说的是:PCI总线和PCIe总线除了物理形态不一样之外,但从软件层面看来两者是一样的;PCIe总线协议是兼容PCI总线协议的,我们可以通过对PCI总线的学习,就更能理解PCIe总线协议。

好,老规矩,咱们从它的历史开始说起。

PCI总线:Peripheral Component Interconnect; PCI总线也属于局部总线(Local Bus)的一种,当然从它的名字中,我们也可以知道它是系统总线的延伸,用于连接CPU与外围组件。随着CPU性能的提升,如上一章所述ISA总线先是被LPC总线替代,现在又被eSPI总线所替代;PCI总线的出现也是淘汰了EISA(Extended Industry Standard Architecture)、VESA(Video Electronics Standards Association)等32位的总线,从那时起它便一直占据了处理器体系结构中的重要地位。

——我习惯称Local Bus是地址/数据信号分离的局部总线(已灭迹好多年,很多应用被SPI总线所替代),虽然PCI总线也属于Local Bus的一种。

那么PCI总线有怎样的魅力,能在快速发展的处理器体系结构中经久不衰呢?而与它同时代的局部总线却早已被淹没在时代的洪流之下了。这就不得不说到“投胎”的技术了:PCI总线规范由Intel的IAL(Intel Architecture Lab)提出,并在1992年正式发布V1.0版本;那么IAL是个啥组织?它是Intel的一个重要实验室,提出了:USB,AGP(Accelerated Graphics Port,替代了VESA总线),PCIe总线规范;甚至连X86的南北桥结构也是由它提出的。

到了1996年, PCISIG(PCI Special Interest Group)陆续发布了PCI总线V2.2,V2.3规范,而PCI总线规范最终定个在V3.0版本。除了PCI总线规范本身之外,PCISIG还定义了与PCI总线相关的规范:PCMCIA(Personal Computer Memory Card International Association)规范、MiniPCI规范,PCI-to-PCI桥规范、PCI电源管理规范、PCI热插拔规范以及CompactPCI总线规范。

——PCI-to-PCI桥规范是理解PCI体系结构的基础,CompactPCI规范用于背板结构大型系统,支持热插拔(当年进公司后做的第一个项目就是类似CPCI架构的设备,然后是ATCA架构(mTCA)的设备)。

PCI总线规范这么多年来取得了巨大的成功,虽然规范中有很多内容是基于Intel架构的X86处理器,但是在其它处理器系统上也有着非常广泛的应用,大多数处理器系统优选使用PCI/PCIe总线来连接外设。随着处理器技术的快速发展,PCI和PCI-X总线遇到了瓶颈,单端并行数据传输方式,限制了总线频率的进一步提升,所以高速串行总线逐步替代了并行总线,而PCIe总线最终替代了PCI总线成为主流。

——不考虑并行数据信号复杂度、功耗以及所占PCB面积等的问题,为什么单端并行数据传输模式的数据速率会受到限制呢?我们知道数据传输需要有时钟来采样,必须要有建立时间(ts)和保持时间(th),如果有64根数据线要实现高速同步传输,就必须要求时钟信号与64根信号线保持精确等长,走线路径环境(PCB板材、过孔以及连接器等)相同,还不能受到串扰等等(看过《信号完整性基础》这章内容的胖友们应该就知道,这是非常困难的),所以实现起来难度非常高;但是为什么DDR总线却可以呢?现在DDR5的速率可以支持到6.4Gbps,它为什么能这么牛B的单端并行传输?有兴趣的胖友们,可以思考下这个问题,DDR总线是如何解决这些问题的。

PCI总线相比于前面介绍的IIC,SPI,LPC以及eSPI总线都复杂了太多,这是一个很大的系统(记得当年刚工作时,学习TCP/IP协议红宝书,看的昏天暗地的,根本就看不懂,好不容易理解了的一点东西也早已忘光),因为它是处理器连接外部设备的主要总线,可以实现管理或业务的功能。

如下图展示了一个基于PCI总线的老系统结构。该系统包括一个北桥(North Bridge,位于中央PCI总线的北方向),北桥是处理器与PCI总线之间的接口。与北桥相连的是处理器总线(processor bus)、系统存储总线(system memory bus)、AGP图像总线(AGP graphics bus),以及PCI总线。这些设备共享PCI总线,它们要么直接与总线相连,要么作为插卡插入到连接器上。在中央PCI总线的“南方”有一个南桥(South Bridge),它用于将PCI与系统外设相连接,这里的系统外设可以是为了使用旧的遗留设备而应用发展了多年的ISA总线。南桥通常也是PCI的中心资源区(central resource),它提供了一些系统信号诸如复位、参考时钟和错误报告操作。

我们知道PCI总线与处理器总线(FSB)以及存储总线(DDR)三者是相互分离的。如下图所示,PCI总线作为处理器系统的局部总线,是处理器系统的一个组成部分。

PCI总线相关的模块包括了:HOST主桥,PCI总线,PCI桥以及PCI设备。

如上所述,HOST主桥的基本功能是分离存储器域和PCI总线域,实现PCI总线域到存储器域,存储器域到PCI总线域之间的数据传递,并管理PCI设备的配置空间。如下图所示,划分了存储器域和PCI总线域;存储器域中划分为CPU域和DRAM域,而PCI域由HOST主桥所决定。

——对于x86来说,外部设备域即为PCI总线域;对于其它处理器来说,很多外设直接挂在FSB总线上而不是挂在PCI总线下。

——非常重要的一点:在处理器系统中,HOST主桥管理着PCI总线域,而不是HOST处理器;如果一个处理器系统中有多个CPU,那么每个CPU都可以成为HOST主桥所管理PCI总树的HOST处理器。

1,处理器访问PCI总线域地址空间时:首先需要访问存储器域的地址空间,再通过HOST主桥将存储器地址转换成PCI总线地址,之后才能进入PCI总线域进行数据交换;

2,PCI设备访问存储器时:首先需要访问PCI总线域的地址空间,再通过HOST主桥将PCI总线地址转换为存储器地址,才能进行数据交换;

——此时处理器需要通过HOST主桥将PCI总线地址反向映射为存储器地址,否则不能访问存储器域地址。

4,如果HOST主桥不支持Peer-to-Peer传输方式,那么不同PCI总线域的PCI设备之间不能直接进行数据交换,而需要通过FSB总线实现。

PCI体系结构支持3种地址空间,如图下图所示:Memory(内存)、I/O、Configuration Address Space(配置地址空间)。x86处理器可以直接访问Memory和I/O空间:如上所述PCI设备映射到处理器内存地址空间,可以支持32位(4GB)或64位寻址;在I/O地址空间,PCI设备可以支持32位寻址,但是因为x86 CPU仅使用16位的I/O地址空间,所以I/O空间限制在了64KB。

PCI还引进了第三种地址空间,称为配置空间(Configuration Address Space),CPU只能对它进行间接访问而非直接访问(软件不能通过命令直接访问到配置空间寄存器)。PCI设备中的每个Function(功能)都包含专为配置空间所准备的内部寄存器,这些寄存器对于软件来说是可见的,并且软件可以通过一个标准化的方式来控制它们的地址与资源,这为PC提供了一个真正的即插即用(plug and play)的环境。每个PCI Function最多可以有256 Bytes的配置地址空间,PCI总线系统的配置空间总大小为16MB。

——PCI最多可支持单个设备含有8个Function、每路总线含有32个设备、单个系统包含256路总线,那么可以得到一个系统的配置空间总量为:256B/Function *8Function/device * 32devices/bus *256buses/system =16MB。

因为x86 CPU无法直接访问配置空间,所以它必须通过IO寄存器进行索引(然而在PCI Express中引入了一种新方法来访问配置空间,这种新方法是通过将配置空间映射入内存地址空间来完成的)。在传统模型中,如上图所示,使用了一种被称为配置地址端口(Configuration Address Port)的IO端口,它位于地址CF8h-CFBh;还使用了一种被称为配置数据端口(Configuration Data Port)的IO端口,它位于地址CFCh-CFFh。

我们再次回到PCI总线的结构,如上所述PCI总线相关的模块包括了:HOST主桥,PCI总线,PCI桥和PCI设备;

——对于多CPU的处理器,这些CPU都可以通过HOST主桥访问其下的PCI总线树,作为HOST处理器;但上面已经说了:PCI总线树的实际管理者是HOST主桥,而非HOST处理器。

PCI总线相比于EISA和MCA总线相比有很多突出的优点:

PCI总线是一条共享总线,一条PCI总线上可以挂接多个PCI设备;这些PCI设备通过信号线与PCI总线相连:地址/数据信号,控制信号,仲裁信号,中断信号等等。同时PCI总线也是一个同步总线,每个设备都有一个CLK信号,发送设备和接收设备使用CLK信号进行数据同步传输;PCI总线使用33MHz和66MHz时钟频率,而PCI-X总线可以使用133MHz、266MHz或533MHz的时钟频率。PCI总线信号如下表所示。

11. INTA/B/C/D#:中断请求信号,PCI设备使用这些中断请求信号向处理器发送中断请求:当中断请求信号为低时,PCI设备想处理器提交中断请求;当处理器执行中断服务程序清楚PCI设备的中断请求后,PCI设备将该信号置高,结束中断请求;——单功能(Function)PCI设备只能使用INTA#,而多功能(Function)设备才能使用INTB#/C#/D#。

1,地址奇偶校验错误;

2,在Special Cycle周期中出现数据奇偶校验错误;

3,系统出现其它严重错误。

PCI总线的管理采用单独管脚信号(带外)来实现,但到了PCIe总线中这些管理功能是前向兼容PCI总线的,这些信号的功能被转移到了带内来实现。