接前一篇文章:《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(11)
1.3.3 HOST处理器访问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总线域”的物理地址,而不是“存储器域”的物理地址。
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总线至关重要!
以上对PCI总线的存储器域I/O总线事务的介绍并没有考虑PCI桥的存在,如果将PCI桥考虑进来,情况将略微复杂。下面仍以图1-1为例说明处理器如何通过HOST主桥和PCI桥x1对PCI设备进行存储器读写操作。
当处理器对PCI设备11进行存储器写操作时,这些数据需要通过HOST主桥x和PCI桥x1,最终到达PCI设备11。其访问步骤如下(注意,以下步骤忽略PCI总线仲裁过程):
(0)首先,处理器将要传递的数据放入通用寄存器中;
(1)之后,处理器向PCI设备11映射到的存储器域的地址进行写操作。值得注意的是,处理器并不能直接访问PCI设备11的PCI总线地址空间,因为这些地址空间是属于PCI总线域的,处理器所能直接访问的空间是存储器域的地址空间。处理器必须通过HOST主桥将存储器域的数据访问转换为PCI总线事务,才能对PCI总线地址空间进行访问。
(2)HOST主桥x接收来自处理器的存储器写请求,之后处理器结束当前存储器写操作,释放系统总线。HOST主桥x将存储器的存储地址转换为PCI总线域的PCI总线地址,并向PCI总线x0发起PCI写请求总线事务。值得注意的是,虽然在许多处理器系统中,存储器地址和PCI地址完全相等,但其含义并不相同。
(3)PCI总线x0上的PCI设备01、PCI设备02和PCI桥1将同时监听这个PCI写总线事务。最后,PCI桥x1接收这个写总线事务,并结束来自PCI总线x0的PCI总线事务。之后,PCI桥x1向PCI总线x1发起新的PCI总线写总线事务。
(4)PCI总线x1上的PCI设备11和PCI设备12同时监听这个写总线事务。最后,PCI设备11通过地址译码方式接收这个写总线事务,并结束来自PCI总线x1上的PCI总线事务。
由以上过程可以发现,由于存储器写总线事务使用Posted传送方式,因此数据通过PCI桥后都将结束上一级总线的PCI事务,从而上一级PCI总线可以被其它PCI设备使用。如果使用Non-Posted传送方式,直到数据发送到PCI设备11之后,PCI总线x1和x0才能依次释放,从而在某种程度上将造成PCI总线的拥塞。
本节内容较长,为了便于理解和消化,后一半内容放到下一回中。