单片机怎么通过host桥访问pcie 桥和开关的区别设备

第1章 PCI总线的基本知识
我的图书馆
第1章 PCI总线的基本知识
第1章&PCI总线的基本知识
PCI总线作为处理器系统的局部总线,主要目的是为了连接外部设备,而不是作为处理器的系统总线连接Cache和主存储器。但是PCI总线、系统总线和处理器体系结构之间依然存在着紧密的联系。
PCI总线作为系统总线的延伸,其设计考虑了许多与处理器相关的内容,如处理器的Cache共享一致性和数据完整性,以及如何与处理器进行数据交换等一系列内容。其中Cache共享一致性和数据完整性是现代处理器局部总线的设计的重点和难点,也是本书将重点讲述的主题之一。
独立地研究PCI总线并不可取,因为PCI总线仅是处理器系统的一个组成部分。深入理解PCI总线需要了解一些与处理器体系结构相关的知识。这些知识是本书所侧重描述的,同时也是PCI总线规范所忽略的内容。脱离实际的处理器系统,不容易也不可能深入理解PCI总线规范。
对于今天的读者来说,PCI总线提出的许多概念略显过时,也有许多不足之处。但是在当年,PCI总线与之前的存在其他并行局部总线如ISA、EISA和MCA总线相比,具有许多突出的优点,是一个全新的设计。
PCI总线空间与处理器空间隔离
PCI设备具有独立的地址空间,即PCI总线地址空间,该空间与存储器地址空间通过HOST主桥隔离。处理器需要通过HOST主桥才能访问PCI设备,而PCI设备需要通过HOST主桥才能主存储器。在HOST主桥中含有许多缓冲,这些缓冲使得处理器总线与PCI总线工作在各自的时钟频率中,彼此互不干扰。HOST主桥的存在也使得PCI设备和处理器可以方便地共享主存储器资源。
处理器访问PCI设备时,必须通过HOST主桥进行地址转换;而PCI设备访问主存储器时,也需要通过HOST主桥进行地址转换。HOST主桥的一个重要作用就是将处理器访问的存储器地址转换为PCI总线地址。PCI设备使用的地址空间是属于PCI总线域的,而与存储器地址空间不同。
x86处理器对PCI总线域与存储器域的划分并不明晰,这也使得许多程序员并没有准确地区分PCI总线域地址空间与存储器域地址空间。而本书将反复强调存储器地址和PCI总线地址的区别,因为这是理解PCI体系结构的重要内容。
PCI规范并没有对HOST主桥的设计进行约束。每一个处理器厂商使用的HOST主桥,其设计都不尽相同。HOST主桥是联系PCI总线与处理器的核心部件,掌握HOST主桥的实现机制是深入理解PCI体系结构的前提。
本书将以Freescale的PowerPC处理器和Intel的x86处理器为例,说明各自HOST主桥的实现方式,值得注意的是本书涉及的PowerPC处理器仅针对Freescale的PowerPC处理器,而不包含IBM和AMCC的Power和PowerPC处理器。而且如果没有特别说明,本书中涉及的x86处理器特指Intel的处理器,而不是其他厂商的x86处理器。
PCI总线具有很强的扩展性。在PCI总线中,HOST主桥可以直接推出一条PCI总线,这条总线也是该HOST主桥的所管理的第一条PCI总线,该总线还可以通过PCI桥扩展出一系列PCI总线,并以HOST主桥为根节点,形成1颗PCI总线树。这些PCI总线都可以连接PCI设备,但是在1颗PCI总线树上,最多只能挂接256个PCI设备(包括PCI桥)。
在同一条PCI总线上的设备间可以直接通信,并不会影响其他PCI总线上设备间的数据通信。隶属于同一颗PCI总线树上的PCI设备,也可以直接通信,但是需要通过PCI桥进行数据转发。
PCI桥是PCI总线的一个重要组成部件,该部件的存在使得PCI总线极具扩展性。PCI桥也是有别于其他局部总线的一个重要部件。在“以HOST主桥为根节点”的PCI总线树中,每一个PCI桥下也可以连接一个PCI总线子树,PCI桥下的PCI总线仍然可以使用PCI桥继续进行总线扩展。
PCI桥可以管理这个PCI总线子树,PCI桥的配置空间含有一系列管理PCI总线子树的配置寄存器。在PCI桥的两端,分别连接了两条总线,分别是上游总线(Primary Bus)和下游总线(Secondary Bus)。其中与处理器距离较近的总线被称为上游总线,另一条被称为下游总线。这两条总线间的通信需要通过PCI桥进行。PCI桥中的许多概念被PCIe总线采纳,理解PCI桥也是理解PCIe体系结构的基础。
动态配置机制
PCI设备使用的地址可以根据需要由系统软件动态分配。PCI总线使用这种方式合理地解决了设备间的地址冲突,从而实现了“即插即用”功能。从而PCI总线不需要使用ISA或者EISA接口卡为解决地址冲突而使用的硬件跳线。
每一个PCI设备都有独立的配置空间,在配置空间中含有该设备在PCI总线中使用的基地址,系统软件可以动态配置这个基地址,从而保证每一个PCI设备使用的物理地址并不相同。PCI桥的配置空间中含有其下PCI子树所能使用的地址范围。
PCI总线与之前的局部总线相比,极大提高了数据传送带宽,32位/33MHz的PCI总线可以提供132MB/s的峰值带宽,而64位/66MHz的PCI总线可以提供的峰值带宽为532MB/s。虽然PCI总线所能提供的峰值带宽远不能和PCIe总线相比,但是与之前的局部总线ISA、EISA和MCA总线相比,仍然具有较大的优势。
ISA总线的最高主频为8MHz,位宽为16,其峰值带宽为16MB/s;EISA总线的最高主频为8.33MHz,位宽为32,其峰值带宽为33MB/s;而MCA总线的最高主频为10MHz,最高位宽为32,其峰值带宽为40MB/s。PCI总线提供的峰值带宽远高于这些总线。
共享总线机制
PCI设备通过仲裁获得PCI总线的使用权后,才能进行数据传送,在PCI总线上进行数据传送,并不需要处理器进行干预。
PCI总线仲裁器不在PCI总线规范定义的范围内,也不一定是HOST主桥和PCI桥的一部分。虽然绝大多数HOST主桥和PCI桥都包含PCI总线仲裁器,但是在某些处理器系统的设计中也可以使用独立的PCI总线仲裁器。如在PowerPC处理器的HOST主桥中含有PCI总线仲裁器,但是用户可以关闭这个总线仲裁器,而使用独立的PCI总线仲裁器。
PCI设备使用共享总线方式进行数据传递,在同一条总线上,所有PCI设备共享同一总线带宽,这将极大地影响PCI总线的利用率。这种机制显然不如PCIe总线采用的交换结构,但是在PCI总线盛行的年代,半导体的工艺、设计能力和制作成本决定了采用共享总线方式是当时的最优选择。
PCI总线上的设备可以通过四根中断请求信号INTA~D#向处理器提交中断请求。与ISA总线上的设备不同,PCI总线上的设备可以共享这些中断请求信号,不同的PCI设备可以将这些中断请求信号“线与”后,与中断控制器的中断请求引脚连接。PCI设备的配置空间记录了该设备使用这四根中断请求信号的信息。
PCI总线进一步提出了MSI(Message Signal Interrupt)机制,该机制使用存储器写总线事务传递中断请求,并可以使用x86处理器FSB(Front Side Bus)总线提供的Interrupt Message总线事务,从而提高了PCI设备的中断请求效率。
虽然从现代总线技术的角度上看,总线仍有许多不足之处,但也不能否认总线已经获得了巨大的成功,不仅处理器将总线作为标准的局部总线连接各类外部设备,、和处理器也将总线作为标准局部总线。除此之外,基于总线的外部设备,如以太网控制器、声卡、硬盘控制器等,也已经成为主流。
在ARM处理器中,使用SoC平台总线,即AMBA总线,连接片内设备。但是某些ARM生产厂商,依然使用AMBA-to-PCI桥推出PCI总线,以连接PCI设备。1.1&PCI总线的组成结构
如上文所述,PCI总线作为处理器系统的局部总线,是处理器系统的一个组成部件,讲述PCI总线的组成结构不能离开处理器系统这个大环境。在一个处理器系统中,与PCI总线相关的模块如图1?1所示。
如图1?1所示在一个处理器系统中,与PCI总线相关的模块包括,HOST主桥、PCI总线、PCI桥和PCI设备。PCI总线由HOST主桥和PCI桥推出,HOST主桥与主存储器控制器在同一级总线上,PCI设备可以方便地通过HOST主桥访问主存储器,即进行DMA操作。
值得注意的是,PCI设备的DMA操作需要与处理器系统的Cache进行一致性操作,当PCI设备通过HOST主桥访问主存储器时,Cache一致性模块将进行地址监听,并根据监听的结果改变Cache的状态。
在一些简单的处理器系统中,可能不含有PCI桥,此时所有PCI设备都是连接在HOST主桥推出的PCI总线上,此外在一些处理器系统中可能含有多个HOST主桥,如在图1?1所示的处理器系统中含有HOST主桥x和HOST主桥Y。
HOST主桥是一个很特别的桥片,其主要功能是隔离处理器系统的存储器域与处理器系统的PCI总线域,管理PCI总线域,并完成处理器与PCI设备间的数据交换。处理器与PCI设备间的数据交换主要由“处理器访问PCI设备的地址空间”和“PCI设备使用DMA机制访问主存储器”这两部分组成。
为简便起见,下文将处理器系统的存储器域简称为存储器域,而将处理器系统的PCI总线域称为PCI总线域,存储器域和PCI总线域的详细介绍见第2.1节。值得注意的是,在一个处理器系统中,有几个HOST主桥,就有几个PCI总线域。
HOST主桥在处理器系统中的位置并不相同,如PowerPC处理器将HOST主桥与处理器集成在一个芯片中。而有些处理器不进行这种集成,如x86处理器使用南北桥结构,处理器内核在一个芯片中,而HOST主桥在北桥中。但是从处理器体系结构的角度上看,这些集成方式并不重要。
PCI设备通过HOST主桥访问主存储器时,需要与处理器的Cache进行一致性操作,因此在设计HOST主桥时需要重点考虑Cache一致性操作。在HOST主桥中,还含有许多数据缓冲,以支持PCI总线的预读机制。
HOST主桥是联系处理器与PCI设备的桥梁。在一个处理器系统中,每一个HOST主桥都管理了一颗PCI总线树,在同一颗PCI总线树上的所有PCI设备属于同一个PCI总线域。如图1?1所示,HOST主桥x之下的PCI设备属于PCI总线x域,而HOST主桥y之下的PCI设备属于PCI总线y域。在这颗总线树上的所有PCI设备的配置空间都由HOST主桥通过配置读写总线周期访问。
如果HOST主桥支持PCI V3.0规范的Peer-to-Peer数据传送方式,那么分属不同PCI总线域的PCI设备可以直接进行数据交换。如图1?1所示,如果HOST主桥y支持Peer-to-Peer数据传送方式,PCI设备y01可以直接访问PCI设备01或者PCI设备11,而不需要通过处理器的参与。但是这种跨越总线域的数据传送方式在PC架构中并不常用,在PC架构中,重点考虑的是PCI设备与主存储器之间的数据交换,而不是PCI设备之间的数据交换。此外在PC架构中,具有两个HOST主桥的处理器系统也并不多见。
在PowerPC处理器中,HOST主桥可以通过设置Inbound寄存器,使得分属于不同PCI总线域的设备可以直接通信。许多PowerPC处理器都具有多个HOST主桥,有关PowerPC处理器使用的HOST主桥详见第2.2节。
在处理器系统中,含有PCI总线和PCI总线树这两个概念。这两个概念并不相同,在一颗PCI总线树中可能具有多条PCI总线,而具有血缘关系的PCI总线组成一颗PCI总线树。如在图1?1所示的处理器系统中,PCI总线x树具有两条PCI总线,分别为PCI总线x0和PCI总线x1。而PCI总线y树中仅有一条PCI总线。
PCI总线由HOST主桥或者PCI桥管理,用来连接各类设备,如声卡、网卡和IDE接口卡等。在一个处理器系统中,可以通过PCI桥扩展PCI总线,并形成具有血缘关系的多级PCI总线,从而形成PCI总线树型结构。在处理器系统中有几个HOST主桥,就有几颗这样的PCI总线树,而每一颗PCI总线树都与一个PCI总线域对应。
与HOST主桥直接连接的PCI总线通常被命名为PCI总线0。考虑到在一个处理器系统中可能有多个主桥,图1?1将HOST主桥x推出的PCI总线命名为x0总线,而将PCI桥x1扩展出的PCI总线称之为x1总线;而将HOST主桥y推出的PCI总线称为y0~yn。分属不同PCI总线树的设备,其使用的PCI总线地址空间分属于不同的PCI总线域空间。
在PCI总线中有三类设备,PCI主设备、PCI从设备和桥设备。其中PCI从设备只能被动地接收来自HOST主桥,或者其他PCI设备的读写请求;而PCI主设备可以通过总线仲裁获得PCI总线的使用权,主动地向其他PCI设备或者主存储器发起存储器读写请求。而桥设备的主要作用是管理下游的PCI总线,并转发上下游总线之间的总线事务。
一个PCI设备可以即是主设备也是从设备,但是在同一个时刻,这个PCI设备或者为主设备或者为从设备。PCI总线规范将PCI主从设备统称为PCI Agent设备。在处理器系统中常见的PCI网卡、显卡、声卡等设备都属于PCI Agent设备。
在PCI总线中,HOST主桥是一个特殊的PCI设备,该设备可以获取PCI总线的控制权访问PCI设备,也可以被PCI设备访问。但是HOST主桥并不是PCI设备。PCI规范也没有规定如何设计HOST主桥。
在PCI总线中,还有一类特殊的设备,即桥设备。桥设备包括PCI桥、PCI-to-(E)ISA桥和PCI-to-Cardbus桥。本篇重点介绍PCI桥,而不关心其他桥设备的实现原理。PCI桥的存在使PCI总线极具扩展性,处理器系统可以使用PCI桥进一步扩展PCI总线。
PCI桥的出现使得采用PCI总线进行大规模系统互连成为可能。但是在目前已经实现的大规模处理器系统中,并没有使用PCI总线进行处理器系统与处理器系统之间的大规模互连。因为PCI总线是一个以HOST主桥为根的树型结构,使用主从架构,因而不易实现多处理器系统间的对等互连。
即便如此PCI桥仍然是PCI总线规范的精华所在,掌握PCI桥是深入理解PCI体系结构的基础。PCI桥可以连接两条PCI总线,上游PCI总线和下游PCI总线,这两个PCI总线属于同一个PCI总线域,使用PCI桥扩展的所有PCI总线都同属于一个PCI总线域。
其中对PCI设备配置空间的访问可以从上游总线转发到下游总线,而数据传送可以双方向进行。在PCI总线中,还存在一种非透明PCI桥,该桥片不是PCI总线规范定义的标准桥片,但是适用于某些特殊应用,本篇将在第2.5节中详细介绍这种桥片。在本书中,如不特别强调,PCI桥是指透明桥,透明桥也是PCI总线规范定义的标准桥片。
PCI-to-(E)ISA桥和PCI-to-Cardbus桥的主要作用是通过PCI总线扩展(E)ISA和Cardbus总线。在PCI总线推出之后,(E)ISA总线并没有在处理器系统中立即消失,此时需要使用PCI-(E)ISA桥扩展(E)ISA总线,而使用PCI-to-Cardbus桥用来扩展Cardbus总线,本篇并不关心(E)ISA和Cardbus总线的设计与实现。
PCI总线规定在同一时刻内,在一颗PCI总线树上有且只有一个HOST处理器。这个HOST处理器可以通过HOST主桥,发起PCI总线的配置请求总线事务,并对PCI总线上的设备和桥片进行配置。
在PCI总线中,HOST处理器是一个较为模糊的概念。在SMP(symmetric multiprocessing)处理器系统中,所有CPU都可以通过HOST主桥访问其下的PCI总线树,这些CPU都可以作为HOST处理器。但是值得注意的是,HOST主桥才是PCI总线树的实际管理者,而不是HOST处理器。
在HOST主桥中,设置了许多寄存器,HOST处理器通过操作这些寄存器管理这些PCI设备。如在x86处理器的HOST主桥中设置了0xCF8和0xCFC这两个I/O端口访问PCI设备的配置空间,而PowerPC处理器的HOST主桥设置了CFG_ADDR和CFG_DATA寄存器访问PCI设备的配置空间。值得注意的是,在PowerPC处理器中并没有I/O端口,因此使用存储器映像寻址方式访问外部设备的寄存器空间。
总线的负载
PCI总线的所能挂接的负载与总线频率相关,其中总线频率越高,所能挂接的负载越少。下文以
PCI总线和PCI-X总线为例说明总线频率、峰值带宽和负载能力之间的关系,如表1?1所示。
&1?1 PCI总线频率、带宽与负载之间的关系
由表1?1所示,PCI总线频率越高,所能挂接的负载越少,但是整条总线所能提供的带宽越大。值得注意的是,PCI-X总线与PCI总线的传送协议略有不同,因此66MHz的PCI-X总线的负载数较大,PCI-X总线的详细说明见第1.5节。当PCI-X总线频率为266MHz和533MHz时,该总线只能挂接一个PCI-X插槽。在PCI总线中,一个插槽相当于两个负载,接插件和插卡各算为一个负载,在表1?1中,33MHz的PCI总线可以挂接4~5个插槽,相当于直接挂接8~10个负载。1.2&PCI总线的信号定义
PCI总线是一条共享总线,在一条PCI总线上可以挂接多个PCI设备。这些PCI设备通过一系列信号与PCI总线相连,这些信号由地址/数据信号、控制信号、仲裁信号、中断信号等多种信号组成。
PCI总线是一个同步总线,每一个设备都具有一个CLK信号,其发送设备与接收设备使用这个CLK信号进行同步数据传递。PCI总线可以使用33MHz或者66MHz的时钟频率,而PCI-X总线可以使用133MHz、266MHz或者533MHz的时钟频率。
除了RST#、INTA~D#、PME#和CLKRUN#等信号之外,PCI设备使用的绝大多数信号需要与CLK信号同步。其中RST#是复位信号,PCI设备使用INTA~D#信号进行中断请求。本篇并不关心PME#和CLKRUN#信号。
在PCI总线中,与地址和数据相关的信号如下所示。
AD[31:0]信号
PCI总线复用地址与数据信号。PCI总线事务在启动后的第一个时钟周期传送地址,这个地址是PCI总线域的存储器地址或者I/O地址;而在下一个时钟周期传送数据。传送地址的时钟周期也被称为地址周期,而传送数据的时钟周期也被称为数据周期。PCI总线支持突发传送,即在一个地址周期之后,可以紧跟多个数据周期。
PCI总线使用奇偶校验机制,保证地址和数据信号在进行数据传递时的正确性。PAR信号是AD[31:0]和C/BE[3:0]的奇偶校验信号。PCI主设备在地址周期和数据周期中,使用该信号为地址和数据信号线提供奇偶校验位。
C/BE[3:0]#信号
PCI总线复用命令与字节选通引脚。在地址周期中,C/BE[3:0]信号表示PCI总线的命令。而在数据周期,C/BE[3:0]引脚输出字节选通信号,其中C/BE3、C/BE2、C/BE1和C/BE0与数据的字节3、2、1和0对应。使用这组信号可以对PCI设备进行单个字节、字和双字访问。PCI总线通过C/BE[3:0]#信号定义了多个总线事务,这些总线事务如表1?2所示。
1?2 PCI总线事务
C/BE[3:0]#
Acknowledge
中断响应总线事务读取当前挂接在PCI总线上的中断控制器的中断向量号。目前大多数处理器系统的中断控制器都不挂接在PCI总线上,因此这种总线事务很少被使用。
Special Cycle
HOST主桥可以使用Special Cycle事务在PCI总线上,进行信息广播。
HOST主桥可以使用该总线事务对PCI设备的I/O地址空间进行读操作。目前多数PCI设备都不支持I/O地址空间,而仅支持存储器地址空间,但是仍有部分PCI设备同时包含I/O地址空间和存储器地址空间。
对PCI总线的I/O地址空间进行写操作。
Memory Read
HOST主桥可以使用该总线事务对PCI设备的存储器空间进行读操作。PCI设备也可以使用该总线事务读取处理器的存储器空间。
Memory Write
HOST主桥可以使用该总线事务对PCI设备的存储器空间进行写操作。PCI设备也可以使用该总线事务向处理器的存储器空间进行写操作。
Configuration Read
HOST主桥可以对PCI设备的配置空间进行读操作。每一个PCI设备都有独立的配置空间。在多功能PCI设备中,每一个子设备(Function)也有一个独立的配置空间。该总线事务只能由HOST主桥发出,PCI桥可以转发该总线事务。
Configuration Write
HOST主桥对PCI设备的配置空间进行写操作。
Memory Read Multiple
HOST主桥可以使用该总线事务对PCI设备的存储器空间进行多行读操作,这种操作并不多见。该总线事务的主要用途是供PCI设备使用,读取主存储器。这个读操作与Memory Read操作(C/BE[3:0]为0x0110时)略有不同,详见第3.4.5节。
Dual Address Cycle
PCI总线支持64位地址,处理器或者其他PCI设备访问64位PCI总线地址时,必须使用双地址周期产生64位的PCI总线地址。PCI设备使用DMA读写方式访问64位的存储器地址时,也可以使用该总线事务。
Memory Read Line
HOST主桥可以使用该总线事务对PCI设备的存储器空间进行单行读操作,这种操作并不多见。该总线事务的主要用途是供PCI设备使用,读取主存储器。详见第3.4.5节。
Memory Write and
Invalidate
存储器写并无效操作,与存储器写不同,PCI设备可以使用该总线事务对主存储器空间进行写操作。该总线事务将数据写入主存储器的同时,将对应Cache行中的数据“使无效”,详见第3.3.4节。
在PCI总线中,接口控制信号的主要作用是保证数据的正常传递,并根据PCI主从设备的状态,暂停、终止或者正常完成当前总线事务,其主要信号如下。
FRAME#信号
该信号指示一个PCI总线事务的开始与结束。当PCI设备获得总线的使用权后,将置该信号有效,即置为低,启动PCI总线事务,当结束总线事务时,将置该信号无效,即置为高。PCI设备(HOST主桥)只有通过仲裁获得当前PCI总线的使用权后,才能驱动该信号。
该信号由PCI主设备(包括HOST主桥)驱动,该信号有效时表示PCI主设备的数据已经准备完毕。如果当前PCI总线事务为写事务,表示数据已经在AD[31:0]上有效;如果为读事务,表示PCI目标设备已经准备好接收缓冲,目标设备可以将数据发送到AD[31:0]上。
该信号由目标设备驱动,该信号有效时表示目标设备已经将数据准备完毕。如果当前PCI总线事务为写事务,表示目标设备已经准备好接收缓冲,可以将AD[31:0]上的数据写入目标设备;如果为读事务,表示PCI设备需要的数据已经在AD[31:0]上有效。
该信号可以和IRDY#信号联合使用,在PCI总线事务上插入等待周期,对PCI总线的数据传送进行控制。
该信号有效时表示目标设备请求主设备停止当前PCI总线事务。一个PCI总线事务除了可以正常结束外,目标设备还可以使用该信号终止当前PCI总线事务。目标设备可以根据不同的情况,要求主设备对当前PCI总线事务进行重试(Retry)、断连(Disconnect),也可以向主设备报告目标设备夭折(Target Abort)。
目标设备要求主设备Retry和Disconnect并不意味着当前PCI总线事务出现错误。当目标设备没有将数据准备好时,可以使用Retry周期使主设备重试当前PCI总线事务。有时目标设备不能接收来自主设备较长的Burst操作时,可以使用Disconnect周期,将一个较长的Burst操作,分解为多个Burst操作。当主设备访问的地址越界时,目标设备可以使用Disconnect周期,终止主设备的越界访问。
而Target Abort表示在数据传送中出现错误。处理器系统必须要对这种情况进行处理。在PCI总线中,出现Abort一般意味着当前PCI总线域出现了较为严重的错误。
PCI总线在进行配置读写总线事务时,使用该信号选择PCI目标设备。配置读写总线事务与存储器读写总线事务在实现上略有不同。在PCI总线中,存储器读写总线事务使用地址译码方式访问外部设备。而配置读写总线事务使用“ID译码方式”访问PCI设备,即通过PCI设备的总线号、设备号和寄存器号访问PCI设备的配置空间。
IDSEL信号与PCI设备的设备号相关,相当于PCI设备配置空间的片选信号,这部分内容将在第2.4.4节中详细介绍。
DEVSEL#信号
该信号有效时表示PCI总线的目标设备准备好,该信号与TRDY#信号不同之处在于该信号有效仅表示目标设备已经完成了地址译码。目标设备使用该信号通知PCI主设备,其访问对象在当前PCI总线上,但是并不表示目标设备可以与主设备进行数据交换。而TRDY#信号表示数据有效,PCI主设备可以向目标设备写入或者从目标设备读取数据。
PCI总线规范根据设备进行译码速度的快慢,将PCI设备分为快速、中速和慢速三种设备。在PCI总线上还有一种特殊的设备,即负向译码设备,在一条PCI总线上当快速、中速和慢速三种设备都不能响应PCI总线事务的地址时,负向译码设备将被动地接收这个PCI总线事务。如果在PCI主设备访问的PCI总线上,没有任何设备可以置DEVSEL#信号为有效,主设备将使用Master Abort周期结束当前总线事务。
PCI主设备可以使用该信号,将目标设备的某个存储器或者I/O资源锁定,以禁止其他PCI主设备访问此资源,直到锁定这个资源的主设备将其释放。PCI总线使用LOCK#信号实现LOCK总线事务,只有HOST主桥、PCI桥或者其他桥片可以使用LOCK#信号。在PCI总线的早期版本中,PCI Agent设备也可以使用LOCK#信号,而目前PCI总线使用LOCK#信号仅是为防止死锁和向前兼容。LOCK总线事务将严重影响PCI总线的传送效率,在实际应用中,设计者应当尽量避免使用该总线事务。
PCI设备使用该组信号进行总线仲裁,并获得PCI总线的使用权。只有PCI主设备需要使用该组信号,而PCI从设备可以不使用总线仲裁信号。这组信号由REQ#和GNT#组成。其中PCI主设备的REQ#和GNT#信号与PCI总线的仲裁器直接相连。
PCI主设备的总线仲裁信号与PCI总线仲裁器的连接关系如图1?2所示。值得注意的是,每一个PCI主设备都具有独立的总线仲裁信号,并与PCI总线仲裁器一一相连。而总线仲裁器需要保证在同一个时间段内,只有一个PCI设备可以使用当前总线。
在一个处理器系统中,一条PCI总线可以挂接PCI主设备的数目,除了与负载能力相关之外,还与PCI总线仲裁器能够提供的仲裁信号数目直接相关。
在一颗PCI总线树中,每一条PCI总线上都有一个总线仲裁器。一个处理器系统可以使用PCI桥扩展出一条新的PCI总线,这条新的PCI总线也需要一个总线仲裁器,通常在PCI桥中集成了这个总线仲裁器。多数HOST主桥也集成了一个PCI总线仲裁器,但是PCI总线也可以使用独立的PCI总线仲裁器。
PCI主设备使用PCI总线进行数据传递时,需要首先置REQ#信号有效,向PCI总线仲裁器发出总线申请,当PCI总线仲裁器允许PCI主设备获得PCI总线的使用权后,将置GNT#信号为有效,并将其发送给指定的PCI主设备。而PCI主设备在获得总线使用权之后,将可以置FRAME#信号有效,与PCI从设备进行数据通信。
PCI总线提供了INTA#、INTB#、INTC#和INTD#四个中断请求信号,PCI设备借助这些中断请求信号,使用电平触发方式向处理器提交中断请求。当这些中断请求信号为低时,PCI设备将向处理器提交中断请求;当处理器执行中断服务程序清除PCI设备的中断请求后,PCI设备将该信号置高,结束当前中断请求。
PCI总线规定单功能设备只能使用INTA#信号,而多功能设备才能使用INTB#/C#/D#信号。PCI设备的这些中断请求信号可以通过某种规则进行线与,之后与中断控制器的中断请求信号线相连。而处理器系统需要预先知道这个规则,以便正确处理来自不同PCI设备的中断请求,这个规则也被称为中断路由表,有关中断路由表的详细描述见第1.4.2节。
PCI总线在进行数据传递过程时,难免会出现各种各样的错误,因此PCI总线提供了一些错误信号,如PERR#和SERR#信号。其中当PERR#信号有效时,表示数据传送过程中出现奇偶校验错(Special Cycle周期除外);而当SERR#信号有效时,表示当前处理器系统出现了三种错误可能,分别为地址奇偶校验错,在Special Cycle周期中出现数据奇偶校验错,或者系统出现其他严重错误。
如果总线支持位模式,还需要提供、、、和这些信号。此外总线还有一些与、以及使能等信号,本章并不关心这些信号。
双地址周期在第一、二个时钟周期,都传送地址。
INTx#这组信号为开漏输出,当所有的驱动源不驱动该信号时,该信号由上拉电阻驱动为高。1.3&PCI总线的存储器读写总线事务
总线的基本任务是实现数据传送,将一组数据从一个设备传送到另一个设备,当然总线也可以将一个设备的数据广播到多个设备。在处理器系统中,这些数据传送都要依赖一定的规则,PCI总线并不例外。
PCI总线使用单端并行数据线,采用地址译码方式进行数据传递,而采用ID译码方式进行配置信息的传递。其中地址译码方式使用地址信号,而ID译码方式使用PCI设备的ID号,包括Bus Number、Device Number、Function Number和Register Number。下文将以图1?1中的处理器系统为例,简要介绍PCI总线支持的总线事务及其传送方式。
如表1?2所示,PCI总线支持多种总线事务。而本节重点介绍存储器读写总线事务,I/O读写总线事务,并在第2.4节详细介绍配置读写总线事务。值得注意的是,PCI设备只有在系统软件初始化配置空间之后,才能够被其他主设备访问。
当PCI设备的配置空间被初始化之后,该设备在当前的PCI总线树上将拥有一个独立的PCI总线地址空间,即BAR((Base Address Register)寄存器所描述的空间,有关BAR寄存器的详细说明见第2.3.2节。
处理器与PCI设备进行数据交换,或者PCI设备之间进行存储器数据交换时,都将通过PCI总线地址完成。而PCI设备与主存储器进行DMA操作时,使用的也是PCI总线域的地址,而不是存储器域的地址,此时HOST主桥将完成PCI总线地址到存储器域地址的转换,不同的HOST主桥进行地址转换时使用的方法并不相同。
PCI总线的配置读写总线事务与HOST主桥与PCI桥相关,因此读者需要了解HOST主桥和PCI桥的详细实现机制之后,才能深入理解这部分内容。本篇将在第2.4节详细介绍这些内容。在下文中,我们假定所使用的PCI设备的配置空间已经被系统软件初始化。
PCI总线支持以下几类存储器读写总线事务。
HOST处理器对PCI设备的BAR空间进行数据读写,BAR空间可以使用存储器或者I/O译码方式。HOST处理器使用PCI总线的存储器读写总线事务和I/O读写总线事务访问PCI设备的BAR空间。
PCI设备之间的数据传递。在PCI总线上的两个设备可以直接通信,如一个PCI设备可以访问另外一个设备的BAR空间。不过这种数据传递在PC处理器系统中,较少使用。
PCI设备对主存储器进行读写,即DMA读写操作。DMA读写操作在所有处理器系统中都较为常用,也是PCI总线数据传送的重点所在。在多数情况下,DMA读写操作结束后将伴随着中断的产生。PCI设备可以使用INTA#、INTB#、INTC#和INTD#信号提交中断请求,也可以使用MSI机制提交中断请求。
总线事务的时序
PCI总线使用第1.2节所述的信号进行数据和配置信息的传递,一个PCI总线事务的基本访问时序如图1?3所示,与PCI总线事务相关的控制信号有FRAME#、IRDY#、TRDY#、DEVSEL#等其他信号。
当一个PCI主设备需要使用PCI总线时,需要首先发送REQ#信号,通过总线仲裁获得总线使用权,即GNT#信号有效后,使用以下步骤完成一个完整PCI总线事务,对目标设备进行存储器或者I/O地址空间的读写访问。
当PCI主设备获得总线使用权之后,将在CLK1的上升沿置FRAME#信号有效,启动PCI总线事务。当PCI总线事务结束后,FRAME#信号将被置为无效。
PCI总线周期的第一个时钟周期(CLK1的上升沿到CLK2的上升沿之间)为地址周期。在地址周期中,PCI主设备将访问的目的地址和总线命令分别驱动到AD[31:0]和C/BE#信号上。如果当前总线命令是配置读写,那么IDSEL信号线也被置为有效,IDSEL信号与PCI总线的AD[31:11]相连,详见第2.4.4节。
当IRDY#、TRDY#和DEVSEL#信号都有效后,总线事务将使用数据周期,进行数据传递。当IRDY#和TRDY#信号没有同时有效时,PCI总线不能进行数据传递,PCI总线使用这两个信号进行传送控制。
PCI总线支持突发周期,因此在地址周期之后可以有多个数据周期,可以传送多组数据。而目标设备并不知道突发周期的长度,如果目标设备不能继续接收数据时,可以disconnect当前总线事务。值得注意的是,只有存储器读写总线事务可以使用突发周期。
一个完整的PCI总线事务远比上述过程复杂的多,因为PCI总线还支持许多传送方式,如双地址周期、fast back-to-back(快速背靠背)、插入等待状态、重试和断连、总线上的错误处理等一系列总线事务。本篇不一一介绍这些传送方式。
和Non-Posted传送方式
PCI总线规定了两类数据传送方式,分别是Posted和Non-Posted数据传送方式。其中使用Posted数据传送方式的总线事务也被称为Posted总线事务;而使用Non-Posted数据传送方式的总线事务也被称为Non-Posted总线事务。
其中Posted总线事务指PCI主设备向PCI目标设备进行数据传递时,当数据到达PCI桥后,即由PCI桥接管来自上游总线的总线事务,并将其转发到下游总线。采用这种数据传送方式,在数据还没有到达最终的目的地之前,PCI总线就可以结束当前总线事务,从而在一定程度上解决了PCI总线的拥塞。
而Non-Posted总线事务是指PCI主设备向PCI目标设备进行数据传递时,数据必须到达最终目的地之后,才能结束当前总线事务的一种数据传递方式。
显然采用Posted传送方式,当这个Posted总线事务通过某条PCI总线后,就可以释放PCI总线的资源;而采用Non-Posted传送方式,PCI总线在没有结束当前总线事务时必须等待。这种等待将严重阻塞当前PCI总线上的其他数据传送,因此PCI总线使用Delayed总线事务处理Non-Posted数据请求,使用Delayed总线事务可以相对缓解PCI总线的拥塞。Delayed总线事务的详细介绍见第1.3.5节。
PCI总线规定只有存储器写请求(包括存储器写并无效请求)可以采用Posted总线事务,下文将Posted存储器写请求简称为PMW(Posted Memory Write),而存储器读请求、I/O读写请求、配置读写请求只能采用Non-Posted总线事务。
下文以图1?1的处理器系统中的PCI设备11向存储器进行DMA写操作为例,说明Posted传送方式的实现过程。PCI设备11进行DMA写操作时使用存储器写总线事务,当PCI设备11获得PCI总线x1的使用权后,将发送存储器写总线事务到PCI总线x1。当PCI桥1发现这个总线事务的地址不在该桥管理的地址范围内将首先接收这个总线事务,并结束PCI总线x1的总线事务。
此时PCI总线x1使用的资源已被释放,PCI设备11和PCI设备12可以使用PCI总线x1进行通信。PCI桥1获得PCI总线x0的使用权后,将转发这个存储器写总线事务到PCI总线x0,之后HOST主桥x将接收这个存储器写总线事务,并最终将数据写入主存储器。
由以上过程可以发现,Posted数据请求在通过PCI总线之后,将逐级释放总线资源,因此PCI总线的利用率较高。而使用Non-Posted方式进行数据传送的处理过程与此不同,Non-Posted数据请求在通过PCI总线时,并不会及时释放总线资源,从而在某种程度上影响PCI总线的使用效率和传送带宽。
处理器访问PCI设备
HOST处理器对PCI设备的数据访问主要包含两方面内容,一方面是处理器向PCI设备发起存储器和I/O读写请求;另一方面是处理器对PCI设备进行配置读写。
在PCI设备的配置空间中,共有6个BAR寄存器。每一个BAR寄存器都与PCI设备使用的一组PCI总线地址空间对应,BAR寄存器记录这组地址空间的基地址。本书将与BAR寄存器对应的PCI总线地址空间称为BAR空间,在BAR空间中可以存放I/O地址空间,也可以存放存储器地址空间。
PCI设备可以根据需要,有选择地使用这些BAR空间。值得注意的是,在BAR寄存器中存放的是PCI设备使用的“PCI总线域”的物理地址,而不是“存储器域”的物理地址,有关BAR寄存器的详细介绍见第2.3.2节。
HOST处理器访问PCI设备I/O地址空间的过程,与访问存储器地址空间略有不同。有些处理器,如x86处理器,具有独立的I/O地址空间。x86处理器可以将PCI设备使用的I/O地址映射到存储器域的I/O地址空间中,之后处理器可以使用IN,OUT等指令对存储器域的I/O地址进行访问,然后通过HOST主桥将存储器域的I/O地址转换为PCI总线域的I/O地址,最后使用PCI总线的I/O总线事务对PCI设备的I/O地址进行读写访问。在x86处理器中,存储器域的I/O地址与PCI总线域的I/O地址相同。
对于有些没有独立I/O地址空间的处理器,如PowerPC处理器,需要在HOST主桥初始化时,将PCI设备使用的I/O地址空间映射为处理器的存储器地址空间。PowerPC处理器对这段“存储器域”的存储器空间进行读写访问时,HOST主桥将存储器域的这段存储器地址转换为PCI总线域的I/O地址,然后通过PCI总线的I/O总线事务对PCI设备的I/O地址进行读写操作。
在PCI总线中,存储器读写事务与I/O读写事务的实现较为类似。首先HOST处理器在初始化时,需要将PCI设备使用的BAR空间映射到“存储器域”的存储器地址空间。之后处理器通过存储器读写指令访问“存储器域”的存储器地址空间,HOST主桥将“存储器域”的读写请求翻译为PCI总线的存储器读写总线事务之后,再发送给目标设备。
值得注意的是,存储器域和PCI总线域的概念,PCI设备能够直接使用的地址为PCI总线域的地址,在PCI总线事务中出现的地址也为PCI总线域的地址;而处理器能够直接使用的地址为存储器域的地址。理解存储器域与PCI总线域的区别对于理解PCI总线至关重要,本篇将在第2.1节专门讨论这两个概念。
以上对PCI总线的存储器与I/O总线事务的介绍并没有考虑PCI桥的存在,如果将PCI桥考虑进来,情况将略微复杂一些。下文将以图1?1为例说明处理器如何通过HOST主桥和PCI桥1对PCI设备11进行存储器读写操作。当处理器对PCI设备11进行存储器写操作时,这些数据需要通过HOST主桥x和PCI桥x1,最终到达PCI设备11,其访问步骤如下。值得注意的是,以下步骤忽略PCI总线的仲裁过程。
首先处理器将要传递的数据放入通用寄存器中,之后向PCI设备11映射到的存储器域的地址进行写操作。值得注意的是,处理器并不能直接访问PCI设备11的PCI总线地址空间,因为这些地址空间是属于PCI总线域的,处理器所能直接访问的空间是存储器域的地址空间。处理器必须通过HOST主桥将存储器域的数据访问转换为PCI总线事务才能对PCI总线地址空间进行访问。
HOST主桥x接收来自处理器的存储器写请求,之后处理器结束当前存储器写操作,释放系统总线。HOST主桥x将存储器域的存储器地址转换为PCI总线域的PCI总线地址。并向PCI总线x0发起PCI写请求总线事务。值得注意的是,虽然在许多处理器系统中,存储器地址和PCI总线地址完全相等,但其含义完全不同。
PCI总线x0上的PCI设备01、PCI设备02和PCI桥1将同时监听这个PCI写总线事务。最后PCI桥x1接收这个写总线事务,并结束来自PCI总线x0的PCI总线事务。之后PCI桥x1向PCI总线x1发起新的PCI总线写总线事务。
PCI总线x1上的PCI设备11和PCI设备12同时监听这个PCI写总线事务。最后PCI设备11通过地址译码方式接收这个写总线事务,并结束来自PCI总线x1上的PCI总线事务。
由以上过程可以发现,由于存储器写总线事务使用Posted传送方式,因此数据通过PCI桥后都将结束上一级总线的PCI总线事务,从而上一级PCI总线可以被其他PCI设备使用。如果使用Non-Posted传送方式,直到数据发送到PCI设备11之后,PCI总线x1和x0才能依次释放,从而在某种程度上将造成PCI总线的拥塞。
处理器对PCI设备11进行I/O写操作时只能采用Non-Posted方式进行,与Posted方式相比,使用Non-Posted方式,当数据到达目标设备后,目标设备需要向主设备发出“回应”,当主设备收到这个“回应”后才能结束整个总线事务。本节不再讲述处理器如何对PCI设备进行I/O写操作,请读者思考这个过程。
处理器对PCI设备11进行存储器读时,这个读请求需要首先通过HOST主桥x和PCI桥x1到达PCI设备,之后PCI设备将读取的数据再次通过PCI桥x1和HOST主桥x传递给HOST处理器,其步骤如下所示。我们首先假设PCI总线没有使用Delayed传送方式处理Non-Posted总线事务,而是使用纯粹的Non-Posted方式。
首先处理器准备接收数据使用的通用寄存器,之后向PCI设备11映射到的存储器域的地址进行读操作,
HOST主桥x接收来自处理器的存储器读请求。HOST主桥x进行存储器地址到PCI总线地址的转换,之后向PCI总线x0发起存储器读总线事务。
PCI总线x0上的PCI设备01、PCI设备02和PCI桥x1将监听这个存储器读请求,之后PCI桥1接收这个存储器读请求。然后PCI桥x1向PCI总线x1发起新的PCI总线读请求。
PCI总线x1上的PCI设备11和PCI设备12监听这个PCI读请求总线事务。最后PCI设备11接收这个存储器读请求总线事务,并将这个读请求总线事务转换为存储器读完成总线事务之后,将数据传送到PCI桥x1,并结束来自PCI总线x1上的PCI总线事务。
PCI桥x1将接收到的数据通过PCI总线x0,继续上传到HOST主桥x,并结束PCI总线x0上的PCI总线事务。
HOST主桥x将数据传递给处理器,最终结束处理器的存储器读操作。
显然这种方式与Posted传送方式相比,PCI总线的利用率较低。因为只要HOST处理器没有收到来自目标设备的“回应”,那么HOST处理器到目标设备的传送路径上使用的所有PCI总线都将被阻塞。因而PCI总线x0和x1并没有被充分利用。
由以上例子,我们可以发现只有“读完成”依次通过PCI总线x1和x0之后,存储器读总线事务才不继续占用PCI总线x1和x0的资源,显然这种数据传送方式并不合理。因此PCI总线使用Delayed传送方式解决这个总线拥塞问题,有关Delayed传送方式的实现机制见第1.3.5节。
设备读写主存储器
PCI设备与存储器直接进行数据交换的过程也被称为DMA。与其他总线的DMA过程类似,PCI设备进行DMA操作时,需要获得数据传送的目的地址和传送大小。支持DMA传递的PCI设备可以在其BAR空间中设置两个寄存器,分别保存这个目标地址和传送大小。这两个寄存器也是PCI设备DMA控制器的组成部件。
值得注意的是,PCI设备进行DMA操作时,使用的目的地址是PCI总线域的物理地址,而不是存储器域的物理地址,因为PCI设备并不能识别存储器域的物理地址,而仅能识别PCI总线域的物理地址。
HOST主桥负责完成PCI总线地址到存储器域地址的转换。HOST主桥需要进行合理设置,将存储器的地址空间映射到PCI总线之后,PCI设备才能对这段存储器空间进行DMA操作。PCI设备不能直接访问没有经过主桥映射的存储器空间。
许多处理器允许PCI设备访问所有存储器域地址空间,但是有些处理器可以设置PCI设备所能访问的存储器域地址空间,从而对存储器域地址空间进行保护。例如PowerPC处理器的HOST主桥可以使用Inbound寄存器组,设置PCI设备访问的存储器地址范围和属性,只有在Inbound寄存器组映射的存储器空间才能被PCI设备访问,本篇将在第2.2节详细介绍PowerPC处理器的这组寄存器。
由上所述,在一个处理器系统中,并不是所有存储器空间都可以被PCI设备访问,只有在PCI总线域中有映像的存储器空间才能被PCI设备访问。经过HOST主桥映射的存储器,具有两个“地址”,一个是在存储器域的地址,一个是在PCI总线域的PCI总线地址。当处理器访问这段存储器空间时,使用存储器地址;而PCI设备访问这段内存时,使用PCI总线地址。在多数处理器系统中,存储器地址与PCI总线地址相同,但是系统程序员需要正确理解这两个地址的区别。
下文以PCI设备11向主存储器写数据为例,说明PCI设备如何进行DMA写操作。
首先PCI设备11将存储器写请求发向PCI总线x1,注意这个写请求使用的地址是PCI总线域的地址。
PCI总线x1上的所有设备监听这个请求,因为PCI设备11是向处理器的存储器写数据,所以PCI总线x1上的PCI
Agent设备都不会接收这个数据请求。
PCI桥x1发现当前总线事务使用的PCI总线地址不是其下游设备使用的PCI总线地址,则接收这个数据请求,有关PCI桥的Secondary总线接收数据的过程见第3.2.1节。此时PCI桥x1将结束来自PCI设备11的Posted存储器写请求,并将这个数据请求推到上游PCI总线上,即PCI总线x0上。
PCI总线x0上的所有PCI设备包括HOST主桥将监听这个请求。PCI总线x0上的PCI
Agent设备也不会接收这个数据请求,此时这个数据请求将由HOST主桥x接收,并结束PCI桥x1的Posted存储器写请求。
HOST主桥x发现这个数据请求发向存储器,则将来自PCI总线x0的PCI总线地址转换为存储器地址,之后通过存储器控制器将数据写入存储器,完成PCI设备的DMA写操作。
PCI设备进行DMA读过程与DMA写过程较为类似。不过PCI总线的存储器读总线事务只能使用Non-Posted总线事务,其过程如下。
首先PCI设备11将存储器读请求发向PCI总线x1。
PCI总线x1上的所有设备监听这个请求,因为PCI设备11是从存储器中读取数据,所以PCI总线x1上的设备,如PCI设备12,不会接收这个数据请求。PCI桥x1发现下游PCI总线没有设备接收这个数据请求,则接收这个数据请求,并将这个数据请求推到上游PCI总线上,即PCI总线x0上。
PCI总线x0上的设备将监听这个请求。PCI总线x0上的设备也不会接收这个数据请求,最后这个数据请求将由HOST主桥x接收。
HOST主桥x发现这个数据请求是发向主存储器,则将来自PCI总线x0的PCI总线地址转换为存储器地址,之后通过存储器控制器将数据读出,并转发到HOST主桥x。
HOST主桥x将数据经由PCI桥x1传递到PCI设备11,PCI设备11接收到这个数据后结束DMA读。
以上过程仅是PCI设备向存储器读写数据的一个简单流程。如果考虑处理器中的Cache,这些存储器读写过程较为复杂。
PCI总线还允许PCI设备之间进行数据传递,PCI设备间的数据交换较为简单。在实际应用中,PCI设备间的数据交换并不常见。下文以图1?1为例,简要介绍PCI设备11将数据写入PCI设备01的过程;请读者自行考虑PCI设备11从PCI设备01读取数据的过程。
首先PCI设备11将PCI写总线事务发向PCI总线x1上。PCI桥x1和PCI设备12同时监听这个写总线事务。
PCI桥x1将接收这个PCI写请求总线事务,并将这个PCI写总线事务上推到PCI总线x0。
PCI总线x0上的所有设备将监听这个PCI写总线事务,最后由PCI设备01接收这个数据请求,并完成PCI写事务。
如上文所述,如果处理器使用Non-Posted总线周期对PCI设备进行读操作,或者PCI设备使用Non-Posted总线事务对存储器进行读操作时,如果数据没有到达目的地,那么在这个读操作路径上的所有PCI总线都不能被释放,这将严重影响PCI总线的使用效率。
为此PCI桥需要对Non-Posted总线事务进行优化处理,并使用Delayed总线事务处理这些Non-Posted总线事务,PCI总线规定只有Non-Posted总线事务可以使用Delayed总线事务。PCI总线的Delay总线事务由Delay读写请求和Delay读写完成总线事务组成,当Delay读写请求到达目的地后,将被转换为Delay读写完成总线事务。基于Delay总线请求的数据交换如图1?4所示。
&<img title="" src="/DownloadImg/3/" name="image_operate_41266" alt="1.3&PCI总线的存储器读写总线事务">
假设处理器通过存储器读、I/O读写或者配置读写访问PCI设备22时,首先经过HOST主桥进行存储器域与PCI总线域的地址转换,并由HOST主桥发起PCI总线事务,然后通过PCI桥1、2,最终到达PCI设备22。其详细步骤如下。
HOST主桥完成存储器域到PCI总线域的转换,然后启动PCI读总线事务。
PCI桥1接收这个读总线事务,并首先使用Retry周期,使HOST主桥择时重新发起相同的总线周期。此时PCI桥1的上游PCI总线将被释放。值得注意的是PCI桥并不会每一次都使用Retry周期,使上游设备择时进行重试操作。在PCI总线中,有一个“16 Clock”原则,即FRAME#信号有效后,必须在16个时钟周期内置为无效,如果PCI桥发现来自上游设备的读总线事务不能在16个时钟周期内结束时,则使用Retry周期终止该总线事务。
PCI桥1使用Delayed总线请求继续访问PCI设备22。
PCI桥2接收这个总线请求,并将这个Delayed总线请求继续传递。此时PCI桥2也将首先使用Retry周期,使PCI桥1择时重新发起相同的总线周期。此时PCI桥2的上游PCI总线被释放。
这个数据请求最终到达PCI设备22,如果PCI设备22没有将数据准备好时,也可以使用Retry周期,使PCI桥2择时重新发起相同的总线周期;如果数据已经准备好,PCI设备22将接收这个数据请求,并将这个Delayed总线请求转换为Delayed总线完成事务。如果Delayed总线请求是读请求,则Delayed总线完成事务中含有数据,否则只有完成信息,而不包含数据。
Delayed总线完成事务将“数据或者完成信息”传递给PCI桥2,当PCI桥1重新发出Non-Posted总线请求时,PCI桥2将这个“数据或者完成信息”传递给PCI桥1。
HOST主桥重新发出存储器读总线事务时,PCI桥1将“数据或者完成信息”传递给HOST主桥,最终完成整个PCI总线事务。
由以上分析可知,Delayed总线周期由Delayed总线请求和Delayed总线完成两部分组成。下文将Delayed读请求总线事务简称为DRR(Delayed Read Request),Delayed读完成总线事务简称为DRC(Delayed Read Completion);而将Delayed写请求总线事务简称为DWR(Delayed Write Request),Delayed写完成总线事务简称为DWC(Delayed Write Completion)。
PCI总线使用Delayed总线事务,在一定程度上可以提高PCI总线的利用率。因为在进行Non-Posted总线事务时,Non-Posted请求在通过PCI桥之后,可以暂时释放PCI总线,但是采用这种方式,HOST/PCI桥将会择时进行重试操作。在许多情况下,使用Delayed总线事务,并不能取得理想的效果,因为过多的重试周期也将大量消耗PCI总线的带宽。
为了进一步提高Non-Posted总线事务的执行效率,PCI-X总线将PCI总线使用的Delayed总线事务,升级为Split总线事务。采用Split总线事务可以有效解决HOST/PCI桥的这些重试操作。Split总线事务的基本思想是发送端首先将Non-Posted总线请求发送给接收端,然后再由接收端主动地将数据传递给发送端。
除了PCI-X总线可以使用Split总线事务进行数据传送之外,有些处理器,如x86和PowerPC处理器的FSB(Front Side Bus)总线也支持这种Split总线事务,因此这些HOST主桥也可以发起这种Split总线事务。在PCIe总线中,Non-Posted数据传送都使用Split总线事务完成,而不再使用Delayed总线事务。本章将在第1.5.1节简要介绍Split总线事务和PCI-X总线对PCI总线的一些功能上的增强。
如果是存储器、I/O读或者配置读总线事务,这个回应包含数据;如果是I/O写或者配置写,这个回应不包含数据。
1.4&PCI总线的中断机制
PCI总线使用INTA#、INTB#、INTC#和INTD#信号向处理器发出中断请求。这些中断请求信号为低电平有效,并与处理器的中断控制器连接。在PCI体系结构中,这些中断信号属于边带信号(Sideband Signals),PCI总线规范并没有明确规定在一个处理器系统中如何使用这些信号,因为这些信号对于PCI总线是可选信号。PCI设备还可以使用MSI机制向处理器提交中断请求,而不使用这组中断信号。有关MSI机制的详细说明见第8章。
不同的处理器使用的中断控制器不同,如x86处理器使用APIC(Advanced Programmable Interrupt
Controller)中断控制器,而PowerPC处理器使用MPIC(Multiprocessor Interrupt
Controller)中断控制器。这些中断控制器都提供了一些外部中断请求引脚IRQ_PINx#。外部设备,包括PCI设备可以使用这些引脚向处理器提交中断请求。
但是PCI总线规范没有规定PCI设备的INTx信号如何与中断控制器的IRQ_PINx#信号相连,这为系统软件的设计带来了一定的困难,为此系统软件使用中断路由表存放PCI设备的INTx信号与中断控制器的连接关系。在x86处理器系统中,BIOS可以提供这个中断路由表,而在PowerPC处理器中Firmware也可以提供这个中断路由表。
在一些简单的嵌入式处理器系统中,Firmware并没有提供中断路由表,此时系统软件开发者需要事先了解PCI设备的INTx信号与中断控制器的连接关系。此时外部设备与中断控制器的连接关系由硬件设计人员指定。
我们假设在一个处理器系统中,共有3个PCI插槽(分别为PCI插槽A、B和C),这些PCI插槽与中断控制器的IRQ_PINx引脚(分别为IRQW#、IRQX#、IRQY#和IRQZ#)可以按照图1?5所示的拓扑结构进行连接。
采用图1?5所示的拓扑结构时,PCI插槽A、B、C的INTA#、INTB#和INTC#信号将分散连接到中断控制器的IRQW#、IRQX#和IRQY#信号,而所有INTD#信号将共享一个IRQZ#信号。采用这种连接方式时,整个处理器系统使用的中断请求信号,其负载较为均衡。而且这种连接方式保证了每一个插槽的INTA#信号都与一根独立的IRQx#信号对应,从而提高了PCI插槽中断请求的效率。
在一个处理器系统中,多数PCI设备仅使用INTA#信号,很少使用INTB#和INTC#信号,而INTD#信号更是极少使用。在PCI总线中,PCI设备配置空间的Interrupt Pin寄存器记录该设备究竟使用哪个INTx信号,该寄存器的详细介绍见第2.3.2节。
总线的连接关系
在PCI总线中,INTx信号属于边带信号。所谓边带信号是指这些信号在PCI总线中是可选信号,而且只能在一个处理器系统的内部使用,并不能离开这个处理器环境。PCI桥也不会处理这些边带信号。这给PCI设备将中断请求发向处理器带来了一些困难,特别是给挂接在PCI桥之下的PCI设备进行中断请求带来了一些麻烦。
在一些嵌入式处理器系统中,这个问题较易解决。因为嵌入式处理器系统很清楚在当前系统中存在多少个PCI设备,这些PCI设备使用了哪些中断资源。在多数嵌入式处理器系统中,PCI设备的数量小于中断控制器提供的外部中断请求引脚数,而且在嵌入式系统中,多数PCI设备仅使用INTA#信号提交中断请求。
在这类处理器系统中,可能并不含有PCI桥,因而PCI设备的中断请求信号与中断控制器的连接关系较易确定。而在这类处理器系统中,即便存在PCI桥,来自PCI桥之下的PCI设备的中断请求也较易处理。
在多数情况下,嵌入式处理器系统使用的PCI设备仅使用INTA#信号进行中断请求,所以只要将这些INTA#信号挂接到中断控制器的独立IRQ_PIN#引脚上即可。这样每一个PCI设备都可以独占一个单独的中断引脚。
而在x86处理器系统中,这个问题需要BIOS参与来解决。在x86处理器系统中,有许多PCI插槽,处理器系统并不知道在这些插槽上将要挂接哪些PCI设备,而且也并不知道这些PCI设备到底需不需要使用所有的INTx#信号线。因此x86处理器系统必须要对各种情况进行处理。
x86处理器系统还经常使用PCI桥进行PCI总线扩展,扩展出来的PCI总线还可能挂接一些PCI插槽,这些插槽上INTx#信号仍然需要处理。PCI桥规范并没有要求桥片传递其下PCI设备的中断请求。事实上多数PCI桥也没有为下游PCI总线提供中断引脚INTx#,管理其下游总线的PCI设备。但是PCI桥规范推荐使用表1?3建立下游PCI设备的INTx信号与上游PCI总线INTx信号之间的映射关系。
1?3 PCI设备INTx#信号与PCI总线INTx#信号的映射关系
PCI设备的INTx#信号
PCI总线的INTx#信号
0, 4, 8, 12, 16, 20, 24, 28
1, 5, 9, 13, 17, 21, 25, 29
2, 6, 10, 14, 18, 22, 26, 30
3, 7, 11, 15, 19, 23, 27, 31
我们举例说明该表的含义。在PCI桥下游总线上的PCI设备,如果其设备号为0,那么这个设备的INTA#引脚将和PCI总线的INTA#引脚相连;如果其设备号为1,其INTA#引脚将和PCI总线的INTB#引脚相连;如果其设备号为2,其INTA#引脚将和PCI总线的INTC#引脚相连;如果其设备号为3,其INTA#引脚将和PCI总线的INTD#引脚相连。
在x86处理器系统中,由BIOS或者APCI表记录PCI总线的INTA~D#信号与中断控制器之间的映射关系,保存这个映射关系的数据结构也被称为中断路由表。大多数BIOS使用表1?3中的映射关系,这也是绝大多数BIOS支持的方式。如果在一个x86处理器系统中,PCI桥下游总线的PCI设备使用的中断映射关系与此不同,那么系统软件程序员需要改动BIOS中的中断路由表。
BIOS初始化代码根据中断路由表中的信息,可以将PCI设备使用的中断向量号写入到该PCI设备配置空间的Interrupt Line register寄存器中,该寄存器将在第2.3.2节中介绍。
在PCI总线中,INTx信号是一个异步信号。所谓异步是指INTx信号的传递并不与PCI总线的数据传送同步,即INTx信号的传递与PCI设备使用的CLK#信号无关。这个“异步”信号给系统软件的设计带来了一定的麻烦。
系统软件程序员需要注意“异步”这种事件,因为几乎所有“异步”事件都会带来系统的“同步”问题。以图1?1为例,当PCI设备11使用DMA写方式,将一组数据写入存储器时,该设备在最后一个数据离开PCI设备11的发送FIFO时,会认为DMA写操作已经完成。此时这个设备将通过INTx信号,通知处理器DMA写操作完成。
此时处理器(驱动程序的中断服务例程)需要注意,因为INTx信号是一个异步信号,当处理器收到INTx信号时,并不意味着PCI设备11已经将数据写入存储器中,因为PCI设备11的数据传递需要通过PCI桥1和HOST主桥,最终才能到达存储器控制器。
而INTx信号是“异步”发送给处理器的,PCI总线并不知道这个“异步”事件何时被处理。很有可能处理器已经接收到INTx信号,开始执行中断处理程序时,该PCI设备还没有完全将数据写入存储器。
因为“PCI设备向处理器提交中断请求”与“将数据写入存储器”分别使用了两个不同的路径,处理器系统无法保证哪个信息率先到达。从而在处理器系统中存在“中断同步”的问题,PCI总线提供了以下两种方法解决这个同步问题。
PCI设备保证在数据到达目的地之后,再提交中断请求。
显然这种方法不仅加大了硬件的开销,而且也不容易实现。如果PCI设备采用Posted写总线事务,PCI设备无法单纯通过硬件逻辑判断数据什么时候写入到存储器。此时为了保证数据到达目的地后,PCI设备才能提交中断请求,PCI设备需要使用“读刷新”的方法保证数据可以到达目的地,其方法如下。
PCI设备在提交中断请求之前,向DMA写的数据区域发出一个读请求,这个读请求总线事务将被PCI设备转换为读完成总线事务,当PCI设备收到这个读完成总线事务后,再向处理器提交中断请求。PCI总线的“序”机制保证这个存储器读请求,会将DMA数据最终写入存储器,有关PCI序的详细说明见第9.3节。
PCI总线规范要求HOST主桥和PCI桥必须保证这种读操作可以刷新写操作。但问题是,没有多少芯片设计者愿意提供这种机制,因为这将极大地增加他们的设计难度。除此之外,使用这种方法也将增加中断请求的延时。
中断服务例程使用“读刷新”方法。
中断服务例程在使用“PCI设备写入存储器”的这些数据之前,需要对这个PCI设备进行读操作。这个读操作也可以强制将数据最终写入存储器,实际上是将数据写到存储器控制器中。这种方法利用了PCI总线的传送序规则,这种方法与第1种方法基本相同,只是使用这种方法使用软件方式,而第1种方式使用硬件方式。第9.3节将详细介绍这个读操作如何将数据刷新到存储器中。
第2种方法也是绝大多数处理器系统采用的方法。程序员在书写中断服务例程时,往往都是先读取PCI设备的中断状态寄存器,判断中断产生原因之后,才对PCI设备写入的数据进行操作。这个读取中断状态寄存器的过程,一方面可以获得设备的中断状态,另一方面是保证DMA写的数据最终到达存储器。如果驱动程序不这样做,就可能产生数据完整性问题。产生这种数据完整性问题的原因是INTx这个异步信号。
这里也再次提醒系统程序员注意PCI总线的“异步”中断所带来的数据完整性问题。在一个操作系统中,即便中断处理程序没有首先读取PCI设备的寄存器,也多半不会出现问题,因为在操作系统中,一个PCI设备从提交中断到处理器开始执行设备的中断服务例程,所需要的时间较长,处理器系统基本上可以保证此时数据已经写入存储器。
但是如果系统程序员不这样做,这个驱动程序依然有Bug存在,尽管这个Bug因为各种机缘巧合,始终不能够暴露出来,而一旦这些Bug被暴露出来将难以定位。为此系统程序员务必要重视设计中出现的每一个实现细节,当然仅凭谨慎小心是远远不够的,因为重视细节的前提是充分理解这些细节。
PCI总线V2.2规范还定义了一种新的中断机制,即MSI中断机制。MSI中断机制采用存储器写总线事务向处理器系统提交中断请求,其实现机制是向HOST处理器指定的一个存储器地址写指定的数据。这个存储器地址一般是中断控制器规定的某段存储器地址范围,而且数据也是事先安排好的数据,通常含有中断向量号。
HOST主桥会将MSI这个特殊的存储器写总线事务进一步翻译为中断请求,提交给处理器。目前PCIe和PCI-X设备必须支持MSI中断机制,但是PCI设备并不一定都支持MSI中断机制。
目前MSI中断机制虽然在PCIe总线上已经成为主流,但是在PCI设备中并不常用。即便是支持MSI中断机制的PCI设备,在设备驱动程序的实现中也很少使用这种机制。首先PCI设备具有INTx#信号可以传递中断,而且这种中断传送方式在PCI总线中根深蒂固。其次PCI总线是一个共享总线,传递MSI中断需要占用PCI总线的带宽,需要进行总线仲裁等一系列过程,远没有使用INTx#信号线直接。
但是使用MSI中断机制可以取消PCI总线这个INTx#边带信号,可以解决使用INTx中断机制所带来的数据完整性问题。而更为重要的是,PCI设备使用MSI中断机制,向处理器系统提交中断请求的同时,还可以通知处理器系统产生该中断的原因,即通过不同中断向量号表示中断请求的来源。当处理器系统执行中断服务例程时,不需要读取PCI设备的中断状态寄存器,获得中断请求的来源,从而在一定程度上提高了中断处理的效率。本书将在第8章详细介绍MSI中断机制。1.5&PCI-X总线简介
PCI-X总线仍采用并行总线技术。PCI-X总线使用的大多数总线事务基于PCI总线,但是在实现细节上略有不同。PCI-X总线将工作频率提高到533MHz,并首先引入了PME(Power Management Event)机制。除此之外,PCI-X总线还提出了许多新的特性。
Split总线事务是PCI-X总线一个重要特性。该总线事务替代了PCI总线的Delayed数据传送方式,从而提高了Non-Posted总线事务的传送效率。下文以存储器读为例,说明PCI-X设备如何使用Split总线事务。
PCI-X总线在进行存储器读总线事务时,总线事务的发起方(Requester)使用Split总线事务与总线事务接收端(Completer)进行数据交换,其步骤如下。
Requester向Completer发起存储器读请求总线事务。
这个存储器读请求在到达Completer之前,可能会经过多级PCI-X桥。这些PCI-X桥使用Split Response周期结束当前总线事务,释放上游PCI总线。之后继续转发这个存储器读请求,直到Completer认领这个存储器读请求总线事务。
Completer认领存储器读请求总线事务后,将记录将Requester的ID号,并使用Split Response周期结束存储器读请求总线事务。
Completer准备好数据后,将重新申请总线,并使用存储器读完成总线事务主动地将数据传送给Requester。在这个完成报文中包含Requester的ID号,因为完成报文使用ID路由而不是地址路由。
这些完成报文根据ID路由方式,最终到达Requester。Requester从完成报文中接收数据并完成整个存储器读请求。
与Delayed总线事务相比,Requester获得的数据是Completer将数据完全准备好后,由Completer主动传递的,而不是通过Requester通过多次重试获得的,因此能够提高PCI-X总线的使用效率。PCI-X总线提出的Split总线事务被PCIe总线继承。
PCI-X总线改变了PCI总线使用的传送协议。目标设备可以将主设备发送的命令锁存,然后在下一个时钟周期进行译码操作。与PCI总线事务相比,PCI-X总线采用的这种方式,虽然在总线时序中多使用了一个时钟周期,但是可以有效提高PCI-X总线的运行频率。
因为主设备通过数据线将命令发送到目标设备需要一定的延时。如果PCI总线频率较高,目标设备很难在一个时钟周期内接收完毕总线命令,并同时完成译码工作。而如果目标设备能够将主设备发出的命令先进行锁存,然后在下一个时钟周期进行译码则可以有效解决这个译码时间Margin不足的问题,从而提高PCI-X总线的频率。PCI-X 1.0总线可以使用的最高总线频率为133MHz,而PCI-X 2.0总线可以使用的最高总线频率为533Mhz,远比PCI总线使用的总线频率高。
除了信号传送协议外,PCI-X总线在进行DMA读写时,可以不进行Cache共享一致性操作,而PCI总线进行DMA读写时必须进行Cache一致性操作。在某些特殊情况下,DMA读写时进行Cache共享一致性不但不能提高总线传送效率,反而会降低。第3.3节将详细讨论与Cache一致性相关的PCI总线事务。
此外PCI-X总线还支持乱序总线事务,即Relaxed Ordering,该总线事务被PCIe总线继承。对于某些应用,PCI-X设备使用Relaxed ordering方式,可以有效地提高数据传送效率。但是支持Relaxed Ordering的设备,需要较多的数据缓存和硬件逻辑处理这些乱序,这为PCI-X设备的设计带来了不小的困难。
在PCI总线中,一次突发传送的大小为2个以上的双字,一次突发传送所携带的数据越多时,突发传送的总线利用率也越高。
而PCI总线的突发传送仍然存在缺陷。在PCI总线中,数据发送端知道究竟需要发送多少字节的数据,但是接收端并不清楚到底需要接收多少数据。这种不确定性,为接收端的缓冲管理带来了较大的挑战。
为此PCI-X总线使用基于数据块的突发传送方式,发送端以ADB(Allowable Disconnect
Boundary)为单位,将数据发送给接收端,一次突发读写为一个以上的ADB。采用这种方式,接收端可以事先预知是否有足够的接收缓冲,接收来自发送端的数据,从而可以及时断连当前总线周期,以节约PCI-X总线的带宽。在PCI-X总线中,ADB的大小为128B。
由于ADB的引入,PCI总线与Cache相关的总线事务如Memory Read Line、Memory Read Multiline和Memory Write and Invalidate,都被PCI-X总线使用与ADB相关的总线事务替代。因为通过ADB,PCI-X桥(HOST主桥)可以准确地预知即将访问的数据在Cache中的分布情况。
PCI-X总线还增加了一些其他特性,如在总线事务中增加传送字节计数,限制等待状态等机制,并增强了奇偶校验的管理方式。但是PCI-X总线还没有普及,就被PCIe总线替代。因此在PC领域和嵌入式领域很少有基于PCI-X总线的设备,PCI-X设备仅在一些高端服务器上出现。因此本节不对PCI-X总线做进一步描述。事实上,PCI-X总线的许多特性都被PCIe总线继承。
本章主要介绍了PCI总线的基本组成部件,PCI设备如何提交中断请求,以及PCI-X总线对PCI总线的功能增强。本章的重点在于PCI总线的Posted和Non-Posted总线事务,以及PCI总线如何使用Delayed传送方式处理Non-Posted总线事务,请读者务必深入理解这两种总线事务的不同。
&PCI总线的桥与配置第2章
在PCI体系结构中,含有两类桥片,一个是HOST主桥,另一个是PCI桥。在每一个PCI设备中(包括PCI桥)都含有一个配置空间。这个配置空间由HOST主桥管理,而PCI桥可以转发来自HOST主桥的配置访问。在PCI总线中,PCI Agent设备使用的配置空间与PCI桥使用的配置空间有些差别,但这些配置空间都是由处理器通过HOST主桥管理。2.1&存储器域与PCI总线域
HOST主桥的实现因处理器系统而异。PowerPC处理器和x86处理器的HOST主桥除了集成方式不同之外,其实现机制也有较大差异。但是这些HOST主桥所完成的最基本功能依然是分离存储器域与PCI总线域,完成PCI总线域到存储器域,存储器域到PCI总线域之间的数据传递,并管理PCI设备的配置空间。
上文曾经多次提到在一个处理器系统中,存在总线域与存储器域,深入理解这两个域的区别是理解主桥的关键所在。在一个处理器系统中,存储器域、总线域与主桥的关系如图所示。
上图所示的处理器系统由一个CPU,一个DRAM控制器和两个HOST主桥组成。在这个处理器系统中,包含CPU域、DRAM域、存储器域和PCI总线域地址空间。其中HOST主桥x和HOST主桥y分别管理PCI总线x域与PCI总线y域。PCI设备访问存储器域时,也需要通过HOST主桥,并由HOST主桥进行PCI总线域到存储器域的地址转换;CPU访问PCI设备时,同样需要通过HOST主桥进行存储器域到PCI总线域的地址转换。
如果HOST主桥支持Peer-to-Peer传送机制,PCI总线x域上的设备可以与PCI总线y域上的设备直接通信,如PCI设备x11可以直接与PCI设备y11通信。为简化模型,在本书中,PCI总线仅使用32位地址空间。
域、DRAM域与存储器域
CPU域地址空间指CPU所能直接访问的地址空间集合。在本书中,CPU、处理器与处理器系统的概念不同。如MPC8548处理器的内核是E500 V2,本书将这个处理器内核称为CPU;处理器由一个或者多个CPU、外部Cache、中断控制器和DRAM控制器组成;而处理器系统由一个或者多个处理器和外部设备组成。
在CPU域中有一个重要概念,即CPU域边界,所谓CPU域边界,即CPU所能控制的数据完整性边界。CPU域的边界由Memory Fence指令的作用范围确定,CPU域边界的划分对数据完整性(Data Consistency)非常重要。与CPU域相关的数据完整性知识较为复杂,可以独立出书,因此本篇对数据完整性不做进一步介绍。笔者有计划再更新完PCIe总线部分的资料后,书体系结构的两方面内容,一个是Cache层次结构,一个是以Weakly Ordered Memory Modle为基础书写数据完整性。
严格的讲CPU域仅在CPU内核中有效,CPU访问主存储器时,首先将读写命令放入读写指令缓冲中,然后将这个命令发送到DRAM控制器或者HOST主桥。DRAM控制器或者HOST主桥将CPU地址转换为DRAM或者PCI总线地址,分别进入DRAM域或者PCI总线域后,再访问相应的地址空间。
DRAM域地址空间指DRAM控制器所能访问的地址空间集合。目前处理器系统的DRAM一般由DDR-SDRAM组成,有的书籍也将这部分内存称为主存储器。在有些处理器系统中,DRAM控制器能够访问的地址空间,并不能被处理器访问,因此在这类处理器系统中,CPU域与DRAM域地址空间并不等同。
比如有些CPU可以支持36位的物理地址,而有些DRAM控制器仅支持32位的物理地址,此时CPU域包含的地址空间大于DRAM域地址空间。但是这并不意味着DRAM域一定包含在CPU域中,在某些处理器系统中,CPU并不能访问在DRAM域中的某些数据区域。而CPU域中除了包含DRAM域外,还包含外部设备空间。
在多数处理器系统中,DRAM域空间是CPU域空间的一部分,但是也有例外。比如显卡控制器可能会借用一部分主存储器空间,这些被借用的空间不能被CPU访问,而只能被DRAM控制器,更为准确地说是显卡通过DRAM控制器访问,因此这段空间不属于CPU域,严格地讲,这段空间属于外部设备域。
本书使用存储器域统称CPU域与DRAM域。存储器域包括CPU内部的通用寄存器,存储器映像寻址的寄存器,主存储器空间和外部设备空间。在Intel的x86处理器系统中,外部设备空间与PCI总线域地址空间等效,因为在x86处理器系统中,使用PCI总线统一管理全部外部设备。为简化起见,本书使用PCI总线域替代外部设备域。
值得注意的是,存储器域的外部设备空间,在PCI总线域中还有一个地址映射。当处理器访问PCI设备时,首先访问的是这个设备在存储器域上的PCI设备空间,之后HOST主桥将这个存储器域的PCI总线地址转换为PCI总线域的物理地址,然后再通过PCI总线事务访问PCI总线域的地址空间。
在x86处理器系统中,PCI总线域是外部设备域的重要组成部分。实际上在Intel的x86处理器系统中,所有的外部设备都使用PCI总线管理。而AMD的x86处理器系统中还存在一条HT(HyperTransport)总线,在AMD的x86处理器系统中还存在HT总线域。本书对HT总线不做进一步介绍。
PCI总线域(PCI Segment)由PCI设备所能直接访问的地址空间组成。在一个处理器系统中,可能存在多个HOST主桥,因此也存在多个PCI总线域。如在图2?1所示的处理器系统中,具有两个HOST主桥,因而在这个处理器系统中存在PCI总线x和y域。
在多数处理器系统中,分属于两个PCI总线域的PCI设备并不能直接进行数据交换,而需要通过FSB进行数据交换。值得注意的是,如果某些处理器的HOST主桥支持Peer-to-Peer数据传送,那么这个HOST主桥可以支持不同PCI总线域间的数据传送。
PowerPC处理器使用了OCeaN技术连接两个HOST主桥,OCeaN可以将属于x域的PCI数据请求转发到y域,OCeaN支持PCI总线的Peer-to-Peer数据传送。有关OCeaN技术的详细说明见第2.2节。
处理器域是指一个处理器系统能够访问的地址空间集合。处理器系统能够访问的地址空间由存储器域和外部设备域组成。其中存储器域地址空间较为简单,而在不同的处理器系统中,外部设备域的组成结构并不相同。如在x86处理器系统中,外部设备域主要由PCI总线域组成,因为大多数外部设备都是挂接在PCI总线上的,而在PowerPC处理器和其他处理器系统中,有相当多的设备与FSB直接相连,而不与PCI总线相连。
本书仅介绍PCI总线域而不对其他外部设备域进行说明。其中存储器域与PCI总线域之间由HOST主桥联系在一起。深入理解这些域的关系是深入理解PCI体系结构的关键所在,实际上这也是理解处理器体系结构的基础。
通过HOST主桥,处理器系统可以将处理器域划分为存储器域与PCI总线域。其中存储器域与PCI总线域,彼此独立,并通过HOST主桥进行数据交换。HOST主桥是联系存储器域与PCI总线域的桥梁,是PCI总线域实际的管理者。
有些书籍认为HOST处理器是PCI总线域的管理者,这种说法并不精确。假设在一个SMP(symmetric
multiprocessing)处理器系统中,存在4个CPU而只有一个HOST主桥,这4个CPU将无法判断究竟谁是HOST处理器。不过究竟是哪个处理器作为HOST处理器并不重要,因为在一个处理器系统中,是HOST主桥管理PCI总线域,而不是HOST处理器。当一个处理器系统中含有多个CPU时,如果这些CPU都可以访问HOST主桥,那么这些CPU都可以作为这个HOST主桥所管理PCI总线树的HOST处理器。
在一个处理器系统中,CPU所能访问的PCI总线地址一定在存储器域中具有地址映射;而PCI设备能访问的存储器域的地址也一定在PCI总线域中具有地址映射。当CPU访问PCI域地址空间时,首先访问存储器域的地址空间,然后经过HOST主桥转换为PCI总线域的地址,再通过PCI总线事务进行数据访问。而当PCI设备访问主存储器时,首先通过PCI总线事务访问PCI总线域的地址空间,然后经过HOST主桥转换为存储器域的地址后,再对这些空间进行数据访问。
由此可见,存储器域与PCI总线域的转换关系由HOST主桥统一进行管理。有些处理器提供了一些寄存器进行这种地址映射,如PowerPC处理器使用Inbound和Outbound寄存器组保存存储器域与PCI总线域的地址映射关系;而有些处理器并没有提供这些寄存器,但是存储器域到PCI总线域的转换关系依然存在。
HOST主桥进行不同地址域间的数据交换时,需要遵循以下规则。为区别存储器域到PCI总线域的地址映射,下文将PCI总线域到存储器域的地址映射称为反向映射。
处理器访问PCI总线域地址空间时,首先需要访问存储器域的地址空间,之后通过HOST主桥将存储器地址转换为PCI总线地址,之后才能进入PCI总线域进行数据交换。PCI设备使用的地址空间保存在各自的PCI配置寄存器中,即BAR寄存器中。这些PCI总线地址空间需要在初始化时映射成为存储器域的存储器地址空间,之后处理器才能访问这些地址空间。在有些处理器的HOST主桥中,具有独立的寄存器保存这个地址映射规则,如PowerPC处理器的Outbound寄存器组;而有些处理器,如在x86处理器中,虽然没有这样的寄存器组,但是在HOST主桥的硬件逻辑中仍然存在这个地址转换的概念。
PCI设备访问存储器域时,首先需要访问PCI总线域的地址空间,之后通过HOST主桥将PCI总线地址转换为存储器地址,之后才能穿越HOST主桥进行数据交换。为此处理器需要通过HOST主桥将这个PCI总线地址反向映射为存储器地址。PCI设备不能访问在PCI总线域中没有进行这种反向映射的存储器域地址空间。PowerPC处理器使用Inbound寄存器组存放PCI设备所能访问的存储器空间,而在x86处理器中并没有这样的寄存器组,但是依然存在这个地址转换的概念。
如果HOST主桥不支持Peer-to-Peer传送方式,那么分属不同PCI总线域的PCI设备间不能直接进行数据交换。在32位的PCI总线中,每一个PCI总线域的地址范围都是0xxFFFF-FFFF,但是这些地址没有直接联系。PCI总线x域上的PCI总线地址0x与PCI总线y域上的PCI总线地址0x并不相同,而且这两个PCI总线地址经过HOST主桥反向映射后,得到的存储器地址也不相同。
本篇在第2.2节中,主要以PowerPC处理器为例说明HOST主桥的实现机制,并在第2.2.4节简要说明了x86处理器中的南北桥构架。尽管部分读者对PowerPC处理器并不感兴趣,笔者仍然强烈建议读者仔细阅读第2.2节的全部内容。
在处理器中,主桥的实现比较完整,尤其是总线域与存储器域的映射关系比较明晰,便于读者准确掌握这个重要的概念。而处理器由于考虑向前兼容,设计中包含了太多的不得已,处理器有时不得不保留原设计中的不完美,向前兼容是的重要成就,也是一个沉重的十字架。
MPC8548处理器基于E500 V2内核。目前E500内核包括V1,V2和mc(MultiCore)三个版本。
x86处理器的Memory Fence指令为MFENCE,LFENCE和SFENCE,而PowerPC处理器的Memory Fence指令为msync和mbar。
PCI总线域只含有物理地址,因此下文将直接使用PCI总线地址,而不使用PCI总线物理地址。
AMD的x86处理器中的某些外部设备,可能是基于HT总线,而不使用PCI总线。2.2&HOST主桥
本节以MPC8548处理器为例说明HOST主桥在PowerPC处理器中的实现机制,并简要介绍x86处理器系统使用的HOST主桥。
MPC8548处理器是Freescale基于E500 V2内核的一个PowerPC处理器,该处理器中集成了DDR控制器、多个eTSEC(Enhanced Three-Speed Ethernet
Controller)、PCI/PCI-X和PCIe总线控制器等一系列接口。MPC8548处理器的拓扑结构如图2?2所示。
&如上图所示,MPC8548处理器的L1 Cache在E500
V2内核中,而L2 Cache与FSB直接相连,不属于E500内核。值得注意的是有些高端PowerPC处理器的L2 Cache也在CPU中,而L3
Cache与CCB总线直接相连。
在MPC8548处理器中,所有外部设备,如以太网控制器、DDR控制器和OCeaN连接的总线控制器都与SoC平台总线直接连接。而SoC平台总线通过Cache共享一致性模块与FSB连接。
在MPC8548处理器中,具有一个32位的PCI总线控制器、一个64位的PCI/PCI-X总线控制器,还有多个PCIe总线控制器。MPC8548处理器使用OCeaN连接这些PCI、PCI-X和PCIe总线控制器。在MPC8548处理器系统中,PCI设备进行DMA操作时,首先通过OCeaN,之后经过SoC平台总线到达DDR控制器。
OCeaN是MPC8548处理器中连接快速外设使用的交叉互连总线,OCeaN不仅可以连接PCI、PCI-X和PCIe总线控制器,而且可以连接RapidIO总线控制器。使用OCeaN进行互连的总线控制器可以直接通信,而不需要通过SoC平台总线。
如来自HOST主桥1的数据报文可以通过OCeaN直接发向HOST主桥2,而不需要将数据通过SoC平台总线,再进行转发,从而减轻了SoC平台总线的负担。OCeaN部件的拓扑结构如图2?3所示。
在MPC8548处理器中,有两个HOST主桥,分别是HOST主桥1和HOST主桥2,其中HOST主桥1可以支持PCI-X总线,而HOST主桥2只能支持PCI总线。此外该处理器还含有多个PCIe总线控制器。
本节仅介绍HOST主桥,即MPC8548处理器中的PCI总线控制器,而不介绍该处理器的PCIe总线控制器。因为从软件层面上看,MPC8548处理器的PCIe总线控制器与PCI/PCI-X总线控制器功能类似。
MPC8548处理器即可以作为PCI总线的HOST处理器,也可以作为PCI总线的从设备,本节仅讲述MPC8548处理器如何作为PCI总线的HOST处理器管理PCI总线树,而并不关心MPC8548处理器作为从设备的情况。
在MPC8548处理器的HOST主桥中,定义了一系列与系统软件相关的寄存器。本节将通过介绍这些寄存器,说明这个HOST主桥的功能。为节约篇幅,本节仅介绍与HOST主桥1相关的寄存器,HOST主桥2使用的寄存器与HOST主桥1使用的寄存器类似。
2设备配置空间的访问机制
PCI总线规定访问配置空间的总线事务,即配置读写总线事务,使用ID号进行寻址。PCI设备的ID号由总线号(Bus Number)、设备号(Device Number)和功能号(Function Number)组成。
其中总线号在HOST主桥遍历PCI总线树时确定。PCI总线可以使用PCI桥扩展PCI总线,并形成一颗PCI总线树。在一颗PCI总线树上,有几个PCI桥(包括HOST主桥),就有几条PCI总线。在一颗PCI总线树中,总线号由系统软件决定,通常与HOST主桥直接相连的PCI总线编号为0,系统软件使用DFS(Depth-First Search)算法扫描PCI总线树上的所有PCI总线,并依次进行编号。
一条PCI总线的设备号由PCI设备的IDSEL信号与PCI总线地址线的连接关系确定,而功能号与PCI设备的具体设计相关。在一个PCI设备中最多有8个功能设备,而且每一个功能设备都有各自的PCI配置空间,而在绝大多数PCI设备中只有一个功能设备。HOST主桥使用寄存器号,访问PCI设备配置空间的某个寄存器。
在MPC8548处理器的HOST主桥中,与PCI设备配置空间相关的寄存器由CFG_ADDR、CFG_DATA和INT_ACK寄存器组成。系统软件使用CFG_ADDR和CFG_DATA寄存器访问PCI设备的配置空间,而使用INT_ACK寄存器访问挂接在PCI总线上的中断控制器的中断向量,这3个寄存器的地址偏移和属性如表2?1所示。
2?1 PCI总线配置寄存器
在MPC8548处理器中,所有内部寄存器都使用存储器映射方式进行寻址,并存放在以BASE_ADDR变量为起始地址的“1MB连续的物理地址空间”中。PowerPC处理器可以通过BASE_ADDR+Offset的方式访问表2?1中的寄存器。
MPC8548处理器使用CFG_ADDR寄存器和CFG_DATA寄存器访问PCI设备的配置空间,其中用CFG_ADDR寄存器保存PCI设备的ID号和寄存器号,该寄存器的各个字段的详细说明如下所示。
Enable位。当该位为1时,HOST主桥使能对PCI设备配置空间的访问,当HOST处理器对CFG_DATA寄存器进行访问时,HOST主桥将对这个寄存器的访问转换为PCI配置读写总线事务并发送到PCI总线上。Bus Number字段记录PCI设备所在的总线号。Device Number字段记录PCI设备的设备号。Function Number字段记录PCI设备的功能号。Register
Number字段记录PCI设备的配置寄存器号。
MPC8548处理器访问PCI设备的配置空间时,首先需要在CFG_ADDR寄存器中设置这个PCI设备对应的总线号、设备号、功能号和寄存器号,然后使能Enable位。之后当MPC8548处理器对CFG_DATA寄存器进行读写访问时, HOST主桥将这个存储器读写访问转换为PCI配置读写请求,并发送到PCI总线上。如果Enable位没有使能,处理器对CFG_DATA的访问不过是一个普通的I/O访问,HOST主桥并不能将其转换为PCI配置读写请求。
HOST主桥根据CFG_ADDR寄存器中的ID号,生成PCI配置读写总线事务,并将这个读写总线事务,通过ID译码方式发送到指定的PCI设备。PCI设备将接收来自配置写总线事务的数据,或者为配置读总线事务提供数据。
值得注意的是,在PowerPC处理器中,在CFG_DATA寄存器中保存的数据采用大端方式进行编址,而PCI设备的配置寄存器采用小端编址,因此HOST主桥需要进行端模式转换。我们以源代码2?1为例说明PowerPC处理器如何访问PCI配置空间。
&2?1 PowerPC处理器访问PCI配置空间
stw r0, 0(r1)
我们首先假设寄存器r1的初始值为BASE_ADDR+0x0_8000(即CFG_ADDR寄存器的地址) ,寄存器r0的初始值为0x,寄存器r2的初始值为BASE_ADDR+0x0_8004 (即CFG_DATA寄存器的地址),而指定PCI设备(总线号、设备号、功能号都为0)的配置寄存器的0x0B~0x08中的值为0x。
这段源代码的执行步骤如下。
将r0寄存器赋值到r1寄存器所指向的地址空间中,即初始化CFG_ADDR寄存器为0x。
从r2寄存器所指向的地址空间中读取数据到r3寄存器中,即从CFG_DATA寄存器中读取数据到r3寄存器。
在MPC8548处理器中,源代码2?1执行完毕后,寄存器r3保存的值为0x,而不是0x。系统程序员在使用这个返回值时,一定要注意大小端模式的转换。值得注意的是,源代码2?1可以使用lwbrx指令进行优化,该指令可以在读取数据的同时,进行大小端模式的转换。
处理器读取INT_ACK寄存器时,HOST主桥将这个读操作转换为PCI总线中断响应事务。PCI总线中断响应事务的作用是通过PCI总线读取中断控制器的中断向量号,这样做的前提是中断控制器需要连接在PCI总线上。
PowerPC处理器使用的MPIC中断控制器不是挂接在PCI总线上,而是挂接在SoC平台总线上的,因此PCI总线提供的中断应答事务在这个处理器系统中并没有太大用途。但是并不排除某些PowerPC处理器系统使用了挂接在PCI总线上的中断控制器,比如PCI南桥芯片,此时PowerPC处理器系统需要使用中断应答事务读取PCI南桥中的中断控制器,以获取中断向量号。
总线域地址空间的转换
MPC8548处理器使用ATMU (Address Translation and Mapping
Unit)寄存器组进行存储器域到PCI总线域,以及PCI总线域到存储器域的地址映射。ATMU寄存器组由两大组寄存器组成,分别为Outbound和Inbound寄存器组。其中Outbound寄存器组将存储器域的地址转换为PCI总线域的地址,而Inbound寄存器组将PCI总线域的地址转换为存储器域的地址。
在MPC8548处理器中,只有当CPU读写访问的地址范围在Outbound寄存器组管理的地址空间之内时,HOST主桥才能接收CPU的读写访问,并将CPU在存储器域上的读写访问转换为PCI总线域上的读写访问,然后才能对PCI设备进行读写操作。
如图2?2所

我要回帖

更多关于 pcie桥片 的文章

 

随机推荐