前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PCI总线的桥与配置(二)

PCI总线的桥与配置(二)

作者头像
碎碎思
发布2021-07-19 15:29:51
1.6K0
发布2021-07-19 15:29:51
举报
文章被收录于专栏:OpenFPGAOpenFPGA

PCI设备都有独立的配置空间,HOST主桥通过配置读写总线事务访问这段空间。PCI总线规定了三种类型的PCI配置空间,分别是PCI Agent设备使用的配置空间,PCI桥使用的配置空间和Cardbus桥片使用的配置空间。

本节重点介绍PCI Agent和PCI桥使用的配置空间,而并不介绍Cardbus桥片使用的配置空间。值得注意的是,在PCI设备配置空间中出现的地址都是PCI总线地址,属于PCI总线域地址空间。

2.3.1 PCI桥

PCI桥的引入使PCI总线极具扩展性,也极大地增加了PCI总线的复杂度。PCI总线的电气特性决定了在一条PCI总线上挂接的负载有限,当PCI总线需要连接多个PCI设备时,需要使用PCI桥进行总线扩展,扩展出的PCI总线可以连接其他PCI设备,包括PCI桥。在一颗PCI总线树上,最多可以挂接256个PCI设备,包括PCI桥。PCI桥在PCI总线树中的位置如图2‑8所示。

PCI桥作为一个特殊的PCI设备,具有独立的配置空间。但是PCI桥配置空间的定义与PCI Agent设备有所不同。PCI桥的配置空间可以管理其下PCI总线子树的PCI设备,并可以优化这些PCI设备通过PCI桥的数据访问。PCI桥的配置空间在系统软件遍历PCI总线树时配置,系统软件不需要专门的驱动程序设置PCI桥的使用方法,这也是PCI桥被称为透明桥的主要原因。

在某些处理器系统中,还有一类PCI桥,叫做非透明桥。非透明桥不是PCI总线定义的标准桥片,但是在使用PCI总线挂接另外一个处理器系统时非常有用,非透明桥片的主要作用是连接两个不同的PCI总线域,进而连接两个处理器系统,本章将在第2.5节中详细介绍PCI非透明桥。

使用PCI桥可以扩展出新的PCI总线,在这条PCI总线上还可以继续挂接多个PCI设备。PCI桥跨接在两个PCI总线之间,其中距离HOST主桥较近的PCI总线被称为该桥片上游总线(Primary Bus),距离HOST主桥较远的PCI总线被称为该桥片的下游总线(Secondary Bus)。如图2‑8所示,PCI桥1的上游总线为PCI总线x0,而PCI桥1的下游总线为PCI总线x1。这两条总线间的数据通信需要通过PCI桥1。

通过PCI桥连接的PCI总线属于同一个PCI总线域,在图2‑8中,PCI桥1、2和3连接的PCI总线都属于PCI总线x域。在这些PCI总线域上的设备可以通过PCI桥直接进行数据交换而不需要进行地址转换;而分属不同PCI总线域的设备间的通信需要进行地址转换,如与PCI非透明桥两端连接的设备之间的通信。

如图2‑8所示,每一个PCI总线的下方都可以挂接一个到多个PCI桥,每一个PCI桥都可以推出一条新的PCI总线。在同一条PCI总线上的设备之间的数据交换不会影响其他PCI总线。如PCI设备21与PCI设备22之间的数据通信仅占用PCI总线x2的带宽,而不会影响PCI总线x0、x1与x3,这也是引入PCI桥的另一个重要原因。

由图2‑8我们还可以发现PCI总线可以通过PCI桥组成一个胖树结构,其中每一个桥片都是父节点,而PCI Agent设备只能是子节点。当PCI桥出现故障时,其下的设备不能将数据传递给上游总线,但是并不影响PCI桥下游设备间的通信。当PCI桥1出现故障时,PCI设备11、PCI设备21和PCI设备22将不能与PCI设备01和存储器进行通信,但是PCI设备21和PCI设备22之间的通信可以正常进行。

使用PCI桥可以扩展一条新的PCI总线,但是不能扩展新的PCI总线域。如果当前系统使用32位的PCI总线地址,那么这个系统的PCI总线域的地址空间为4GB大小,在这个总线域上的所有设备将共享这个4GB大小的空间。如在PCI总线x域上的PCI桥1、PCI设备01、PCI设备11、PCI桥2、PCI设备21和PCI设备22等都将共享一个4GB大小的空间。再次强调这个4GB空间是PCI总线x域的“PCI总线地址空间”,和存储器域地址空间和PCI总线y域没有直接联系。

处理器系统可以通过HOST主桥扩展出新的PCI总线域,如MPC8548处理器的HOST主桥x和y可以扩展出两个PCI总线域x和y。这两个PCI总线域x和y之间的PCI空间在正常情况下不能直接进行数据交换,但是PowerPC处理器可以通过设置PIWARn寄存器的TGI字段使得不同PCI总线域的设备直接通信,详见第2.2.3节。

许多处理器系统使用的PCI设备较少,因而并不需要使用PCI桥。因此在这些处理器系统中,PCI设备都是直接挂接在HOST主桥上,而不需要使用PCI桥扩展新的PCI总线。即便如此读者也需要深入理解PCI桥的知识。

PCI桥对于理解PCI和PCIe总线都非常重要。在PCIe总线中,虽然在物理结构上并不含有PCI桥,但是与PCI桥相关的知识在PCIe总线中无处不在,比如在PCIe总线的Switch中,每一个端口都与一个虚拟PCI桥对应,Switch使用这个虚拟PCI桥管理其下PCI总线子树的地址空间。

2.3.2 PCI Agent设备的配置空间

在一个具体的处理器应用中,PCI设备通常将PCI配置信息存放在E2PROM中。PCI设备进行上电初始化时,将E2PROM中的信息读到PCI设备的配置空间中作为初始值。这个过程由硬件逻辑完成,绝大多数PCI设备使用这种方式初始化其配置空间。

读者可能会对这种机制产生一个疑问,如果系统软件在PCI设备将E2PROM中的信息读到配置空间之前,就开始操作配置空间,会不会带来问题?因为此时PCI设备的初始值并不“正确”,仅仅是PCI设备使用的复位值。

读者的这种担心是多余的,因为PCI设备在配置寄存器没有初始化完毕之前,即E2PROM中的内容没有导入PCI设备的配置空间之前,可以使用PCI总线规定的“Retry”周期使HOST主桥在合适的时机重新发起配置读写请求。

在x86处理器中,系统软件使用CONFIG_ADDR和CONFIG_DATA寄存器,读取PCI设备配置空间的这些初始化信息,然后根据处理器系统的实际情况使用DFS算法,初始化处理器系统中所有PCI设备的配置空间。

在PCI Agent设备的配置空间中包含了许多寄存器,这些寄存器决定了该设备在PCI总线中的使用方法,本节不会全部介绍这些寄存器,因为系统软件只对部分配置寄存器感兴趣。PCI Agent设备使用的配置空间如图2‑9所示。

在PCI Agent设备配置空间中包含的寄存器如下所示。

(1) Device ID和Vendor ID寄存器

这两个寄存器的值由PCISIG分配,只读。其中Vendor ID代表PCI设备的生产厂商,而Device ID代表这个厂商所生产的具体设备。如Intel公司的基于82571EB芯片的系列网卡,其Vendor ID为0x8086[1],而Device ID为0x105E[2]。

(2) Revision ID和Class Code寄存器

这两个寄存器只读。其中Revision ID寄存器记载PCI设备的版本号。该寄存器可以被认为是Device ID寄存器的扩展。

(3) Header Type寄存器

该寄存器只读,由8位组成。

第7位为1表示当前PCI设备是多功能设备,为0表示为单功能设备。

第6~0位表示当前配置空间的类型,为0表示该设备使用PCI Agent设备的配置空间,普通PCI设备都使用这种配置头;为1表示使用PCI桥的配置空间,PCI桥使用这种配置头;为2表示使用Cardbus桥片的配置空间,Card Bus桥片使用这种配置头,本篇对这类配置头不感兴趣。

系统软件需要使用该寄存器区分不同类型的PCI配置空间,该寄存器的初始化必须与PCI设备的实际情况对应,而且必须为一个合法值。

(4) Cache Line Size寄存器

该寄存器记录HOST处理器使用的Cache行长度。在PCI总线中和Cache相关的总线事务,如存储器写并无效和Cache多行读等总线事务需要使用这个寄存器。值得注意的是,该寄存器由系统软件设置,但是在PCI设备的运行过程中,只有其硬件逻辑才会使用该寄存器,比如PCI设备的硬件逻辑需要得知处理器系统Cache行的大小,才能进行存储器写并无效总线事务,单行读和多行读总线事务。

如果PCI设备不支持与Cache相关的总线事务,系统软件可以不设置该寄存器,此时该寄存器为初始值0x00。对于PCIe设备,该寄存器的值无意义,因为PCIe设备在进行数据传送时,在其报文中含有一次数据传送的大小,PCIe总线控制器可以使用这个“大小”,判断数据区域与Cache行的对应关系。

(5) Subsystem ID和Subsystem Vendor ID寄存器

这两个寄存器和Device ID和Vendor ID类似,也是记录PCI设备的生产厂商和设备名称。但是这两个寄存器和Device ID与Vendor ID寄存器略有不同。下文以一个实例说明Subsystem ID和Subsystem Vendor ID的用途。

Xilinx公司在FGPA中集成了一个PCIe总线接口的IP核,即LogiCORE。用户可以使用LogiCORE设计各种各样基于PCIe总线的设备,但是这些设备的Device ID都是0x10EE,而Vendor ID为0x0007[3]。

(6) Expansion ROM base address寄存器

有些PCI设备在处理器还没有运行操作系统之前,就需要完成基本的初始化设置,比如显卡、键盘和硬盘等设备。为了实现这个“预先执行”功能,PCI设备需要提供一段ROM程序,而处理器在初始化过程中将运行这段ROM程序,初始化这些PCI设备。Expansion ROM base address记载这段ROM程序的基地址。

(7) Capabilities Pointer寄存器

在PCI设备中,该寄存器是可选的,但是在PCI-X和PCIe设备中必须支持这个寄存器,Capabilities Pointer寄存器存放Capabilities寄存器组的基地址,PCI设备使用Capabilities寄存器组存放一些与PCI设备相关的扩展配置信息。该组寄存器的详细说明见第4.3节。

(8) Interrupt Line寄存器

这个寄存器是系统软件对PCI设备进行配置时写入的,该寄存器记录当前PCI设备使用的中断向量号,设备驱动程序可以通过这个寄存器,判断当前PCI设备使用处理器系统中的哪个中断向量号,并将驱动程序的中断服务例程注册到操作系统中[4]。

该寄存器由系统软件初始化,其保存的值与8259A中断控制器相关,该寄存器的值也是由PCI设备与8259A中断控制器的连接关系决定的。如果在一个处理器系统中,没有使用8259A中断控制器管理PCI设备的中断,则该寄存器中的数据并没有意义。

在多数PowerPC处理器系统中,并不使用8259A中断控制器管理PCI设备的中断请求,因此该寄存器没有意义。即使在x86处理器系统中,如果使用I/O APIC中断控制器,该寄存器保存的内容仍然无效。目前在绝大多数处理器系统中,并没有使用该寄存器存放PCI设备使用的中断向量号。

(9) Interrupt Pin寄存器

这个寄存器保存PCI设备使用的中断引脚,PCI总线提供了四个中断引脚INTA#、INTB#、INTC#和INTD#。Interrupt Pin寄存器为1时表示使用INTA#引脚向中断控制器提交中断请求,为2表示使用INTB#,为3表示使用INTC#,为4表示使用INTD#。

如果PCI设备只有一个子设备时,该设备只能使用INTA#;如果有多个子设备时,可以使用INTB~D#信号。如果PCI设备不使用这些中断引脚,向处理器提交中断请求时,该寄存器的值必须为0。值得注意的是,虽然在PCIe设备中并不含有INTA~D#信号,但是依然可以使用该寄存器,因为PCIe设备可以使用INTx中断消息,模拟PCI设备的INTA~D#信号,详见第6.3.4节。

(10) Base Address Register 0~5寄存器

该组寄存器简称为BAR寄存器,BAR寄存器保存PCI设备使用的地址空间的基地址,该基地址保存的是该设备在PCI总线域中的地址。其中每一个设备最多可以有6个基址空间,但多数设备不会使用这么多组地址空间。

在PCI设备复位之后,该寄存器将存放PCI设备需要使用的基址空间大小,这段空间是I/O空间还是存储器空间[5],如果是存储器空间该空间是否可预取,有关PCI总线预读机制的详细说明见第3.4.5节。

系统软件对PCI总线进行配置时,首先获得BAR寄存器中的初始化信息,之后根据处理器系统的配置,将合理的基地址写入相应的BAR寄存器中。系统软件还可以使用该寄存器,获得PCI设备使用的BAR空间的长度,其方法是向BAR寄存器写入0xFFFF-FFFF,之后再读取该寄存器。

处理器访问PCI设备的BAR空间时,需要使用BAR寄存器提供的基地址。值得注意的是,处理器使用存储器域的地址,而BAR寄存器存放PCI总线域的地址。因此处理器系统并不能直接使用“BAR寄存器+偏移”的方式访问PCI设备的寄存器空间,而需要将PCI总线域的地址转换为存储器域的地址。

如果x86处理器系统使能了IOMMU后,这两个地址也并不一定相等,因此处理器系统直接使用这个PCI总线域的物理地址,并不能确保访问PCI设备的BAR空间的正确性。除此之外在Linux系统中,ioremap函数的输入参数为存储器域的物理地址,而不能使用PCI总线域的物理地址。

而在pci_devàresource[bar].start参数中保存的地址已经经过PCI总线域到存储器域的地址转换,因此在编写Linux系统的设备驱动程序时,需要使用pci_devàresource[bar].start参数中的物理地址,然后再经过ioremap函数将物理地址转换为“存储器域”的虚拟地址。

(11) Command寄存器

该寄存器为PCI设备的命令寄存器,该寄存器在初始化时,其值为0,此时这个PCI设备除了能够接收配置请求总线事务之外,不能接收任何存储器或者I/O请求。系统软件需要合理设置该寄存器之后,才能访问该设备的存储器或者I/O空间。在Linux系统中,设备驱动程序调用pci_enable_device函数,使能该寄存器的I/O和Memory Space位之后,才能访问该设备的存储器或者I/O地址空间。

(12) Status寄存器

该寄存器的绝大多数位都是只读位,保存PCI设备的状态。

(13) Latency Timer寄存器

在PCI总线中,多个设备共享同一条总线带宽。该寄存器用来控制PCI设备占用PCI总线的时间,当PCI设备获得总线使用权,并使能Frame#信号后,Latency Timer寄存器将递减,当该寄存器归零后,该设备将使用超时机制停止[6]对当前总线的使用。

如果当前总线事务为Memeory Write and Invalidate时,需要保证对一个完整Cache行的操作结束后才能停止当前总线事务。对于多数PCI设备而言,该寄存器的值为32或者64,以保证一次突发传送的基本单位为一个Cache行。

PCIe设备不需要使用该寄存器,该寄存器的值必须为0。因为PCIe总线的仲裁方法与PCI总线不同,使用的连接方法也与PCI总线不同。

2.3.3 PCI桥的配置空间

PCI桥使用的配置空间的寄存器如图2‑10所示。PCI桥作为一个PCI设备,使用的许多配置寄存器与PCI Agent的寄存器是类似的,如Device ID、Vendor ID、Status、Command、Interrupt Pin、Interrupt Line寄存器等,本节不再重复介绍这些寄存器。下文将重点介绍在PCI桥中与PCI Agent的配置空间不相同的寄存器。

与PCI Agent设备不同,在PCI桥中只含有两组BAR寄存器,Base Address Register 0~1寄存器。这两组寄存器与PCI Agent设备配置空间的对应寄存器的含义一致。但是在PCI桥中,这两个寄存器是可选的。如果在PCI桥中不存在私有寄存器,那么可以不使用这组寄存器设置BAR空间。

在大多数PCI桥中都不存在私有寄存器,操作系统也不需要为PCI桥提供专门的驱动程序,这也是这类桥被称为透明桥的原因。如果在PCI桥中不存在私有空间时,PCI桥将这两个BAR寄存器初始化为0。在PCI桥的配置空间中使用两个BAR寄存器的目的是这两个32位的寄存器可以组成一个64位地址空间。

在PCI桥的配置空间中,有许多寄存器是PCI桥所特有的。PCI桥除了作为PCI设备之外,还需要管理其下连接的PCI总线子树使用的各类资源,即Secondary Bus所连接PCI总线子树使用的资源。这些资源包括存储器、I/O地址空间和总线号。

在PCI桥中,与Secondary bus相关的寄存器包括两大类。一类寄存器管理Secondary Bus之下PCI子树的总线号,如Secondary和Subordinate Bus Number寄存器;另一类寄存器管理下游PCI总线的I/O和存储器地址空间,如I/O和Memory Limit、I/O和Memory Base寄存器。在PCI桥中还使用Primary Bus寄存器保存上游的PCI总线号。

其中存储器地址空间还分为可预读空间和不可预读空间,Prefetchable Memory Limit和Prefetchable Memory Base寄存器管理可预读空间,而Memory Limit、Memory Base管理不可预读空间。在PCI体系结构中,除了了ROM地址空间之外,PCI设备使用的地址空间大多都是不可预读的。

(1) Subordinate Bus Number、Secondary Bus Number和Primary Bus Number寄存器

PCI桥可以管理其下的PCI总线子树。其中Subordinate Bus Number寄存器存放当前PCI子树中,编号最大的PCI总线号。而Secondary Bus Number寄存器存放当前PCI桥Secondary Bus使用的总线号,这个PCI总线号也是该PCI桥管理的PCI子树中编号最小的PCI总线号。因此一个PCI桥能够管理的PCI总线号在Secondary Bus Number~Subordinate Bus Number之间。这两个寄存器的值由系统软件遍历PCI总线树时设置。

Primary Bus Number寄存器存放该PCI桥上游的PCI总线号,该寄存器可读写。Primary Bus Number、Subordinate Bus Number和Secondary Bus Number寄存器在初始化时必须为0,系统软件将根据这几个寄存器是否为0,判断PCI桥是否被配置过。

不同的操作系统使用不同的Bootloader引导,有的Bootloader可能会对PCI总线树进行遍历,此时操作系统可以不再重新遍历PCI总线树。在x86处理器系统中,BIOS会遍历处理器系统中的所有PCI总线树,操作系统可以直接使用BIOS的结果,也可以重新遍历PCI总线树。而PowerPC处理器系统中的Bootloader,如U-Boot并没有完全遍历PCI总线树,此时操作系统必须重新遍历PCI总线树。

(2) Secondary Status寄存器

该寄存器的含义与PCI Agent配置空间的Status寄存器的含义相近,PCI桥的Secondary Status寄存器记录Secondary Bus的状态,而不是PCI桥作为PCI设备时使用的状态。在PCI桥配置空间中还存在一个Status寄存器,该寄存器保存PCI桥作为PCI设备时的状态。

(3) Secondary Latency Timer寄存器

该寄存器的含义与PCI Agent配置空间的Latency Timer寄存器的含义相近,PCI桥的Secondary Latency Timer寄存器管理Secondary Bus的超时机制,即PCI桥发向下游的总线事务;在PCI桥配置空间中还存在一个Latency Timer寄存器,该寄存器管理PCI桥发向上游的总线事务。

(4) I/O Limit和I/O Base寄存器

在PCI桥管理的PCI子树中包含许多PCI设备,而这些PCI设备可能会使用I/O地址空间。PCI桥使用这两个寄存器,存放PCI子树中所有设备使用的I/O地址空间集合的基地址和大小。

(5) Memory Limit和Memory Base寄存器

在PCI桥管理的PCI子树中有许多PCI设备,这些PCI设备可能会使用存储器地址空间。这两个寄存器存放所有这些PCI设备使用的,存储器地址空间集合的基地址和大小,PCI桥规定这个空间的大小至少为1MB。

(6) Prefetchable Memory Limit和Prefetchable Memory Base寄存器

在PCI桥管理的PCI子树中有许多PCI设备,如果这些PCI设备支持预读,则需要从PCI桥的可预读空间中获取地址空间。PCI桥的这两个寄存器存放这些PCI设备使用的,可预取存储器空间的基地址和大小。

如果PCI桥不支持预读,则其下支持预读的PCI设备需要从Memory Base寄存器为基地址的存储器空间中获取地址空间。如果PCI桥支持预读,其下的PCI设备需要根据情况,决定使用可预读空间,还是不可预读空间。PCI总线建议PCI设备支持预读,但是支持预读的PCI设备并不多见。

(7) I/O Base Upper 16 Bits and I/O Limit Upper 16寄存器

如果PCI桥仅支持16位的I/O端口,这组寄存器只读,且其值为0。如果PCI桥支持32位I/O端口,这组寄存器可以提供I/O端口的高16位地址。

(8) Bridge Control Register。

该寄存器用来管理PCI桥的Secondary Bus,其主要位的描述如下。

Secondary Bus Reset位,第6位,可读写。当该位为1时,将使用下游总线提供的RST#信号复位与PCI桥的下游总线连接的PCI设备。通常情况下与PCI桥下游总线连接的PCI设备,其复位信号需要与PCI桥提供的RST#信号连接,而不能与HOST主桥提供的RST#信号连接。

Primary Discard Timer位,第8位,可读写。PCI桥支持Delayed传送方式,当PCI桥的Primary总线上的主设备使用Delayed方式进行数据传递时,PCI桥使用Retry周期结束Primary总线的Non-Posted数据请求,并将这个Non-Posted数据请求转换为Delayed数据请求,之后主设备需要择时重试相同的Non-Posted数据请求。当该位为1时,表示在Primary Bus上的主设备需要在210个时钟周期之内重试这个数据请求,为0时,表示主设备需要在215个时钟周期之内重试这个数据请求,否则PCI桥将丢弃Delayed数据请求。

Secondary Discard Timer位,第9位,可读写。当该位为1时,表示在Secondary Bus上的主设备需要在210个时钟周期之内重试这个数据请求,为0时,表示主设备需要在215个时钟周期之内重试这个数据请求,如果主设备在规定的时间内没有进行重试时,PCI桥将丢弃Delayed数据请求。

PCI总线的配置

PCI总线定义了两类配置请求,一个是Type 00h配置请求,另一个是Type 01h配置请求。PCI总线使用这些配置请求访问PCI总线树上的设备配置空间,包括PCI桥和PCI Agent设备的配置空间。

其中HOST主桥或者PCI桥使用Type 00h配置请求,访问与HOST主桥或者PCI桥直接相连的PCI Agent设备或者PCI桥[1];而HOST主桥或者PCI桥使用Type 01h配置请求,需要至少穿越一个PCI桥,访问没有与其直接相连的PCI Agent设备或者PCI桥。如图2‑8所示,HOST主桥可以使用Type 00h配置请求访问PCI设备01,而使用Type 01h配置请求通过PCI桥1、2或者3转换为Type 00h配置请求之后,访问PCI总线树上的PCI设备11、21、22、31和32[2]。

当x86处理器对CONFIG_DATA寄存器进行读写操作时,HOST主桥将决定向PCI总线发送Type 00h配置请求还是Type 01h配置请求。在PCI总线事务的地址周期中,这两种配置请求总线事务的不同反映在PCI总线的AD[31:0]信号线上。

值得注意的是,PCIe总线还可以使用ECAM(Enhanced Configuration Access Mechanism)机制访问PCIe设备的扩展配置空间,使用这种方式可以访问PCIe设备256B~4KB之间的扩展配置空间。但是本节仅介绍如何使用CONFIG_ADDRESS和CONFIG_FATA寄存器产生Type 00h和Type 01h配置请求。有关ECAM机制的详细说明见第5.3.2节。

处理器首先将目标PCI设备的ID号保存在CONFIG_ADDRESS寄存器中,之后HOST主桥根据该寄存器的Bus Number字段,决定是产生Type 00h配置请求,还是Type 01h配置请求。当Bus Number字段为0时,将产生Type 00h配置请求,因为与HOST主桥直接相连的总线号为0;大于0时,将产生Type 01h配置请求。

2.4.1 Type 01h和Type 00h配置请求

本节首先介绍Type 01h配置请求,并从PCI总线使用的信号线的角度上,讲述HOST主桥如何生成Type 01配置请求。在PCI总线中,只有PCI桥能够接收Type 01h配置请求。Type 01h配置请求不能直接发向最终的PCI Agent设备,而只能由PCI桥将其转换为Type 01h继续发向其他PCI桥,或者转换为Type 00h配置请求发向PCI Agent设备。PCI桥还可以将Type 01h配置请求转换为Special Cycle总线事务(HOST主桥也可以实现该功能),本节对这种情况不做介绍。

在地址周期中,HOST主桥使用配置读写总线事务,将CONFIG_ADDRESS寄存器的内容拷贝到PCI总线的AD[31:0]信号线中。CONFIG_ADDRESS寄存器与Type 01h配置请求的对应关系如图2‑11所示。

从图2‑11中可以发现,CONFIG_ADDRESS寄存器的内容基本上是原封不动的拷贝到PCI总线的AD[31:0]信号线上的[3]。其中CONFIG_ADDRESS的Enable位不被拷贝,而AD总线的第0位为必须为1,表示当前配置请求是Type 01h。

当PCI总线接收到Type 01配置请求时,将寻找合适的PCI桥[4]接收这个配置信息。如果这个配置请求是直接发向PCI桥下的PCI设备时,PCI桥将接收个Type 01配置请求,并将其转换为Type 00h配置请求;否则PCI桥将当前Type 01h配置请求原封不动的传递给下一级PCI总线。

如果HOST主桥或者PCI桥发起的是Type 00h配置请求,CONFIG_ADDRESS寄存器与AD[31:0]的转换如图2‑12所示。

此时处理器对CONFIG_DATA寄存器进行读写时,处理器将CONFIG_ADDRESS寄存器中的Function Number和Register Number字段拷贝到PCI的AD总线的第10~2位;将AD总线的第1~0位赋值为0b00。PCI总线在配置请求总线事务的地址周期根据AD[1:0]判断当前配置请求是Type 00h还是Type 01h,如果AD[1:0]等于0b00表示是Type 00h配置请求,如果AD[1:0]等于0b01表示是Type 01h配置请求。

而AD[31:11]与CONFIG_ADDRESS的Device Number字段有关,在Type 00h配置请求的地址周期中,AD[31:11]位有且只有一位为1,其中AD[31:11]的每一位选通一个PCI设备的配置空间。如第1.2.2节所述,PCI设备配置空间的片选信号是IDSEL,因此AD[31:11]将与PCI设备的IDSEL信号对应相连。

当以下两种请求之一满足时,HOST主桥或者PCI桥将生成Type 00h配置头,并将其发送到指定的PCI总线上。

(1) CONFIG_ADDRESS寄存器的Bus Number字段为0时,处理器访问CONFIG_DATA寄存器时,HOST主桥将直接向PCI总线0发出Type 00h配置请求。因为与HOST主桥直接相连的PCI总线号为0,此时表示HOST主桥需要访问与其直接相连的PCI设备。

(2) 当PCI桥收到Type 01h配置头时,将检查Type 01配置头的Bus Number字段,如果这个Bus Number与PCI桥的Secondary Bus Number相同,则将这个Type 01配置头转换为Type 00h配置头,并发送到该PCI桥的Secondary总线上。

2.4.2 PCI总线配置请求的转换原则

当CONFIG_ADDRESS寄存器的Enable位为1,系统软件访问CONFIG_DATA寄存器时,HOST主桥可以产生两类PCI总线配置读写总线事务,分别为Type 00h和Type 01h配置读写总线事务。在配置读写总线事务的地址周期和数据周期中,CONFIG_ADDRESS和CONFIG_DATA寄存器中的数据将被放置到PCI总线的AD总线上。其中Type 00h和Type 01h配置读写总线事务映射到AD总线的数据并不相同。

其中Type 00h配置请求可以直接读取PCI Agent设备的配置空间,而Type 01h配置请求在通过PCI桥时,最终将被转换为Type 00h配置请求,并读取PCI Agent设备的配置寄存器。本节重点讲述PCI桥如何将Type 01h配置请求转换为Type 00h配置请求。

首先Type 00h配置请求不会被转换成Type 01h配置请求,因为Type 00h配置请求是发向最终PCI Agent设备,这些PCI Agent设备不会转发这些配置请求。

当CONFIG_ADDRESS寄存器的Bus Number字段为0时,处理器对CONFIG_DATA寄存器操作时,HOST主桥将直接产生Type 00h配置请求,挂接在PCI总线0上的某个设备将通过ID译码接收这个Type 00h配置请求,并对配置寄存器进行读写操作。如果PCI总线上没有设备接收这个Type 00h配置请求,将引发Master Abort,详情见PCI总线规范,本节对此不做进一步说明。

如果CONFIG_ADDRESS寄存器的Bus Number字段为n(n≠0),即访问的PCI设备不是直接挂接在PCI总线0上的,此时HOST主桥对CONFIG_DATA寄存器操作时,将产生Type 01h配置请求,PCI总线0将遍历所有在这条总线上的PCI桥,确定由哪个PCI桥接收这个Type 01h配置请求。

如果n大于等于某个PCI桥的Secondary Bus Number寄存器,而且小于等于Subordinate Bus number寄存器,那么这个PCI桥将接收在当前PCI总线上的Type 01配置请求,并采用以下规则进行递归处理。

(1) 开始。

(2) 遍历当前PCI总线的所有PCI桥。

(3) 如果n等于某个PCI桥的Secondary Bus Number寄存器,说明这个Type 01配置请求的目标设备直接连接在该PCI桥的Secondary bus上。此时PCI桥将Type 01配置请求转换为Type 00h配置请求,并将这个配置请求发送到PCI桥的Secondary Bus上,Secondary Bus上的某个设备将响应这个Type 00h配置请求,并与HOST主桥进行配置信息的交换,转(5)。

(4) 如果n大于PCI桥的Secondary Bus Number寄存器,而且小于等于PCI桥的Subordinate Bus number寄存器,说明这个Type 01配置请求的目标设备不与该PCI桥的Secondary Bus直接相连,但是由这个PCI桥下游总线上的某个PCI桥管理。此时PCI桥将首先认领这个Type 01配置请求,并将其转发到Secondary Bus,转(2)。

(5) 结束。

下文将举例说明PCI总线配置请求的转换原则,并以图2‑8为例说明处理器如何访问PCI设备01和PCI设备31的配置空间。PCI设备01直接与HOST主桥相连,因此HOST主桥可以使用Type 00h配置请求访问该设备。

而HOST主桥需要经过多级PCI桥才能访问PCI设备31,因此HOST主桥需要首先使用Type 01h配置请求,之后通过PCI桥1、2和3将Type 01h配置请求转换为Type 00h配置请求,最终访问PCI设备31。

1 PCI设备01

这种情况较易处理,当HOST处理器访问PCI设备01的配置空间时,发现PCI设备01与HOST主桥直接相连,所以将直接使用Type 00h配置请求访问该设备的配置空间,具体步骤如下。

首先HOST处理器将CONFIG_ADDRESS寄存器的Enable位置1,Bus Number号置为0,并对该寄存器的Device、Function和Register Number字段赋值。当处理器对CONFIG_DATA寄存器访问时,HOST主桥将存放在CONFIG_ADDRESS寄存器中的数值,转换为Type 00h配置请求,并发送到PCI总线0上,PCI设备01将接收这个Type 00h配置请求,并与处理器进行配置信息交换。

2 PCI设备31

HOST处理器对PCI设备31进行配置读写时,需要通过HOST主桥、PCI桥1、2和3,最终到达PCI设备31。

当处理器访问PCI设备31时,首先将CONFIG_ADDRESS寄存器的Enable位置1,Bus Number字段置为3,并对Device、Function和Register Number字段赋值。之后当处理器对CONFIG_DATA寄存器进行读写访问时,HOST主桥、PCI桥1、2和3将按照以下步骤进行处理,最后PCI设备31将接收这个配置请求。

(1) HOST主桥发现Bus Number字段的值为3,该总线号并不是与HOST主桥直接相连的PCI总线的Bus Number,所以HOST主桥将处理器对CONFIG_DATA寄存器的读写访问直接转换为Type 01h配置请求,并将这个配置请求发送到PCI总线0上。PCI总线规定Type 01h配置请求只能由PCI桥负责处理。

(2) 在PCI总线0上,PCI桥1的Secondary Bus Number为1而Subordinate Bus Number为3。而1< Bus Number <= 3,所以PCI桥1将接收来自PCI总线0的Type 01h配置请求,并将这个配置请求直接下推到PCI总线1。

(3) 在PCI总线1上,PCI桥2的Secondary Bus Number为2而Subordinate Bus Number为3。而1< Bus Number <= 3,所以PCI桥2将接收来自PCI总线0的Type 01h配置请求,并将这个配置请求直接下推到PCI总线2。

(4) 在PCI总线2上,PCI桥3的Secondary Bus Number为3,因此PCI桥3将“来自PCI总线2的Type 01h配置请求”转换为Type 00h配置请求,并将其下推到PCI总线3。PCI总线规定,如果PCI桥的Secondary Bus Number与Type 01h配置请求中包含的Bus Number相同时,该PCI桥将接收的Type 01h配置请求转换为Type 00h配置请求,然后再发向其Secondary Bus。

(5) 在PCI总线3上,有两个设备PCI设备31和PCI设备32。在这两个设备中,必然有一个设备将要响应这个Type 00h配置请求,从而完成整个配置请求周期。本篇在第2.4.1节中,讨论了究竟是PCI设备31还是PCI设备32接收这个配置请求,这个问题涉及PCI总线如何分配PCI设备使用的设备号。

2.4.3 PCI总线树Bus号的初始化

在一个处理器系统中,每一个HOST主桥都推出一颗PCI总线树。在一颗PCI总线树中有多少个PCI桥(包括HOST主桥),就含有多少条PCI总线。系统软件在遍历当前PCI总线树时,需要首先对这些PCI总线进行编号,即初始化PCI桥的Primary、Secondary和Subordinate Bus Number寄存器。

在一个处理器系统中,一般将与HOST主桥直接相连的PCI总线被命名为PCI总线0。然后系统软件使用DFS(Depth First Search)算法,依次对其他PCI总线进行编号。值得注意的是,与HOST主桥直接相连的PCI总线,其编号都为0,因此当处理器系统中存在多个HOST主桥时,将有多个编号为0的PCI总线,但是这些编号为0的PCI总线分属不同的PCI总线域,其含义并不相同。

在一个处理器系统中,PCI总线树的结构如图2‑13所示。当然在一个实际的处理器系统中,很少会出现这样复杂的PCI总线树结构,本节采用这个结构的目的是便于说明PCI总线号的分配过程。

在PCI总线中,系统软件使用深度优先DFS算法对PCI总线树进行遍历,DFS算法和广度优先BFS(Breadth First Search)算法是遍历树型结构的常用算法。与BFS算法相比,DFS算法的空间复杂度较低,因此绝大多数系统系统在遍历PCI总线树时,都使用DFS算法而不是BFS算法。

DFS是搜索算法的一种,其实现机制是沿着一颗树的深度遍历各个节点,并尽可能深地搜索树的分支,DFS的算法为线性时间复杂度,适合对拓扑结构未知的树进行遍历。在一个处理器系统的初始化阶段,PCI总线树的拓扑结构是未知的,适合使用DFS算法进行遍历。下文以图2‑13为例,说明系统软件如何使用DFS算法,分配PCI总线号,并初始化PCI桥中的Primary Bus Number、Secondary Bus Number和Subordinate Bus number寄存器。所谓DFS算法是指按照深度优先的原则遍历PCI胖树,其步骤如下。

(1) HOST主桥扫描PCI总线0上的设备。系统软件首先忽略所有这条总线上的PCI Agent设备,因为在这些设备之下不会挂接新的PCI总线。例如PCI设备01下不可能挂接新的PCI总线。

(2) HOST主桥首先发现PCI桥1,并将PCI桥1的Secondary Bus命名为PCI总线1。系统软件将初始化PCI桥1的配置空间,将PCI桥1的Primary Bus Number寄存器赋值为0,而将Secondary Bus Number寄存器赋值为1,即PCI桥1的上游PCI总线号为0,而下游PCI总线号为1。

(3) 扫描PCI总线1,发现PCI桥2,并将PCI桥2的Secondary Bus命名为PCI总线2。系统软件将初始化PCI桥2的配置空间,将PCI桥2的Primary Bus Number寄存器赋值为1,而将Secondary Bus Number寄存器赋值为2。

(4) 扫描PCI总线2,发现PCI桥3,并将PCI桥3的Secondary Bus命名为PCI总线3。系统软件将初始化PCI桥3的配置空间,将PCI桥3的Primary Bus Number寄存器赋值为2,而将Secondary Bus Number寄存器赋值为3。

(5) 扫描PCI总线3,没有发现任何PCI桥,这表示PCI总线3下不可能有新的总线,此时系统软件将PCI桥3的Subordinate Bus number寄存器赋值为3。系统软件在完成PCI总线3的扫描后,将回退到PCI总线3的上一级总线,即PCI总线2,继续进行扫描。

(6) 在重新扫描PCI总线2时,系统软件发现PCI总线2上除了PCI桥3之外没有发现新的PCI桥,而PCI桥3之下的所有设备已经完成了扫描过程,此时系统软件将PCI桥2的Subordinate Bus number寄存器赋值为3。继续回退到PCI总线1。

(7) PCI总线1上除了PCI桥2外,没有其他桥片,于是继续回退到PCI总线0,并将PCI桥1的Subordinate Bus number寄存器赋值为3。

(8) 在PCI总线0上,系统软件扫描到PCI桥4,则首先将PCI桥4的Primary Bus Number寄存器赋值为0,而将Secondary Bus Number寄存器赋值为4,即PCI桥1的上游PCI总线号为0,而下游PCI总线号为4。

(9) 系统软件发现PCI总线4上没有任何PCI桥,将结束对PCI总线4的扫描,并将PCI桥4的Subordinate Bus number寄存器赋值为4,之后回退到PCI总线4的上游总线,即PCI总线0继续进行扫描。

(10) 系统软件发现在PCI总线0上的两个桥片PCI总线0和PCI总线4都已完成扫描后,将结束对PCI总线的DFS遍历全过程。

从以上算法可以看出,PCI桥的Primary Bus和Secondary Bus号的分配在遍历PCI总线树的过程中从上向下分配,而Subordinate Bus号是从下向上分配的,因为只有确定了一个PCI桥之下究竟有多少条PCI总线后,才能初始化该PCI桥的Subordinate Bus号。

2.4.4 PCI总线Device号的分配

一条PCI总线会挂接各种各样的PCI设备,而每一个PCI设备在PCI总线下具有唯一的设备号。系统软件通过总线号和设备号定位一个PCI设备之后,才能访问这个PCI设备的配置寄存器。值得注意的是,系统软件使用“地址寻址方式”访问PCI设备的存储器和I/O地址空间,这与访问配置空间使用的“ID寻址方式”不同。

PCI设备的IDSEL信号与PCI总线的AD[31:0]信号的连接关系决定了该设备在这条PCI总线的设备号。如上文所述,每一个PCI设备都使用独立的IDSEL信号,该信号将与PCI总线的AD[31:0]信号连接,IDSEL信号的含义见第1.2.2节。

在此我们简要回顾PCI的配置读写事务使用的时序。如图1‑3所示,PCI总线事务由一个地址周期加若干个数据周期组成。在进行配置读写请求总线事务时,C/BE#信号线的值在地址周期中为0x1010或者为0x1011,表示当前总线事务为配置读或者配置写请求。此时出现在AD[31:0]总线上的值并不是目标设备的PCI总线地址,而是目标设备的ID号,这与PCI总线进行I/O或者存储器请求时不同,因为PCI总线使用ID号而不是PCI总线地址对配置空间进行访问。

如图2‑12所示,在配置读写总线事务的地址周期中,AD[10:0]信号已经被Function Number和Register Number使用,因此PCI设备的IDSEL只能与AD[31:11]信号连接。

认真的读者一定可以发现在CONFIG_ADDRESS寄存器中Device Number字段一共有5位可以表示32个设备,而AD[31:11]只有21位,显然在这两者之间无法建立一一对应的映射关系。因此在一条PCI总线上如果有21个以上的PCI设备,那么总是有几个设备无法与AD[31:11]信号线连接,从而PCI总线无法访问这些设备。因为PCI总线在配置请求的地址周期中,只能使用第31~11这些AD信号,所以在一条总线上最多也只能挂接21个PCI设备。这21个设备可能是从0到20,也可能是从11到31排列。从而系统软件在遍历PCI总线时,还是需要从0到31遍历整条PCI总线。

在实际的应用中,一条PCI总线能够挂接21个设备已经足够了,实际上由于PCI总线的负载能力有限,即便总线频率为33MHz的情况下,在一条PCI总线中最多也只能挂接10个负载,一条PCI总线所能挂接的负载详见表1‑1。AD信号线与PCI设备IDSEL线的连接关系如图2‑14所示。

PCI总线推荐了一种Device Number字段与AD[31:16]之间的映射关系。其中PCI设备0与Device Number字段的0b00000对应;PCI设备1与Device Number字段的0b00001对应,并以此类推,PCI设备15与Device Number字段的0b01111对应。

在这种映射关系之下,一条PCI总线中,与信号线AD16相连的PCI设备其设备号为0;与信号线AD17相连的PCI设备其设备号为1;以此类推,与信号线AD31相连的PCI设备其设备号为15。在Type 00h配置请求中,设备号并没有像Function Number和Register Number那样以编码的形式出现在AD总线上,而是与AD信号一一对应,如图2‑12所示。

这里有一个原则需要读者注意,就是对PCI设备的配置寄存器进行访问时,一定要有确定的Bus Number、Device Number、Function Number和Register Number,这“四元组”缺一不可。在Type 00h配置请求中,Device Number由AD[31:11]信号线与PCI设备IDSEL信号的连接关系确定;Function Number保存在AD[10:8]字段中;而Register Number保存在AD[7:0]字段中;在Type 01h配置请求中,也有完整的四元组信息。

非透明PCI桥

PCI桥规范定义了透明桥的实现规则,本篇在第2.3.1节中详细介绍了这种桥片。通过透明桥,处理器系统可以以HOST主桥为根节点,建立一颗PCI总线树,在这个树上的PCI设备共享同一个PCI总线域上的地址空间。

但是在某些场合下PCI透明桥并不适用。在图2‑15所示的处理器系统中存在两个处理器,此时使用PCI桥1连接处理器2并不利于整个处理器系统的配置与管理。我们假定PCI总线使用32位地址空间,而处理器1和处理器2所使用的存储器大小都为2GB,同时我们假定处理器1和处理器2使用的存储器都可以被PCI设备访问。

此时处理器1和2使用的存储器空间必须映射到PCI总线的地址空间中,而32位的PCI总线只能提供4GB地址空间,此时PCI总线x0的地址空间将全部被处理器1和2的存储器空间占用,而没有额外的空间分配给PCI设备。

此外有些处理器不能作为PCI Agent设备,因此不能直接连接到PCI桥上,比如x86处理器就无法作为PCI Agent设备,因此使用PCI透明桥无法将两个x86处理器直接相连。如果处理器2有两个以上的PCI接口,其中一个可以与PCI桥1相连(此时处理器2将作为PCI Agent设备),而另一个作为HOST主桥y连接PCI设备。此时HOST主桥y挂接的PCI设备将无法被处理器1直接访问。

使用透明桥也不便于解决处理器1与处理器2间的地址冲突,如图2‑15所示的处理器系统,如果处理器1和2都将各自的存储器映射到PCI总线地址空间中,有可能会出现地址冲突。虽然PowerPC处理器可以使用Inbound寄存器,将存储器地址空间映射到不同的PCI总线地址空间中,但是不是所有的处理器都具有这种映射机制。许多处理器的存储器地址与PCI总线地址使用了“简单相等”这种映射方法,如果PCI总线连接了两个这样的处理器,将不可避免地出现PCI总线地址的映射冲突。

采用非透明桥将有效解决以上这些问题,非透明桥并不是PCI总线定义的标准桥片,但是这类桥片在连接两个处理器系统中得到了广泛的应用。一个使用非透明桥连接两个处理器系统的实例如图2‑16所示。

使用非透明PCI桥可以方便地连接两个处理器系统。从上图中我们可以发现非透明桥可以将PCI总线x域与PCI总线y域进行隔离。值得注意的是,非透明PCI桥的作用是对不同PCI总线域地址空间进行隔离,而不是隔离存储器域地址空间。而HOST主桥的作用才是将存储器域与PCI总线域进行隔离。

非透明PCI桥可以连接两条独立的PCI总线,一条被称为Secondary PCI总线,另一条被称为Primary PCI总线,但是这两条总线没有从属关系,两边是对等的[1]。从处理器x的角度上看,与非透明PCI桥右边连接的总线叫Secondary PCI总线;而从处理器y的角度上看,非透明PCI桥左边连接的总线叫Secondary PCI总线。

HOST处理器x和PCI设备可以通过非透明PCI桥,直接访问PCI总线y域的地址空间,并通过HOST主桥y与访问存储器y;HOST处理器y和PCI设备也可以通过非透明PCI桥,直接访问PCI总线x域的地址空间,并通过HOST主桥x访问存储器x。为此非透明PCI桥需要对分属不同PCI总线域的地址空间进行转换。

目前有许多厂商可以提供非透明PCI桥的芯片,在具体实现上各有差异,但是其基本原理类似,下文以Intel 21555为例说明非透明PCI桥。值得注意的是,在PCIe体系结构中,也存在非透明PCI桥的概念。

2.5.1 Intel 21555中的配置寄存器

Intel 21555非透明PCI桥源于DEC21554[2],并在此基础上做了一些改动。Intel 21555桥片与其他透明桥在系统中的位置相同。如图2‑16所示,这个桥片一边与Primary PCI总线相连,另一边与Secondary PCI总线相连。

在Intel 21555桥片中,包含两个PCI 设备配置空间,分别是Primary PCI总线配置空间和Secondary PCI总线配置空间,处理器可以使用Type 00h配置请求访问这些配置空间。在大多数情况之下,在Primary PCI总线上的HOST处理器管理Primary PCI配置空间;在Secondary PCI总线上的HOST处理器管理Secondary PCI配置空间[3]。

在Intel 21555桥片中,还有一组私有寄存器CSR(Control and Status Register),系统软件使用这组寄存器对非透明桥进行管理并获得桥片的一些信息,这组寄存器可以被映射成为PCI总线的存储器地址空间或者I/O地址空间。

本章仅介绍Primary PCI总线这一边的配置寄存器,Secondary PCI总线的配置寄存器虽然与Primary PCI总线的这些寄存器略有不同,但是基本对等,因此本节对此不做介绍。Primary PCI总线的主要寄存器如表2‑6所示。

表2‑6 Primary PCI总线的配置寄存器

从表2‑6中,我们可以发现Primary PCI总线的这些配置寄存器共分为两组,一组寄存器与PCI设备的配置寄存器的BAR0~5对应,这些寄存器与标准PCI配置寄存器BAR0~5的功能相同;另一组寄存器是Translated Base寄存器,这组寄存器的主要作用是将来自Primary PCI总线的数据访问转换到Secondary PCI总线。

其中BAR0~5寄存器在系统初始化时由Primary PCI总线上的HOST处理器进行配置,配置过程与PCI总线上的普通设备完全相同。只是Intel 21555规定,BAR0只能映射为32位存储器空间。

CSR寄存器可以根据需要映射在BAR0空间中,此时BAR0空间最小为4KB。CSR寄存器也可以根据需要使用BAR1寄存器映射为I/O地址空间,同时BAR1寄存器还可以映射其他I/O空间;BAR2~3只能映射为32位存储器地址空间;而BAR4~5用来映射64位的存储器地址空间。

对于Primary PCI总线,所有BAR0~5寄存器映射的地址空间都将占用Primary PCI总线域,然而这些地址空间中所对应的数据并不在Primary PCI总线域中,而是在Secondary PCI总线域中。Translated Base寄存器实现不同PCI总线域地址空间的转换,Intel 21555将不同PCI总线域地址空间的转换过程称为“地址翻译”。

Intel 21555支持两种地址翻译方法,一个是直接地址翻译,一个是查表翻译。Primary PCI总线的BAR空间只支持直接地址翻译,而Secondary PCI总线的Memory 2 BAR空间支持查表翻译,本节仅介绍直接地址翻译方法,对查表翻译有兴趣的读者请阅读Intel 21555的数据手册[4]。直接地址翻译过程如图2‑17所示。

当Primary PCI总线对非透明桥21555的BAR0~5地址空间进行数据请求时,这个数据请求将被转换为对Secondary PCI总线的数据请求。Translated Base寄存器将完成这个地址翻译过程,下节将结合实例说明这个直接地址翻译过程。

2.5.2 通过非透明桥片进行数据传递

下文以图2‑16中处理器x访问处理器y存储器地址空间的实例,说明非透明桥21555如何将PCI总线x域与PCI总线y域联系在一起。

处理器x需要访问处理器y的存储器空间之前,需要做一些必要的准备工作。

(1) 首先确定由哪一个BAR寄存器空间映射处理器y的存储器地址空间。本节假定使用BAR2寄存器映射处理器y的存储器地址空间。

(2) BAR2寄存器使用Downstream Memory 2 Translated Base寄存器,将来自Primary PCI总线的访问转换为对Secondary PCI总线地址空间的访问。其中Downstream Memory 2 Translated Base寄存器可以由处理器x或者处理器y根据需要进行设置。

假定处理器x和y的HOST主桥使用“直接相等”策略,建立存储器域与PCI总线域间的映射;而处理器x使用BAR2地址空间访问处理器y存储器空间0x1000-000~0x1FFF-FFFF;处理器x的系统软件事先将BAR2寄存器设置完毕。处理器x访问处理器y的这段存储器空间的步骤如下,读者可参考图2‑18理解这一步骤。

(1) 首先处理器x访问在处理器x域中,且与非透明桥的BAR2空间相对应的存储器地址空间。

(2) HOST主桥将进行存储器域到PCI总线域的转换,并将这个请求发送到Primary PCI总线上。

(3) 非透明桥发现这个数据请求发向BAR2地址空间,则接收这个数据请求,并在桥片中暂存这个数据请求。

(4) 非透明桥根据Downstream Memory 2 Translated Base寄存器的内容,按照图2‑17所示的规则进行地址转换。假设Downstream Memory 2 Translated Base寄存器的基地址被预先设置为0x1000-0000,大小为256MB(这个物理地址属于处理器y的主存储器地址空间)。

(5) 经过非透明桥的转换后,这个数据请求将穿越非透明桥,从Primary PCI总线域进入Secondary PCI总线域,然后访问处理器y的基地址为0x1000-0000的存储器区域。

(6) 处理器y的HOST主桥接收这个存储器访问请求,并最终将数据请求发向处理器y的存储器中。

非透明桥21555除了可以支持存储器到存储器之间的数据传递,还支持PCI总线域到存储器域,以及PCI总线域之间的数据传递,此外非透明桥21555还可以通过I2O和Doorbell寄存器进行Primary PCI总线与Secondary PCI总线之间的中断信号传递。本节对这部分内容不做进一步介绍。

非透明桥有效解决了使用PCI总线连接两个处理器存在的问题,因而得到了广泛的应用。在PCIe体系结构中,也存在非透明PCI桥的概念。如在PLX的Switch芯片中,各个端口都可以设置为非透明模式。

代码语言:javascript
复制
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenFPGA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.4.1 Type 01h和Type 00h配置请求
  • 2.4.2 PCI总线配置请求的转换原则
    • 1 PCI设备01
      • 2 PCI设备31
      • 2.4.3 PCI总线树Bus号的初始化
      • 2.4.4 PCI总线Device号的分配
      • 2.5.1 Intel 21555中的配置寄存器
      • 2.5.2 通过非透明桥片进行数据传递
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档