初步了解完PCI总线标准之后,我们接下来正式开始PCIe设备的漫游之旅。从我们按下PC的电源按钮开始,BIOS就接管系统控制权开始工作,它会先进行一些内存和设备的初始化工作(当然,也包括我们的PCI设备),由于商业上的原因,Phoenix等厂商的BIOS代码需要授权协议,在此,我们以另外一个款开源BIOS(openbios)为例,来剖析BIOS中,我们的PCIe设备是如何被找到以及初始化的。

PCI设备的扫描是基于深度优先搜索算法(DFS:Depth First Search),也就是说,下级分支最多的PCI桥将最先完成其子设备的扫描。下面我们以图片来具体说明,BIOS是如何一步步完成PCI 设备扫描的。

第一步:

PCI Host 主桥扫描Bus 0上的设备(在一个处理器系统中,一般将与HOST主桥直接相连的PCI总线被命名为PCI Bus 0),系统首先会忽略Bus 0上的D1,D2等不会挂接PCI桥的设备,主桥发现Bridge 1后,将Bridge1 下面的PCI Bus定为 Bus 1,系统将初始化Bridge 1的配置空间,并将该桥的Primary Bus Number 和 Secondary Bus Number寄存器分别设置成0和1,以表明Bridge1 的上游总线是0,下游总线是1,由于还无法确定Bridge1下挂载设备的具体情况,系统先暂时将Subordinate
Bus Number设为0xFF。如下图所示:

第二步:

系统开始扫描Bus 1,将会发现Bridge 2。系统将Bridge 2下面的PCI Bus定为Bus 2,并将该桥的Primary Bus Number 和 Secondary Bus Number寄存器分别设置成1和2,和上一步一样暂时把Bridge 2 的Subordinate Bus Number设为0xFF。如下图所示:

第三步:

系统继续扫描Bus 2,将会发现Bridge 4。系统将Bridge 4下面的PCI Bus定为Bus 3,并将该桥的Primary Bus Number 和 Secondary Bus Number寄存器分别设置成2和3,此后

系统继续扫描后发现Bus 3 下面已经没有任何Bridge了,意味着该PCI总线下已经没有任何挂载下游总线了,因此Bridge 4的Subordinate Bus Number的值已经可以确定为3了。

如下图所示:

第四步:

完成Bus 3的扫描后,系统返回到Bus 2继续扫描,发现Bus 2下面已经没有其他Bridge了。此时Bridge 2的Subordinate Bus Number的值也已经可以确定为3了。如下图所示:

第五步:

完成Bus 2的扫描后,系统返回到Bus1继续扫描,会发现Bridge 3,系统将Bridge 3下面的PCI Bus定为Bus 4。并将Bridge 4的Primary Bus Number 和 Secondary Bus Number寄存器分别设置成1和4,此后系统继续扫描后发现Bus 4 下面已经没有任何Bridge了,意味着该PCI总线下已经没有挂载任何下游总线了,因此Bridge 3 的Subordinate Bus Number的值已经可以确定为4了。如下图所示:

第六步:

完成Bus 4的扫描后,系统返回到Bus 1继续扫描, 发现Bus 1下面已经没有其他Bridge了。此时Bridge 1的Subordinate Bus Number的值已经可以确定为4,系统返回Bus 0继续扫描(Bus 0下如果有其他它Bridge,将重复上述的步骤进行扫描)。至此,本例中的整个PCI的设备扫描已经完成了。最终的设备和总线的扫描结果如下图所示。

了解了上面PCI设备扫描的大概流程,我们接下来看看Bios代码中具体是如何实现这些扫描的。

一般来说,我们可以通过两个寄存器来访问PCI的配置空间(寄存器CONFIG_ADDRESS与CONFIG_DATA),在x86体系下,这两个寄存器分别对应0xCF8和0xCFC端口,对配置空间的访问都是通过对这两个寄存器的读写来实现先。CONFIG_ADDRESS寄存器的具体位组成如下图所示:

Bus Number : 总线号(8 bit),范围0--255。

Device Number: 设备号(5 bit),范围0--31。

Function Number: 功能号(3 bit),范围0--7。

Register Number: 寄存器号(6 bit),范围0--63 (配置空间一共256个字节,分割成64个4字节的寄存器,从0--63编号)。

每个PCI设备可根据上图所示的四个信息:Bus Number, Device Number, Function Number,Register
Number 来进行具体设备的定位并对其配置空间访问。当我们要访问PCI设备的配置空间时,先根据以上格式设置CONFIG_ADDRESS寄存器,然后再读取CONFIG_DATA寄存器即可得到相应的配置空间寄存器的值。

因此,BIOS中PCI配置空间的读写可以封装成下面的函数:

【DSP开发】【VS开发】PCIE设备扫描过程的更多相关文章

  1. 【PCIE-3】---PCIE设备的枚举扫描(经典好文)

    前面两个小节大致总结了下PCIE的基本知识,算是扫盲篇吧.本文主要总结PCIE设备的枚举扫描过程,此部分才是PCIE模块的重点,无论是在BIOS下还是系统驱动下都会用到. 按照国际惯例,先列问题: 1 ...

  2. Win10 IoT C#开发 6 - 4x4矩阵键盘扫描

    Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我 ...

  3. XE5应用开发支持的安卓设备

    XE5应用开发支持的安卓设备 A.官方文档声明 RADStudio 支持Android设备的应用开发,android版本从2.3到4.3.x,ARMv7处理器,MEON支持.根据Embarcadero ...

  4. HTML5移动应用开发入门经典 中文pdf扫描版

    HTML5是关注度ZUI高的前沿Web技术,而移动互联网则是近两年ZUI炙手可热的Web领域.<HTML5移动应用开发入门经典>将这两者巧妙结合起来,详细讲解了如何利用HTML5进行移动应 ...

  5. HTML5游戏开发进阶指南 中文pdf扫描版​

    HTML5游戏开发进阶指南介绍了HTML5游戏开发的一般过程和技巧.全书共分12章,第1章介绍了本书相关的HTML5的诸多新特性,包括在canvas上绘图.播放声音等,另外还引入了子画面页的概念:第2 ...

  6. 浅尝Spring注解开发_Bean生命周期及执行过程

    Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含Bean生命周期.自定义初始化方法.Debug BeanPostProcessor执行过程及在Spring底层中的应 ...

  7. XE7 & IOS开发之开发账号(3):证书、AppID、设备、授权profile的申请使用,附Debug真机调试、Ad hoc下iPA文件生成演示(XCode5或以上版本推荐,有图有真相)

    网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 注意,以下讨论都是以&q ...

  8. XE7 & IOS开发之开发账号(1):开发证书、AppID、设备、开发授权profile的申请使用,附Debug真机调试演示(XCode所有版本通用,有图有真相)

    网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 注意,以下讨论都是以&q ...

  9. AllJoyn+Android开发案例-android跨设备调用方法

    AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...

随机推荐

  1. Remote API(RAPI)之 文件管理

    RAPI库由一组函数组成,这些函数可用于通过桌面应用程序管理设备,包括设备的目录文件.设备的注册表和系统信息. RAPI提供了一组文件管理方法 CeCopyFile:复制文件 CeCreateDire ...

  2. 35. ClustrixDB 减少device1大小

    ClustrixDB中的device1文件用于所有数据库数据.撤消日志.临时表.binlog和ClustrixDB系统对象.ClustrixDB确保device1文件在集群的所有节点上大小相同.一旦得 ...

  3. nginx负载均衡 页面缓存

    nginx的upstream目前支持4种方式的分配 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight 指定轮询几率,weight ...

  4. Mockito 2 关于打标(stubbing)

    请参考下面有关于打标的代码. //You can mock concrete classes, not just interfaces LinkedList mockedList = mock(Lin ...

  5. NOI2007 项链工厂

    题目链接:戳我 60pts 有一点容易写错的小细节: 比如说求全局的段数的时候,如果只有一种颜色,那么当左右端点相等时,就不要ans--了. 注意右端点小于左端点的情况. #include<io ...

  6. Java当中的集合框架

    Java当中的集合框架 01 在我们班里有50位同学,就有50位对象. // 简书作者:达叔小生 Student[] stus = new Student[20]; 结果来了一位插班生,该同学因为觉得 ...

  7. Catch That Cow (POJ - 3278)(简单BFS)

    转载请注明出处:https://blog.csdn.net/Mercury_Lc/article/details/82693928作者:Mercury_Lc 题目链接 题解:给你x.y,x可以加1.减 ...

  8. python数据分析-数据导入

    1.导入CSV格式数据 import pandas data = pandas.read_csv("C:\\Users\\zhaosai\\Desktop\\进击的DBA\\谁说菜鸟不会数据 ...

  9. hadoop yarn日志分离

    根据hdfs的auditlog以及fsimage分析,yarn的日志文件占用了10%-20%的rpc请求以及文件量,这对namenode的性能有比较大的影响,特别是当集群规模越来越大,会影响生产业务. ...

  10. java多线程编程详细总结

    一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般都更复 ...