初始化PCI设备的BAR(Base Address Register)寄存器和PCI桥的Base、Limit寄存器是配置PCI总线地址空间的关键步骤,这些寄存器的设置影响了系统中PCI设备和桥接器对地址空间的使用和访问。下面详细解释它们的初始化过程:
PCI设备的BAR寄存器初始化
-
BAR寄存器概述:
- PCI设备的BAR寄存器用于指定该设备在PCI总线地址空间中所需的基地址和大小。
- 每个PCI设备最多有6个BAR寄存器,编号从0到5。
- BAR寄存器的值分为两部分:地址和控制位。地址部分指示PCI设备在PCI总线地址空间中的基地址,控制位则指定地址空间的类型(内存空间、I/O空间等)和大小。
-
BAR寄存器初始化步骤:
- 确定地址空间类型:首先需要确定每个BAR寄存器所描述的地址空间类型,如内存空间还是I/O空间。
- 分配地址空间:系统软件根据PCI设备的需求和系统中可用的PCI总线地址空间,为每个BAR寄存器分配合适的基地址。
- 设置BAR寄存器值:将计算得到的基地址和控制位写入到相应的BAR寄存器中。
PCI桥的Base和Limit寄存器初始化
-
Base和Limit寄存器概述:
- PCI桥的Base寄存器指定其下所有PCI设备在PCI总线地址空间中的基地址。
- PCI桥的Limit寄存器指定其下所有PCI设备在PCI总线地址空间中可以使用的地址范围的大小。
-
Base和Limit寄存器初始化步骤:
- 计算PCI总线地址空间需求:系统软件根据其下所有PCI设备的BAR寄存器需求,计算出需要分配的基地址和地址空间大小。
- 分配基地址:为PCI桥的Base寄存器分配一个合适的基地址,通常是相对于整个PCI总线树的起始地址。
- 设置Limit寄存器:根据计算得到的地址空间大小,将其写入到PCI桥的Limit寄存器中,限定其下所有PCI设备可以使用的地址范围。
具体操作示例
假设在一个PCI总线树中,按照DFS算法遍历并初始化各个PCI设备和PCI桥的BAR寄存器、Base和Limit寄存器的过程如下:
-
PCI设备的BAR寄存器初始化:
- 确定每个PCI设备的地址空间类型(内存空间或I/O空间)。
- 根据系统分配的PCI总线地址空间,为每个PCI设备的BAR寄存器分配基地址。
- 将计算得到的基地址和控制位写入到各个BAR寄存器中。
-
PCI桥的Base和Limit寄存器初始化:
- 确定PCI桥所在的PCI总线地址空间范围。
- 根据其下所有PCI设备的BAR寄存器需求,计算出合适的基地址和地址空间大小。
- 将计算得到的基地址写入到PCI桥的Base寄存器中。
- 将计算得到的地址空间大小写入到PCI桥的Limit寄存器中。
这样,通过初始化BAR寄存器和Base、Limit寄存器,系统确保了每个PCI设备和PCI桥能够正确地访问PCI总线地址空间,避免了地址冲突和资源竞争问题,保证了整个PCI系统的稳定性和可靠性。
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) 系统软件根据DFS算法,系统软件率先寻找到第一组PCI设备,分别为PCI设备31和PCI设备32[1],并根据这两个PCI设备需要的PCI空间大小,从PCI总线地址空间中(0x7000-0000~0x77FF-FFFF)为这两个PCI设备的BAR0寄存器分配基地址,分别为0x7000-0000和0x7100-0000。
(2) 当系统软件完成PCI总线3下所有设备的BAR空间的分配后,将初始化PCI桥3的配置空间。这个桥片的Memory Base寄存器保存其下所有PCI设备使用的"PCI总线域地址空间的基地址",而Memory Limit寄存器保存其下PCI设备使用的"PCI总线域地址空间的大小"。系统软件将Memory Base寄存器赋值为0x7000-0000,而将Memory Limit寄存器赋值为0x200-0000。
(3) 系统软件回朔到PCI总线2,并找到PCI总线2上的PCI设备21,并将PCI设备21的BAR0寄存器赋值为0x7200-0000。
(4) 完成PCI总线2的遍历后,系统软件初始化PCI桥2的配置寄存器,将Memory Base寄存器赋值为0x7000-0000,Memory Limit寄存器赋值为0x300-0000。
(5) 系统软件回朔到PCI总线1,并找到PCI设备11,并将这个设备的BAR0寄存器赋值为0x7300-0000。并将PCI桥1的Memory Base寄存器赋值为0x7000-0000,Memory Limit寄存器赋值为0x400-0000。
(6) 系统软件回朔到PCI总线0,并在这条总线上发现另外一个PCI桥,即PCI桥4。并使用DFS算法继续遍历PCI桥4。首先系统软件将遍历PCI总线4,并发现PCI设备41和PCI设备42,并将这两个PCI设备的BAR0寄存器分别赋值为0x7400-0000和0x7500-0000。
(7) 系统软件初始化PCI桥4的配置寄存器,将Memory Base寄存器赋值为0x7400-0000,Memory Limit寄存器赋值为0x200-0000。系统软件再次回到PCI总线0,这一次系统软件没有发现新的PCI桥,于是将初始化这条总线上的所有PCI设备。
(8) PCI总线0上只有一个PCI设备,PCI设备01。系统软件将这个设备的BAR0寄存器赋值为0x7600-0000,并结束整个DFS遍历过程。