八、PCI总线的其它操作

8.1、设备选择

一个设备是否被选中,是由DEVSEL#信号来指示的。DEVSEL#由当前传输中的目标设备所驱动,如下图所示。

八、PCI总线的其它操作

DEVSEL#信号可在地址期之后的1个、2个或3个时钟处被驱动,具体时刻可在配置空间的状态寄存器中指定。DEVSEL#的发出必须早于或者同时于目标设备TRDY#、STOP#或读的时钟边沿,也就是说,一个目标设备要先置DEVSEL#有效后才能发出其它目标响应信号。一旦目标设备确定了DEVSEL#信号,就不能在FRAME#被撤销而IRDY#有效时和最后数据期完成之前撤销它。在正常的主设备终止情况下,DEVSEL#的撤销必须与TRDY#的撤销同时发生。

如果在FRAME#有效后的3个时钟周期内,没有设备发出DEVSEL#信号,则按负向译码的设备便可以置DEVSEL#有效并拥有传输的权力。倘若整个系统中没有一个负向译码的设备,则主设备就收不到有效的DEVSEL#信号,它便以自己的方式终止传输。

一个目标设备必须在进行了完全的地址译码之后才能发出DEVSEL#或任何其它的目标响应信号,否则设置DEVSEL#有效是非法的,因为这样可能造成冲突。在非配置命令中,目标设备必须先用FRAME#信号来认可AD线上的信息,然后才能设置DEVSEL#信号;而在配置命令中,目标设备要先用FRAME#和AD[1..0]来认可IDSEL信号后再设置DEVSEL#信号。一般来说,大部分目标设备都能再FRAME#有效之后的1~2个时钟周期内完成地址译码并发出DEVSEL#信号,如上图中的快速档和中速档。

如果一个访问中的地址落入目标节点的地址范围,这个目标就会发出DEVSEL#信号,表示承担这个传输访问。但是,如果主备企图跨越资源边界以继续它的突发传输时,目标节点就应该发出断开信号。

当一个目标设备许诺了一个I/O访问,同时字节使能信号又表示1个或更多的字节不再该设备的地址范围之内时,它就必须发出目标废止信号。对于一个负向译码的设备,如扩展总线桥,为了适应这类I/O问题,可采用如下之一的做法:

1)凡是发现有不同的设备公用一个双字地址时,就以该地址作正向译码,然后再用字节使能信号进行检测,发现问题就实现目标废止。

2)将整个访问都放到扩展总线上,没法服务的部分就丢掉。

8.2、特殊周期命令

该命令提供了PCI总线上简单的信息发布机制(消息广播),用以传达处理机状态,或者发送各个从设备之间的信号。如果不要求精确的时间关系或物理信号同步的情况下,此命令也可用来再PCI设备之间做逻辑的侧面连接信号。

由于特殊周期命令的目的是提供一种消息广播机制,因此该命令的发送中没有明显的目标地址,而是广播给所有的设备,每个接受设备必须自我确定广播的消息是否适合它。PCI总线上的设备不能设置DEVSEL#信号作为对特殊周期命令的响应,也就是说在此类传输中,不需要任何目标握手信号;同时,采用负向译码的桥也不能把特殊周期命令传到它的次级总线上去,即特殊周期命令不能跨桥传播。

一个特殊周期命令可以含有可选的、由消息决定的数据,而且这些数据不需要由PCI序列器本身来解释,它是根据需要传送给与PCI序列器相连的硬件。通常情况下,显式寻址的消息一般不采用特殊周期命令来处理,而是利用PCI总线上的三种物理地址空间的其中之一来处理。

就像其它总线命令一样,特殊周期命令中也包含一个地址期和一个数据期。地址期也是在FRAME#信号有效之时开始,当FRAME#和IRDY#同时撤销时,也表示该命令已经完成,要说它与其它总线命令的唯一区别,那就是没有目标设备给出DEVSEL#响应信号,它时广播给所有设备,然后由感兴趣的设备予以接受并加以处理。

该命令在地址期中,除了发送命令之外不包含其它有效信息。但是,有一点要注意,尽管该命令不含有明显的地址信息,可AD[31..0]要被驱动到一个稳定的电平,同时也要产生奇偶位。在数据期内,AD[31..0]上含有信息类型和一个选型的数据字段,其中低16位AD[15..0]表示i信息类型;高16位AD[31..16]表示选项数据,但并不是所有的信息类型都要求高16位。主设备可以像对待其它总线命令一样,在特殊周期命令中插入等待周期,但是,由于没有固定目标,所以目标设备不能插入等待周期。消息和数据只在IRDY#有效的第一个时钟处有效,而其后数据期中所含信息及时序关系则由消息类型确定。

在地址期中,若C/BE[3..0]# = 0001,则表示特殊周期命令,此时,AD[31..0]别驱动为随机值且必须忽略;在特殊周期命令的数据期中,C/BE[3..0]#要处于有效状态,而AD[31..0]的各位如下表所示。

八、PCI总线的其它操作

PCI序列器启动特殊周期命令的方式与其它的总线命令相同,但该命令的终止则要依靠主设备废止方式。响应的目标设备只要发现主设备废止时就直到访问已经完成,在此情况下,不能将配置空间的状态寄存器的“接收主设备废止位”置为“1”。一般来说,一个特殊周期命令最快可以在5个时钟周期内完成,同时要附加1个时钟周期作为下个访问开始之前的过渡周期(交换周期),换而言之,从一个特殊周期命令的开始到下一个访问之间,需要6个时钟周期。

8.3、数据/地址的渐进

PCI总线上的“事务代理”将一个设备发出的信号拓展到几个时钟周期之内逐步驱动,而不是在一个时钟内完成,这种能力成为渐进(Steping)。此概念的应用,可以使一个设备以“弱的”输出缓冲将一组信号在几个时钟周期内逐渐驱动到有效状态,从而减少了由每个输出驱动所产生的地电流负载。还有以各种渐进的方法是:允许设备以”强的“输出驱动在几个时钟内分批驱动,每个时钟周期驱动一部分信号,直到全部被驱动到有效状态为止,成为分批渐进,此方法可以减少同时开关的信号数量。

上述两种渐进方法,无论哪一种都能使一个芯片的电源线与地线输减少,从而使得设备的性能与价格之间具有取舍自由。但应注意,在采用全部渐进时,必须避免哪些要求严格的控制信号之间的相互耦合,这是因为,本应在各个时钟边沿上取样的信号此时可能在一个时钟边沿上出现跳变,所以,对性能要求较高的设备应慎用这种方法。

并非所有的信号都可以渐进,只要AD[31..0]、AD[64..32]、PAR、PAR64及IDSEL这些信号才行,因为它们总是要由控制信号来认可,或者说,这些信号只有在它们被认可的时钟边沿上才被认为是有效的。我们知道,AD线的确认,在地址期是依靠FRAME#信号,在数据期则是根据数据的传输方向分别依靠IRDY#或TRDY#信号;PAR是在每个认可AD的时钟之后一个周期内隐含确认的;IDSEL信号的确认则是通过FRAME#和译码得到的配置命令相结合来完成的。

下图表示了全部AD线的渐进情况。可以看出,一个主设备将FRAME#的建立一直推迟到该设备成功地驱动了全部AD线时为止。对于主设备来讲,一旦它的总线使用请求得到批准并且总线又处于空闲状态时,那么该设备对AD线和C/BE#线的驱动时允许的,也是必要的,但是它可以利用多个时钟周期来驱动使其达到有效值,然后再发FRAME#信号。

八、PCI总线的其它操作

不过,这种延迟建立FRAME#信号的做法,使得主设备有可能失去总线的控制权,因此,对于任何设备,GNT#信号在FRAME#信号建立之前的一个时钟沿处必须有效,如果此时(上图中标A的时钟边沿)GNT#已被置为无效,仲裁器就会将总线批准给另外一个主设备使用,从而使当前主设备失掉中线控制权,从图中可明显看到,只要GNT#信号在B或C多对应时钟边沿处撤销,那么FRAME#信号就能够建立,并且传输将继续进行。需要说明的是,如果当前主设备失去总线控制时,它应立即将AD线置为第三状态。

8.4、配置周期

PCI的驱动软件提供了一个初始化的配置通道和一块独立的地址空间。为此,PCI设备应具有256字节的配置寄存器,有关这些寄存器的说明见后面章节。本节只讨论位访问PCI配置空间而设立的配置命令,即配置读命令和配置写命令。

一、配置访问

在前面的章节中我们已讨论过,正常的访问中,每个设备都对它自己的地址进行译码。然而,对于配置地址空间的访问,则要求采用另外的方法进行设备选择译码,即通过IDSEL引脚来选择PCI设备,也就时将IDSEL引脚作为”芯片选择“信号。对于某一PCI设备,只有当它的IDSEL引脚上有信号并且AD[1..0]在地址期内为00时,该设备才会被作为配置(读或写)命令的目标设备。64个双字寄存器的内部寻址是通过AD[7..2]和字节使能信号来完成的。

配置命令跟其它总线命令一样,允许以字节、字、双字或者突发操作的方式进行访问;访问过程中的其它操作及终止方式也和一般的命令没有什么差异。如果没有设备响应配置命令,则应由主设备废止。扩展总线桥绝对不能将配置命令传到扩展总线上去。

关于如何准确驱动IDSEL引脚的问题,一般由主桥或系统的设计者去决定。但是,才过去的设计中,该选择信号可以与高21位地址线中的其中一位相连,这是因为在配置访问中,高21位地址线没有别的用途。至于如何用高21位地址来决定IDSEL,还没有现成的或标准的方法可遵循,所以,设备必须留有IDSEL引脚。换而言之,PCI设备不能为了节省一个引脚而在内部将IDSEL信号连到一个条AD线上。唯独总线主桥可以例外,因为它可以决定如何映射IDSEL。

AD[31..0]在地址期中必须全部被驱动为有效状态,其中的每一条可连接一个设备,每次确定AD[31..11]当中的一条为IDSEL信号,从而可以从21一个设备中选择一个设备进行配置读写。

上述利用高21位地址线来决定IDSEL的方法会使AD线上增加一个负载,为此,可以将IDSEL利用电阻耦合到适当的AD上来解决负载加重这一问题。然而这样做,又带来了一个新的问题,那就是使得IDSEL的变化率大为减慢,并且在大部分时间内处于无效的逻辑状态。如下图中的”XXXX“所示的数据区段。

八、PCI总线的其它操作

万幸的是,IDSEL信号只有在一个配置命令的地址期内才会用到,所以可以在FRAME#建立之前的几个时钟周期内,将与IDSEL相连的地址线进行预先驱动,以保证IDSEL信号在需要被采样时是稳定有效的。地址总线的预先驱动方法与前述的地址/渐进相类似。

为了支持分层的PCI总线,采用了两种类型的配置访问,分别成为0类配置访问和1类配置访问,其格式如下:

八、PCI总线的其它操作

从上面的格式表示中可以看出,它们的实质是表示了AD线在配置命令的地址其中的用法。两类访问的区别在于AD[1..0]线上的取值不同。对于0类配置访问,AD[1..0] = 00,用来在运行的PCI总线上选择一个设备;对于1类配置访问,AD[1..0] = 01,用来将一个配置请求传递到另一条PCI总线上。可见,在此处AD[1..0]相当于标志位。

两类配置访问中的寄存器编号和功能编号字段具有相同的含义;设备编号和总线编号字段只用于1类配置访问中;目标设备对保留字段应予以忽略,不能做出任何响应。

下面对上述各字段的具体含义做一说明:

寄存器号:选择目标设备配置空间中的一个双字(DWORD)。

功能号:用来选择多功能设备的某一个功能,有八种功能供选择。

设备号:用以在一条给定的总线上选择32个设备的其中之一。但是如果采用IDSEL与一条AD线相连,只能选择到21个设备。

总线号:用以在一个系统中从256条总线中选择一条。

无论是主桥还是PCI到PCI的桥,如果需要残生一个0类配置访问时,要用设备号决定建立哪一条IDSEL信号;在AD[10..8]上提供功能号;在AD[7..2]上给出寄存器号;AD[1..0]此时必须为00以表示为0类配置空间。0类配置访问不会传播到本地PCI总线以外的总线上去,因此,必须要有一个本地设备对其做出响应,否则,主设备就会将该次访问废止。

倘若配置访问的目标不再本地总线上,而是在另一条PCI总线上,那就必须用1类配置访问。也就是说,1类访问只适用于PCI到PCI的桥,其它所有目标设备都将其忽略,不作任何响应。这些桥对总线号字段进行译码,以判断配置访问的目标是否驻留在自己的桥路之后。如果总线号不是只想自己桥路后面的一条总线,就将它忽略,如果访问的目标时本桥路后面的一条总线,此桥就要接收这次配置访问,其具体的响应又分为两种情况:①如果总线编号与该桥路所带总线相符,此桥就要把这个1类访问变换成0类配置访问,也就是将AD[1..0]由01转变为00,而AD[10..2]保持原值不变,同时对设备号进行译码从而选择一个IDSEL在相应的线上发出,开始一次配置访问;②如果总线编号与该桥路所带的总线不相符,此桥就会将配置访问直接向下一级传递。

有两种类型的设备可以响应0类配置访问:其一为单功能设备,是为了做到向后兼容而设定的,响应于否只需要利用它的IDSEL引脚和AD[1..0] = 00来决定;其二为多功能设备,能够接收功能编号字段,需要利用它的IDSEL引脚、AD[1..0] = 00及AD[10..8]的编码值这三个条件来决定是否响应相应的配置访问。这两类设备的却别在于它们的配置空间的头标区的编码值不同。

对于多功能设备,必须能对AD[10..8]进行完全译码。 以选择相应的功能,而且,只有那些在配置空间寄存器组中实现的功能才能得到响应。在它们所实现的功能中,必须具有0号功能,其它的功能都是可选的,并且功能编号可任意选择。例如,有一个2功能设备,那它必须有0号功能,而第二个功能的编号可以是1~7中当中的任何一个号码。