在PCI Agent设备进行数据传送之前,系统软件需要初始化PCI Agent设备的BAR0~5寄存器和PCI桥的Base、Limit寄存器。系统软件使用DFS算法对PCI总线进行遍历时,完成这些寄存器的初始化,即分配这些设备在PCI总线域的地址空间。当这些寄存器初始化完毕后,PCI设备可以使用PCI总线地址进行数据传递。
值得注意的是,PCI Agent设备的BAR0~5寄存器和PCI桥的Base寄存器保存的地址都是PCI总线地址。而这些地址在处理器系统的存储器域中具有映像,如果一个PCI设备的BAR空间在存储器域中没有映像,处理器将不能访问该PCI设备的BAR空间。
如上文所述,处理器通过HOST主桥将PCI总线域与存储器域隔离。当处理器访问PCI设备的地址空间时,需要首先访问该设备在存储器域中的地址空间,并通过HOST主桥将这个存储器域的地址空间转换为PCI总线域的地址空间之后,再使用PCI总线事务将数据发送到指定的PCI设备中。
PCI设备访问存储器域的地址空间,即进行DMA操作时,也是首先访问该存储器地址空间所对应的PCI总线地址空间,之后通过HOST主桥将这个PCI总线地址空间转换为存储器地址空间,再由DDR控制器对存储器进行读写访问。
不同的处理器系统采用不同的机制实现存储器域和PCI总线域的转换。如PowerPC处理器使用Outbound寄存器组实现存储器域到PCI总线域间的转换,并使用Inbound寄存器组实现PCI总线域到存储器域间的转换。
而x86处理器没有这种地址空间域的转换机制,因此从PCI设备的角度上看,PCI设备可以直接访问存储器地址;从处理器的角度上看,处理器可以直接访问PCI总线地址空间。但是读者需要注意,在x86处理器的HOST主桥中仍然有存储器域与PCI总线域这个概念。只是在x86处理器的HOST主桥中,存储器域的存储器地址与PCI总线地址相等,这种“简单相等”也是一种映射关系。
3.1.1 存储器地址与PCI总线地址的转换
下文根据PowerPC和x86处理器的主桥,抽象出一个虚拟的HOST主桥,并以此为例讲述PCI Agent设备之间,以及PCI Agent设备与主存储器间的数据传送过程。
我们假设在一个32位处理器中,其存储器域的0xF000-0000~0xF7FF-FFFF(共128MB)这段物理地址空间与PCI总线的地址空间存在映射关系。
当处理器访问这段存储器地址空间时,HOST主桥将会认领这个存储器访问,并将这个存储器访问使用的物理地址空间转换为PCI总线地址空间,并与0x7000-0000~0x77FF-FFFF这段PCI总线地址空间对应。
为简化起见,我们假定在存储器域中只映射了PCI设备的存储器地址空间,而不映射PCI设备的I/O地址空间。而PCI设备的BAR空间使用0x7000-0000~0x77FF-FFFF这段PCI总线域的存储器地址空间。
在这个HOST主桥中,存储器域与PCI总线域的对应关系如图3?1所示。
当PCI设备使用DMA机制,访问存储器域地址空间时,处理器系统同样需要将存储器域的地址空间反向映射到PCI总线地址空间。假设在一个处理器系统中,如果主存储器大小为2GB,其在存储器域的地址范围为0x0000-0000~0x7FFF-FFFF,而这段地址在PCI总线域中对应的“PCI总线地址空间”为0x8000-0000~0xFFFF-FFFF。
因此PCI设备进行DMA操作时,必须使用0x8000-0000~0xFFFF-FFFF这段PCI总线域的地址,HOST主桥才能认领这个PCI总线事务,并将这个总线事务使用的PCI总线地址转换为存储器地址,并与0x0000-0000~0x7FFF-FFFF这段存储器区域进行数据传递。
在一个实际的处理器系统中,很少有系统软件采用这样的方法,实现存储器域与PCI总线域之间的映射,“简单相等”还是最常用的映射方法。本章采用图3?1的映射关系,虽然增加了映射复杂度,却便于读者深入理解存储器域到PCI总线域之间的映射关系。下文将以这种映射关系为例,详细讲述PCI设备BAR0~5寄存器的初始化。
3.1.2 PCI设备BAR寄存器和PCI桥Base、Limit寄存器的初始化
PCI桥的Base、Limit寄存器保存“该桥所管理的PCI子树”的存储器或者I/O空间的基地址和长度。值得注意的是,PCI桥也是PCI总线上的一个设备,在其配置空间中也有BAR寄存器,本节不对PCI桥BAR寄存器进行说明,因为在多数情况下透明桥并不使用其内部的BAR寄存器。下文以图3?2所示的处理器系统为例说明上述寄存器的初始化过程,该处理器系统使用的存储器域与PCI总线域的映射关系如图3?1所示。
在PCI设备的BAR寄存器中,包含该设备使用的PCI总线域的地址范围。在PCI设备的配置空间中共有6个BAR寄存器,因此一个PCI设备最多可以使用6组32位的PCI总线地址空间,或者3组64位的PCI总线地址空间。这些BAR空间可以保存PCI总线域的存储器地址空间或者I/O地址空间,目前多数PCI设备仅使用存储器地址空间。而在通常情况下,一个PCI设备使用2到3个BAR寄存器就足够了。
为简化起见,我们首先假定在图3?2中所示的PCI总线树中,所有PCI Agent设备只使用了BAR0寄存器,其申请的数据空间大小为16M字节(即0x1000000字节)而且不可预读,而且PCI桥不占用PCI总线地址空间,即PCI桥不含有BAR空间。并且假定当前HOST主桥已经完成了对PCI总线树的编号。
根据以上假设,系统软件该PCI总线树的遍历过程如下所示。
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
[1] HOST主桥下的第一个桥片是PCI桥片1,PCI桥片1下的第一个桥片是PCI桥片2,而PCI桥片2下的第一个桥片是PCI桥片3,因而第一组PCI设备为PCI总线3下的PCI设备。不同的系统软件查找第一组PCI设备的方法不同,Linux认为第一组PCI设备为PCI总线0下的PCI设备。
版权声明:本文为博主原创文章,未经博主允许不得转载。