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设备访问。
由上所述,在一个处理器系统中,并不是所有存储器空间都可以被PCI设备访问,只有在PCI总线域中有映像的存储器空间才能被PCI设备访问。经过HOST主桥映射的存储器,具有两个“地址”,一个是在存储器域的地址,一个是在PCI总线域的PCI总线地址。当处理器访问这段存储器空间时,使用存储器地址;而PCI设备访问这段内存时,使用PCI总线地址。在多数处理器系统中,存储器地址与PCI总线地址相同,但是系统程序员需要正确理解这两个地址的区别。
下文以PCI设备11向主存储器写数据为例,说明PCI设备如何进行DMA写操作。
(1) 首先PCI设备11将存储器写请求发向PCI总线x1,注意这个写请求使用的地址是PCI总线域的地址。
(2) PCI总 线x1上的所有设备监听这个请求,因为PCI设备11是向处理器的存储器写数据,所以PCI总线x1上的PCI Agent设备都不会接收这个数据请求。
(3) PCI桥x1发现当前总线事务使用的PCI总线地址不是其下游设备使用的PCI总线地址,则接收这个数据请求,有关PCI桥的Secondary总线接收数据的过程见第3.2.1节。此时PCI桥x1将结束来自PCI设备11的Posted存储器写请求,并将这个数据请求推到上游PCI总线上,即PCI总线x0上。
(4) PCI总线x0上的所有PCI设备包括HOST主桥将监听这个请求。PCI总线x0上的PCI Agent设备也不会接收这个数据请求,此时这个数据请求将由HOST主桥x接收,并结束PCI桥x1的Posted存储器写请求。
(5) HOST主桥x发现这个数据请求发向存储器,则将来自PCI总线x0的PCI总线地址转换为存储器地址,之后通过存储器控制器将数据写入存储器,完成PCI设备的DMA写操作。
PCI设备进行DMA读过程与DMA写过程较为类似。不过PCI总线的存储器读总线事务只能使用Non-Posted总线事务,其过程如下。
(1) 首先PCI设备11将存储器读请求发向PCI总线x1。
(2) PCI总线x1上的所有设备监听这个请求,因为PCI设备11是从存储器中读取数据,所以PCI总线x1上的设备,如PCI设备12,不会接收这个数据请求。PCI桥x1发现下游PCI总线没有设备接收这个数据请求,则接收这个数据请求,并将这个数据请求推到上游PCI总线上,即PCI总线x0上。
(3) PCI总线x0上的设备将监听这个请求。PCI总线x0上的设备也不会接收这个数据请求,最后这个数据请求将由HOST主桥x接收。
(4) HOST主桥x发现这个数据请求是发向主存储器,则将来自PCI总线x0的PCI总线地址转换为存储器地址,之后通过存储器控制器将数据读出,并转发到HOST主桥x。
(5) 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读取数据的过程。
(1) 首先PCI设备11将PCI写总线事务发向PCI总线x1上。PCI桥x1和PCI设备12同时监听这个写总线事务。
(2) PCI桥x1将接收这个PCI写请求总线事务,并将这个PCI写总线事务上推到PCI总线x0。
(3) PCI总线x0上的所有设备将监听这个PCI写总线事务,最后由PCI设备01接收这个数据请求,并完成PCI写事务。