请问PCIE设备自检表是一个个进行的还是同时进行的?

上篇文章主要从硬件的角度分析叻PCI设备的特性以及各种寄存器那么本节就结合LInux源代码分析下内核中PCI设备的各种数据结构以及相互之间的联系和工作机制


每个PCI总线都有一個pci_bus结构与之对应。

系统中所有的根总线的pci_bus结构通过node连接起来;

parent指向该总线的父总线即上一级总线;

children描述这条PCI总线的子总线链表的表头;

devices描述了这条PCI总线的逻辑设备链表的表头;

self指向引出这条PCI总线的桥设备的pci_dev结构;

ops指向一个结构描述访问配置空间的方法;

primary描述桥设备所在总线;

 PCI 总线上的每一个逻辑设备都会有一个这样的结构

 系统用resource结构管理地址空间资源,因为这里主要的目的是映射地址空间(PIO或者MMIO)到设备所以地址空间可以说是一种资源,每段地址空间用一个resource结构来描述该结构中有地址空间的起始和结束地址,name和一些位;系统维护了兩个全局的resource链表,一个用于管理IO端口空间一个用于管理IO内存空间。从resource结构可以看出这里是通过树来组织这些结构。这里有些类似于windows中虛拟内存管理方式通过这种方式可以比较高效的分配一段未使用的区间或者查找一段区间是否有重叠!

start指向区间的起点

flag记录区间的一些標志位


 额~~~仔细一数算,涉及到的结构还真不多那么就不在这耽搁时间了,看LInux内核中PCI设备探测和初始化的过程

PCI设备的探测有多种方式大體上分为BIOS探测和直接探测。直接探测又分为两种类型一般而言只要是采用PCI总线的PC机,其BIOS都必须提供对PCI总线的支持因而成为PCI BIOS。这种BIOS在机器加电之后的自检阶段会从系统中的第一个PCI桥即host-PCI 桥开始进行探测和扫描逐个的枚举连接在第一条PCI总线上的所有PCI设备并记录。如果其中有個设备是PCI-PCI桥则更进一步,在探测这个桥所连接总线上的设备依次递归,知道穷尽所有的PCI设备但是并不是所有的系统都有BIOS,后来LInux内核吔就提供了一种直接探测PCI设备的方式绕过了BIOS的探测。

PCI设备的初始化在内核中我们分为两个入口:

该函数完成的主要是与体系结构相关的函数中根据不同的探索方式有不同的选项,这里我们只关注CONFIG_PCI_DIRECT 可以看到这里仅仅是调用了一个pci_direct_probe函数

/*在IO地址空间从0xCF8开始申请八个字节用于鼡于配置PCI*/

该函数完成的功能比较简单,就是从IO地址空间申请8个字节用作访问PCI配置空间的IO端口0xCF8~0xCFF前四个字节做地址端口,后四个字节做数据端口

然后调用pci_check_type1函数进一步检查,这主要是对1型配置方式做检查:

这里代码只有短短几行但是着实不容易理解,首先向0xCFB写入了0x01,然后保存0xCF8 ㈣个字节的内容接着向地址端口0xCF8写入0x,然后读数据端口。回想下前面提到的PCI总线地址的格式最高位始终为1,那么这里就意味着要读0总线0設备0功能0寄存器的值但是下面貌似并没有读取数据端口,而是又读了下地址端口这我就不太明白了,难道这里只是检测下端口是否正瑺?

接着就继续调用了pci_sanity_check函数确保这种访问模式可以正确执行这里是测试HOST-bridge是否存在

该函数就比较短小了,在前面pci_direct_probe函数的时候已经返回1那么这里实际上就是设置raw_pci_ops=&pci_direct_config,从而设置正确的的读取PCI设备配置空间的方法到此为止,一阶段已经结束了看下面第二部分

在Pci_x86.c文件中,有这麼一段初始化的宏:

这里就是如果配置了ACPI的话就初始化成pci_acpi_init,否则就初始化成pci_legacy_init这里我们先只考虑没有配置ACPI的情况。

4 /*找到0号总线后后续僦比较容易了,这里直接遍历总线链表,若已经存在对应总线号的总线则说明已经探测到了,就直接返回*/ 11 /*否则还需要根据总线号寻找总线並返回*/

 其实这里关于sysdata的问题我也不是很清楚,貌似和CPU架构相关这里我们不重点考虑,后续晓得了 再补充我们可以看到这里调用了x86_pci_root_bus_resource函數给总线分配资源,这里需要说下就是一条总线上的设备的资源也是从总线的资源里面分配的就是我们所说的窗口,设备或者桥的窗口┅定是对应总线窗口的子窗口如果可能后面会专门拿出一节分析资源的分配。

/*这里判断是否已经分配了总线号资源*/ /*如果没有分配需要重噺分配*/ /*相当于向系统注册总线号资源*/ /*向系统注册地址空间资源*/

 这里首先判断总线的总线号资源分配情况因为总线号也是一种资源,且由於总线遍历是按照深度优先遍历一条总线上的所有子总线可以看成一棵树,并且这些总线号是连续的所以可以用区间来表示,这就和IO資源、MEM资源类似了所以这里总线号资源也是通过resource结构来表示的。一个host-bridge有一个全局的资源链表resources,连接了所有pci_host_bridge_window总线号资源、IO端口资源、IO内存資源在里面都有体现.为什么这么说呢?因为不论是那种资源都都会有一个pci_host_bridge_window与之对应,注意是一个区间就有一个pci_host_bridge_window结构我们还是看下这个結构:

 list使结构作为节点连接在resources链表中,res指向其所对应的resource而offset表示映射的偏移,该字段主要用在IO端口和IO内存和物理内存的映射总线号资源這里默认是0.

回到x86_pci_root_bus_resource函数中。之前咱们看到初始化的时候x86.init有可能被初始化成acpi_init,如果是这个那么资源很可能就分配好了所以这里判断下。如果没囿的话就调用pci_add_resource函数添加资源所完成的功能就是申请一个pci_host_bridge_window结构,指向对应的res结构挂入全局resource链表。函数内容我们就不看了要不就讲不完叻。

 接着就注册地址空间资源(IO端口和IO内存)这里基本分为两步:

1、创建对应的windows,并挂入链表

2、把res插入到全局的资源树中

第一步就不茬赘述,第二步其实就是从全局的资源中申请空间类似于windows中VAD树和LInux中的红黑树,但是又不同这里树的结构前面文章有提到,总之插入の后表明该段空间已经被占用,在次分配就不能分配和本段冲突

下面就该pci_scan_root_bus函数 ,这才是探测总线的重点!!

版权声明:author:alex wang copyright:本文版权归作者和CSDN共囿 转载:欢迎转载为了保存作者的创作热情,请按要求【转载】谢谢 要求:未经作者同意,请保留此段声明;在文章中给出原文连接;否则必究法律责任 /u/article/details/

最近楼主比较苦逼啊主管布置了一道访问pci的作业,这个作业使用io方式还可以非常浪地将所有的东西都给读取出来雖然不能读取出pci-e设备的所有信息,但是还是可以将256位的其他东西给读出来的

本文将先从io访问模式进行对pci访问的设置,在这里我所使用的包含了dos和linux这样可以看到这2个的系统代码的不同。

PCI总线是一种高性能32位或者64位的多路复用地址或者数据行的总线相当于现实生活中的公蕗,是所谓的信号通道可以在这上面传输数据、控制信号等等。

作用:高度集成外围控制其、外围插件和处理器/内存系统之间的互连机淛

如果要访问PCI 设备,首先要确定PCI设备在系统中的物理连接情况描述这个连接情况的数据是“总线号”、“设备号”和“功能号”。一個系统可以有256个PCI总线每个总线上可以有32个设备,每个设备可以具有8个功能(每个功能作为一个PCI设备)当这三个数据确定的时候,就可鉯在系统中唯一确定一个PCI 设备

8~10:功能位. 有时候,一个pci设备对应多个功能.将每个功能单元分离出来,对应一个独立的pci device
11~15位:设备号 对应该pci总线上的设備序号
16~23位:总线号 根总线的总线号为0.每遍历到下层总线,总线号+1

同样,SCSI和VIDEO同类型资源必须要是pci_bus1的子集.pci bus1上有一个pci桥,对应的资源也就是它所连桥上的资源.即pci_bus->self.也就是说,下层总线的资源是它上层总线资源的子集上层总线资源是下层总线资源的父集。

其实,每个PCI设备的资源地始哋址都是由操作系统设置的.在x86上,都由bios设置好了.

PCI配置空间是一块容量为256字节并具有特定记录结构或模型的地址空间通过配置空间,我们可以了解该PCI设备的一些配置情况进而控制该设备,除主总线桥以外的所有PCI设备都必须事先配置空间.

配置空间的前64个字节叫头标区头标区又分成两个部分,第一部分为前16个字节在各种类型的设备中定义都是一样的,其他字节随各设备支持的功能不同而有所不同位于偏移0EH的投标类型字段规定了是何种布局,目前有三种头标类型头标类型1用于PCI-PCI桥,头标类型2用于PCI-CARDBUS桥头标类型0用于其他PCI设备,下图为頭标类型0的头标区布局
头标区中有5个字段涉及设备的识别。

偏移:00H该字段用以标明设备的制造者。一个有效的供应商标识由PCI SIG来分配鉯保证它的唯一性。0FFFFH是该字段的无效值

偏移:02H。用以标明特定的设备具体代码由供应商来分配。

偏移:08H用来指定一个设备特有的版夲识别代码,其值由供应商提供可以是0。

偏移:0EH该字段有两个作用,一是用来表示配置空间头标区第二部分的布局类型;二是用以指萣设备是否包含多功能位7用来标识一个多功能设备,位7为0表明是单功能设备位7为1表明是多功能设备。位0-位6表明头标区类型

偏移:09H。標识设备的总体功能和特定的寄存器级编程接口该字节分三部分,每部分占一个字节第一部分是基本分类代码,位于偏移0BH第二部分叫子分类代码,位于偏移0AH处第三部分用于标识一个特定的寄存器级编程接口。

在dos下申请相关的接口就可以得到io口通过cf8和cfc的模式进行读取遍历pci设备。

在linux系统下就很简单了直接看代码吧!

今天暂时到这里,下一章将介绍什么是mmio如何实现的!欢迎关注!

如何检查华硕Z270-AR主板的M.2-1插口PCIE通道是否正常

我的华硕Z270-AR 主板的M.2-1插口原来使用的是三星SM951 SSD,突然在1插口不识别了,插在2口依然好使

但是,1插口可以识别闪迪SSD(SATA模式)说明主板M.2-1插口识別SATA插口不识别PCIE,请教如何检查1口PCIE模式

跑一下测速,看看是不是被锁在600MB/s以下就知道是不是走SATA通道了

插在M.2-1插口主板就识别不出来,插在2ロ就能正常使用速度是读1800,写1200

怎么还纠结这个呢?拿华硕维修一年包换!让华硕客服插pcie通道的ssd再看能不能认(别插sata通道的ssd固...

在网上淘宝买的,需要拆下来邮寄到深圳如果不是主板问题,就不用来回折腾了!我地华硕店没有SM9511SSD可实验的
2-1内部存储设置有三个,自动识别、PCIE、磁盘阵列三个选项我都试过了,就是不识别!
我就是升级BIOS0906以后发生的但是选项中仍有PCIE模式,我试过了不行。还有磁盘阵列 模式(升级前没有这个模式)
2-1接口有:自动识别、PCIE、SATA三种选择都试过了,那种模式也识别不出来951SSD.但是951插在M.2-2口仍然正常。在SATA设置里面有AHCI和inter RST两鍺选择我用的是AHCI.

仔细看看这里模式AHCI还是 有其它模式?

是的可是,更新之后还继续使用来着第二天 开机就出现找不到硬盘了。

目前你這里能做的:拔掉所有机械硬盘sata拔掉机箱上usb口磁盘,拔掉电源线清理主板cmos信息,插上m.2_1...

今天去华硕专卖店师傅判定是BIOS升级之后,不兼嫆问题我现在是升级到0906版本(文明用语最高版本),如何升级弄明白了但是,如何降低版本并不会操作(一旦弄不好,主板就废了)请指教!(我买主板时有光盘送主板驱动,如何重新刷不懂啊)

以前我做过清除COMS事情,没有解决现在2-1口插上其它SSD马上就识别了(SATAロ 模式),我地区整个市场也没有SM9551 SSDD无法用951PCIE测试(只要2-1口能识别出插入的M.2设备,就说明主板接口没有问题的只是不能识别SM951SSD,应该是兼容不兼容的问题)

跑一下测速,看看是不是被锁在600MB/s以下就知道是不是走SATA通道了

插在2-2口测试,读1700写1250,用3.0乘4选项鲁大师跑分45600.插在2-1口就检测不到此盘
在951插在2-2口情况下,2-1口再插闪迪、联想SSD都能检测到真奇怪了。

目前你这里能做的:拔掉所有机械硬盘sata拔掉机箱上usb口磁盘,拔掉电源线清理主板cmos信息,插上m.2_1...

BIOS刷回0701试过,不行把掉一切,扣2电池加电,再扣电池插951重启,2--1口就是不识别然后从2-1口拔下,插回2-2口竝即正常。

仔细看看这里模式AHCI还是 有其它模式

有两种,一是AHCI ,二是磁盘阵列选项我选的是AHCI

我要回帖

更多关于 由pcie设备唤醒 的文章

 

随机推荐