一、PCI 协议概述
PCI总线标准是intel在很早以前推出的一种连接主板和外部设备的总线标准,全称为[Peripheral Component Interconnect]。
任何事物的出现总是有其时代性,在PC领域也不例外。PCI的出现也是因为当时PC的性能和设计成本的要求。
PCI针对ISA总线,做了不少改进,具有不少的优势。
PCI槽在主板上是很容易找到的,一般都是乳白色的插槽,如下图所示。不过现在市场上的主板基本都不在有PCI槽,或者有1个。
目前均使用更高性能的、pci的下一代接口PCI-express。这都是后话了。
PCI总线的 地址总线 与 数据总线 是分时复用的,支持即插即用 (plug andplay)、中断共享等功能。
分时复用的好处是一方面可以节省接插件的引脚数,另一方面便于实现突发数据传输。
比如即插即用和中断共享这两个特点就足以把ISA比下去了。
传统的ISA设备在插入系统之后,需要调整BIOS来添加一些特定的配置,而且中断也是独享的,系统的irq用一个就少一个;
如果使用PCI总线,设备插入之后,BIOS会自动根据pci卡的特性分配IO、MEM空间和IRQ,并且IRQ是可以在PCI设备中共享的。PCI架构确实增加了系统的灵活性。
在带宽方面PCI总线在当时来说也提高了很多,这才是最关键的优势了。
33.33 MHz时钟 的同步传输;也有66MHz的扩展时钟频率。总线带宽为32bit,当然也有64bit的扩展。
最大传输133 MB/s (133 megabytes per second) for 32-bit bus width(33.33 MHz × 32 bits ÷ 8 bits/byte = 133 MB/s)。
对于64M的频率来说,总线带宽可以达到264MB/s。
32 或 64位的内存位址, 32位元 I/O port 空间
PCI 规范
想要了解PCI的规范,最权威的资料要属PCI Spec了。这些规范,包括PCIe,均是由美国的PCI-SIG协会(PCI特别兴趣小组)来管理和更新。
总线规范中也列出来适宜阅读的人群和工种。对于底层的软件工程师BIOS来说,基本需要了解如下几个章节:
Chapter 1 introduction 总线介绍
Chapter 2 Signal definition 信号定义
Chapter 3 Bus Operation 总线操作
Chapter 6 configuration space 配置空间
然作为BIOS工程师来说,不仅仅是阅读spec这么简单。解决问题才是最终目的。spec的东西还是比较晦涩难懂的,属于理论的层面,在具体的操作实践中会完全就是两回事了。
将会碰到的事情很多,比如:
1、 PCI device 配置空间的访问和配置方法和原则
2、 PCI 总线的遍历
3、 PCI 设备的IRQ分配原则和方式
4、 PCI 分配memory /IO的原则和方式
5、 PCI Bridge 的概念和工作原理
最终的还是需要落实到一点:看源代码和spec。
二、PCI 接口定义
PCI协议规定,对于目标设备至少需要47Pin来实现功能,而主设备则需要49Pin来实现。
这些功能包括:处理数据、寻址、接口管理、仲裁机制和系统功能。
下图列出总线上的所有Pin脚,以直观的视角了解PCI总线。
A、系统Pin脚
CLK :
系统时钟信号,对于所有的PCI设备都是输入信号。一般都是从Clock Gen那边拉出来的。其频率可达33MHZ(当然可以达到66MHz),最低频率一般为0HZ(DC),这一频率也称为PCI的工频率。PCI的所有信号,除了RST#、INTA#、INTB#、INTC#、INTD#之外,其余信号都在CLK的上升沿有效(或采样)。
RST#:
复位信号,输入pin。用来使PCI专用的特性寄存器和时序相关的信号恢复规定的初始状态。每当复位时,PCI的全部输出信号一般都应驱动到tri-stated。SERR#信号为高阻状态,SBD#和SDONE可驱动到低电平(如果未提供三态门输出)。REQ#和GNT#必须同时驱动到三态,不能在复位期间为High 或为Low。为防止AD、C/BE#及PAR在复位期间浮动,需要将它们驱动到Low,不能是High。
B、地址和数据信号
AD[31::00]:
地址、数据多数复用的输入/输出信号。在寻址周期AD[31:0]包含32bit的物理地址;对于IO,则是1个byte的地址,对于配置空间和memory空间访问,则是Dword的地址。在数据周期,AD则表示32bit的数据。
C/BE[3::0]#:
总线命令和字节使能多路复用信号线。在地址期中,这四条线上传输的是总线命令;在数据期内,它们传输的是字节使能信号,用来表示整个数据期中,AD[31::00]上哪些字节为有效数据。比如C/BE[0]#表示使能AD上的byte0,C/BE[3]#则使能AD上的byte3.
C、接口控制信号
FRAME#::
帧周期信号。由当前主设备驱动,表示一次访问的开始和持续时间。
IRDY# :
主设备(initiator)准备好信号。在写周期内该信号有效表示数据已经在AD[31::00]中;在读周期内该信号声明,表示主设备已经做好接收数据的准备。
TRDY#:
从设备(target)准备好信号。在写周期内表示从设备已经做好接收数据的准备;在读周期内有效,表示数据已经在AD[31::00]线上。
IRDY#和TRDY# 信号一般是一起使用的。IRDY#表示initiator ready; TRDY#表示target ready。
数据需要传输,必须IRDY#和TRDY#都要宣告好。如果两个信号都没有动作,那么总线处于wait cycles。
IRDY#信号,在Write周期,I#表明在AD总线上存在数据,已经准备开始传输了。在Read周期,I#表明master已经准备好接受AD上的数据。针对TRDY#同样道理。Write周期,T#表示target开始接受数据了。 Read周期,T#表明数据已经在AD线上了,等待接受。
STOP# :
停止数据传送信号。Targe申请需要停止数据传输。
LOCK#:
锁定信号。一般在专有设备才会使用该信号。
IDSEL:
初始化设备选择信号。在配置周期读写传输期间,用作片选信号。设备的输入pin。
DEVSEL#:
设备选择信号。该信号有效时,表示驱动它的设备已按照当前的地址译码成为了当前访问的从设备。
PCI总线上基本的Read 操作:
D、PCI仲裁信号(Bus master only)
REQ#: 总线占用请求信号。它是一个点到点的信号线,任何主设备都有其REQ#信号。
GNT#: 总线占用允许信号。这也是一个点到点的信号线,任何主设备都应有自己的GNT#信号。
E、错误汇报信号
PERR#:
数据奇偶校验错误报告。但该信号不报告特殊周期中的数据奇偶错。
一个设备只有在响应设备选择信号(DEVSEL#)和完成数据期之后,才能报告一个PERR#。
对于每个数据接收设备,如果发现数据有错误,就应在数据收到后的两个时钟周期内将PERR#激活。
该信号的持续时间与数据期的多少有关,如果是一个数据期于,则最小持续时间为一个时钟周期;
若是一连串的数据期并且每个数据期都有错,那么PERR#的持续时间将多于一个时钟周期。
由于该信号是持续的三态信号,因此,该信号在释放前必须先驱动为高电平。
另外,对于数据期奇偶错的报告不能丢失也不能推迟。
SERR#:
系统错误报告信号。该信号的作用是报告地址奇偶错、特殊命令序列的数据奇偶错,以及其它可能引起灾难性后果的系统错误。
F、中断信号
INTA#,INTB#,INTC#,INTD#均为PCI总线上的中断Pin脚,属于可选pin。
定义为水平触发,低电平有效。这些pin的声明是和工作频率CLK不同步的。如果设备需要使用中断,该设备会去拉动INTx#信号,以请求产生中断。直到设备驱动响应了中断,才会释放INTx# pin。
对于PCI单功能设备来说,一般只会使用INTA#pin脚来申请中断;
对于多功能设备才会使用其他的几个Pin:INTB#、INTC#、INTD#。
一个设备不能同时使用两个INTx,但是两个设备可以同时使用同一个INTx。
针对PCI设备使用中断的问题,需要板子上的HW和SW都要设定好对应Route方式,来实现PCI设备的IRQ共享。
如果随便设置的话,有可能导致多个设备同时使用同一个IRQ,而另外的IRQ却是空闲的。这必然导致系统性能变低。
那么这就涉及到PCI的四个中断pin INTx#如何连接到主板上去。在板子的设计开发过程中,BIOS会针对HW上IDSEL pin 和INTx# pin连接的方式来做好PCI irq routing table。这个可以后续再讨论。
HW上 针对AD pin和INTx的搭配有一些规则。
IRQ = (D + I )mod 4
其中,IRQ表示设备使用主板上的irq序号(1/2/3/4);南桥有PIRQa-PIRQd和PIRQe-PIRQh
D表示PCI槽上IDSEL连接到的主板的AD NO;一般情况为AD[31-11]
I表示PCI槽上INTx#的序号(1/2/3/4).
具体的连线搭配如下图。
文章学自: https://blog.csdn.net/pankul/article/category/1346835/2