在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)      系统软件根据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遍历过程。




[1] HOST主桥下的第一个桥片是PCI桥片1,PCI桥片1下的第一个桥片是PCI桥片2,而PCI桥片2下的第一个桥片是PCI桥片3,因而第一组PCI设备为PCI总线3下的PCI设备。不同的系统软件查找第一组PCI设备的方法不同,Linux认为第一组PCI设备为PCI总线0下的PCI设备。

3.1 PCI设备BAR空间的初始化的更多相关文章

  1. 008 PCI设备BAR空间的初始化

    一.PCI设备BAR空间的初始化 在PCI Agent设备进行数据传送之前,系统软件需要初始化PCI Agent设备的BAR0~5寄存器和PCI桥的Base.Limit寄存器.系统软件使用DFS算法对 ...

  2. 2.3 PCI桥与PCI设备的配置空间

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

  3. linux PCI设备初始化过程

    linux PCI设备初始化过程 start_kernel->rest_init 这个函数会启动一个核心线程0, 核心线程然后调用init -> do_basic_setup. 然后我们开 ...

  4. 3.3.3 PCI设备对可Cache的存储器空间进行DMA读写

    PCI设备向"可Cache的存储器空间"进行读操作的过程相对简单.对于x86处理器或者PowerPC处理器,如果访问的数据在Cache中命中,CPU会通知FSB总线,PCI设备所访 ...

  5. 3.3.2 PCI设备对不可Cache的存储器空间进行DMA读写

    在x86处理器和PowerPC处理器中,PCI设备对"不可Cache的存储器空间"进行DMA读写的过程并不相同.其中PowerPC处理器对"不可Cache的存储器空间&q ...

  6. 3.2 PCI设备的数据传递

    PCI设备的数据传递使用地址译码方式,当一个存储器读写总线事务到达PCI总线时,在这条总线上的所有PCI设备将进行地址译码,如果当前总线事务使用的地址在某个PCI设备的BAR空间中时,该PCI设备将使 ...

  7. PCI 设备详解二

    上篇文章主要从硬件的角度分析了PCI设备的特性以及各种寄存器,那么本节就结合LInux源代码分析下内核中PCI设备的各种数据结构以及相互之间的联系和工作机制 2016-10-09 注:一下代码参考LI ...

  8. PCI 设备详解一

    2016-10-09 其实之前是简单学习过PCI设备的相关知识,但是总感觉 自己的理解很函数,很多东西说不清楚,正好今天接着写这篇文章自己重新梳理一下,文章想要分为三部分,首先介绍PCI设备硬件相关的 ...

  9. 【DPDK】谈谈DPDK如何实现bypass内核的原理 其一 PCI设备与UIO驱动

    [前言] 随着网络的高速发展,对网络的性能要求也越来越高,DPDK框架是目前的一种加速网络IO的解决方案之一,也是最为流行的一套方案.DPDK通过bypass内核协议栈与内核驱动,将驱动的工作从内核态 ...

随机推荐

  1. 跟我一起读postgresql源码(十五)——Executor(查询执行模块之——control节点(上))

    控制节点 控制节点用于完成一些特殊的流程执行方式.由于PostgreSQL为査询语句生成二叉树状的査询计划,其中大部分节点的执行过程需要两个以内的输入和一个输出.但有一些特殊的功能为了优化的需要,会含 ...

  2. win7:你需要来自Administrators的权限才能对此文件进行修改的一个文件

    win7:你需要来自Administrators的权限才能对此文件进行修改的一个文件 Posted on 2010-11-29 09:54 寒宵飞飞 阅读(36117) 评论(1) 编辑 收藏 新建一 ...

  3. BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]

    题意: 一个序列,求k个不相同的长度属于\([L,R]\)的区间使得和最大 前缀和,对于每个r找最小的a[l] 然后我yy了一个可持久化线段树做法...也许会T 实际上主席树就可以了,区间k小值 然后 ...

  4. 51Nod 1225 余数之和 [整除分块]

    1225 余数之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 F(n) = (n % 1) + (n % 2) + (n % 3) + ... ...

  5. firefox在引入vue.js后不支持e=e||window.event的解决办法

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. 关于在jsp中的路径问题

    前言: jsp作为javaweb开发中常见的视图技术,我们平时在开发项目使用的过程中,经常会导入一些静态资源,比如css\js\jpg.png等图片格式的文件,这些文件的路径成了问题,经常会出现索引不 ...

  7. 12小时格式Xcode的-在一个“TimePicker”24 NSDate的设置

    我正在使用的NSDate对象,和好了,我的iPhone与24小时格式,所以当我在测试我的应用程序,一切正常,但是,我的一个朋友试图在他的iPhone上的应用程序 CodeGo.net,但12小时格式, ...

  8. mac 查看某个文件夹下所有隐藏文件(夹)的大小

    du -d 1 -h 对应Linux的命令是: du -ah --max-depth=1

  9. 基于Parallax设计HTML视差效果

    年关将至,给大家拜年. 最近时间充裕了一点,给大家介绍一个比较有意思的控件:Parallax.它可以用来实现鼠标移动时,页面上的元素也做偏移的视差效果.在一些有表现层次,布局空旷的页面上,用来做Hea ...

  10. Yii的URL助手

    Url 帮助类 获得通用 URL 记住 URLs 检查相对 URLs Url 帮助类提供一系列的静态方法来帮助管理 URL. 获得通用 URL 有两种获取通用 URLS 的方法 :当前请求的 home ...