PCIe 基础(一)操作配置空间

PCI配置空间

PCI有三种地址空间:I/O空间,内存地址空间,PCI配置空间。在启动时bootloader

或者内核会遍历PCI总线并分配资源,如中断和内存,设备驱动程序通过PCI配置空间

找到资源分配。大小为256字节。

配置空间图:

(1) Device ID和Vendor ID寄存器

这两个寄存器的值由PCISIG分配,只读。其中Vendor ID代表PCI设备的生产厂商,

而Device ID代表这个厂商所生产的具体设备。如Intel公司的基于82571EB芯片的

系列网卡,其Vendor ID为0x8086[1],而Device ID为0x105E[2]。

(2) Revision ID和Class Code寄存器

这两个寄存器只读。其中Revision ID寄存器记载PCI设备的版本号。该寄存器可以

被认为是Device ID寄存器的扩展。

(3) Header Type寄存器

该寄存器只读,由8位组成。第7位为1表示当前PCI设备是多功能设备,为0表示为

单功能设备。第6~0位表示当前配置空间的类型,为0表示该设备使用PCI Agent设

备的配置空间,普通PCI设备都使用这种配置头;为1表示使用PCI桥的配置空间,

PCI桥使用这种配置头;为2表示使用Cardbus桥片的配置空间,Card Bus桥片使用

这种配置头,本篇对这类配置头不感兴趣。系统软件需要使用该寄存器区分不同类

型的PCI配置空间,该寄存器的初始化必须与PCI设备的实际情况对应,而且必须为

一个合法值。

(4) Subsystem ID和Subsystem Vendor ID寄存器

这两个寄存器和Device ID和Vendor ID类似,也是记录PCI设备的生产厂商和设备

名称。但是这两个寄存器和Device ID与Vendor ID寄存器略有不同。下文以一个

实例说明Subsystem ID和Subsystem Vendor ID的用途。Xilinx公司在FGPA中

集成了一个PCIe总线接口的IP核,即LogiCORE。用户可以使用LogiCORE设计各

种各样基于PCIe总线的设备,但是这些设备的Device ID都是0x10EE,而Vendor

ID为0x0007[3]。

(6) Expansion ROM base address寄存器

有些PCI设备在处理器还没有运行操作系统之前,就需要完成基本的初始化设置,

比如显卡、键盘和硬盘等设备。为了实现这个“预先执行”功能,PCI设备需要

提供一段ROM程序,而处理器在初始化过程中将运行这段ROM程序,初始化这

些PCI设备。Expansion ROM base address记载这段ROM程序的基地址。

(7) Capabilities Pointer寄存器

在PCI设备中,该寄存器是可选的,但是在PCI-X和PCIe设备中必须支持这个寄

存器,Capabilities Pointer寄存器存放Capabilities寄存器组的基地址,PCI设

备使用Capabilities寄存器组存放一些与PCI设备相关的扩展配置信息。

(8) Interrupt Line寄存器

这个寄存器是系统软件对PCI设备进行配置时写入的,该寄存器记录当前PCI设备

使用的中断向量号,设备驱动程序可以通过这个寄存器,判断当前PCI设备使用处

理器系统中的哪个中断向量号,并将驱动程序的中断服务例程注册到操作系统中

[4]。该寄存器由系统软件初始化,其保存的值与8259A中断控制器相关,该寄存

器的值也是由PCI设备与8259A中断控制器的连接关系决定的。如果在一个处理器

系统中,没有使用8259A中断控制器管理PCI设备的中断,则该寄存器中的数据并

没有意义。在多数PowerPC处理器系统中,并不使用8259A中断控制器管理PCI设

备的中断请求,因此该寄存器没有意义。即使在x86处理器系统中,如果使用I/O

APIC中断控制器,该寄存器保存的内容仍然无效。目前在绝大多数处理器系统中,

并没有使用该寄存器存放PCI设备使用的中断向量号。

(9) Interrupt Pin寄存器

这个寄存器保存PCI设备使用的中断引脚,PCI总线提供了四个中断引脚INTA#、

INTB#、INTC#和INTD#。Interrupt Pin寄存器为1时表示使用INTA#引脚向中

断控制器提交中断请求,为2表示使用INTB#,为3表示使用INTC#,为4表示使

用INTD#。如果PCI设备只有一个子设备时,该设备只能使用INTA#;如果有多

个子设备时,可以使用INTB~D#信号。如果PCI设备不使用这些中断引脚,向处

理器提交中断请求时,该寄存器的值必须为0。值得注意的是,虽然在PCIe设备

中并不含有INTA~D#信号,但是依然可以使用该寄存器,因为PCIe设备可以使

用INTx中断消息,模拟PCI设备的INTA~D#信号,详见第6.3.4节。

(10) Base Address Register 0~5寄存器

该组寄存器简称为BAR寄存器,BAR寄存器保存PCI设备使用的地址空间的基地址,

该基地址保存的是该设备在PCI总线域中的地址。其中每一个设备最多可以有6个

基址空间,但多数设备不会使用这么多组地址空间。在PCI设备复位之后,该寄存

器将存放PCI设备需要使用的基址空间大小,这段空间是I/O空间还是存储器空间

[5],如果是存储器空间该空间是否可预取,系统软件对PCI总线进行配置时,首先

获得BAR寄存器中的初始化信息,之后根据处理器系统的配置,将合理的基地址写

入相应的BAR寄存器中。系统软件还可以使用该寄存器,获得PCI设备使用的BAR

空间的长度,其方法是向BAR寄存器写入0xFFFF-FFFF,之后再读取该寄存器。

处理器访问PCI设备的BAR空间时,需要使用BAR寄存器提供的基地址。值得注意

的是,处理器使用存储器域的地址,而BAR寄存器存放PCI总线域的地址。因此处

理器系统并不能直接使用“BAR寄存器+偏移”的方式访问PCI设备的寄存器空间,

而需要将PCI总线域的地址转换为存储器域的地址。如果x86处理器系统使能了

IOMMU后,这两个地址也并不一定相等,因此处理器系统直接使用这个PCI总线

域的物理地址,并不能确保访问PCI设备的BAR空间的正确性。除此之外在Linux

系统中,ioremap函数的输入参数为存储器域的物理地址,而不能使用

PCI总线域的物理地址。而在pci_devàresource[bar].start参数中保存的地址已经

经过PCI总线域到存储器域的地址转换,因此在编写Linux系统的设备驱动程序时,

需要使用pci_devàresource[bar].start参数中的物理地址,然后再经过ioremap

函数将物理地址转换为“存储器域”的虚拟地址。

(11) Command寄存器

该寄存器为PCI设备的命令寄存器,该寄存器在初始化时,其值为0,此时这个PCI

设备除了能够接收配置请求总线事务之外,不能接收任何存储器或者I/O请求。系

统软件需要合理设置该寄存器之后,才能访问该设备的存储器或者I/O空间。在

Linux系统中,设备驱动程序调用pci_enable_device函数,使能该寄存器的I/O和

Memory Space位之后,才能访问该设备的存储器或者I/O地址空间。

(12) Status寄存器

该寄存器的绝大多数位都是只读位,保存PCI设备的状态。

时间: 2024-08-09 02:09:05

PCIe 基础(一)操作配置空间的相关文章

如何访问pcie整个4k的配置空间

目前用于访问PCIe配置空间寄存器的方法需要追溯到原始的PCI规范.为了发起PCI总线配置周期,Intel实现的PCI规范使用IO空间的CF8h和CFCh来分别作为索引和数据寄存器,这种方法可以访问所有PCI设备的255 bytes配置寄存器.Intel Chipsets目前仍然支持这种访问PCI配置空间的方法. PCIe规范在PCI规范的基础上,将配置空间扩展到4K bytes,至于为什么扩展到4K,具体可以参考PCIe规范,这些功能都需要配置空间.原来的CF8/CFC方法仍然可以访问所有PC

怎样訪问pcie整个4k的配置空间

眼下用于訪问PCIe配置空间寄存器的方法须要追溯到原始的PCI规范. 为了发起PCI总线配置周期,Intel实现的PCI规范使用IO空间的CF8h和CFCh来分别作为索引和数据寄存器,这样的方法能够訪问全部PCI设备的255 bytes配置寄存器.Intel Chipsets眼下仍然支持这样的訪问PCI配置空间的方法. PCIe规范在PCI规范的基础上,将配置空间扩展到4K bytes,至于为什么扩展到4K,详细能够參考PCIe规范,这些功能都须要配置空间.原来的CF8/CFC方法仍然能够訪问全

PCI、PCIE配置空间的訪问(MCFG,Bus,Device,Funtion)

一般来说,在x86平台上,有两大类方式能够訪问这一区间的寄存器, 1,配置机制1#或者配置机制2# 訪问时借助in/out指令.请注意,这样的方式有别于一般的in/out指令訪问PCI的IO空间,它引入了地址port和数据port. 配置机制2#仅仅在某些特定的主板上被使用. 新的设计应使用配置机制1#来产生配置空间的物理操作.这样的机制使用了两个特定的32位I/O空间,即CF8h和CFCh.这两个空间相应于PCI桥路的两个寄存器,当桥路看到CPU在局部总线对这两个I/O空间进行双字操作时,就将

PCI、PCIE配置空间的访问(MCFG,Bus,Device,Funtion)

一般来说,在x86平台上,有两大类方式可以访问这一区间的寄存器, 1,配置机制1#或者配置机制2# 访问时借助in/out指令.请注意,这种方式有别于一般的in/out指令访问PCI的IO空间,它引入了地址端口和数据端口. 配置机制2#只在某些特定的主板上被使用. 新的设计应使用配置机制1#来产生配置空间的物理操作.这种机制使用了两个特定的32位I/O空间,即CF8h和CFCh.这两个空间对应于PCI桥路的两个寄存器,当桥路看到CPU在局部总线对这两个I/O空间进行双字操作时,就将该I/O操作转

【PCIE-2】---PCIE配置空间及访问方式简介

对新手来说,第一步了解PCIE的相关基本概念,第二步了解PCIE配置空间,第三步深入研究PCIE设备枚举方式.本章主要总结第二步的PCIE配置空间 按照国际惯例,先提问题: 1. 什么是PCIE的配置空间? 2. PCIE设备的配置空间有多大?     PCI和PCIE的配置空间有何区别与联系? 3. 如何访问PCIE设备的配置空间? 4. 有几种类型,都包含什么内容? 带着上述问题,来进行该部分的总结: 什么是PCIE的配置空间? 每个PCIE设备都有自己的独立的一段配置空间,该部分空间是这个

ASP.NET三层架构基础详细操作图文教程(转)

本文主要讲述Asp.net B/S结构 下基础的三层架构项目.三层主要是指的界面UI层,逻辑层,数据层.界面UI层:用于用户观看,体验的表示层.逻辑层:程序运行逻辑的封装层.数据层:程序数据相关操作的封装层. 每层当中还可以进行不同的详细划分,因为是基础教程,先领新手入门,所以不进行复杂的讲解.本来出自http://www.cnntec.com 作者:A.Z猫 转载请注明,违者必究.准备工具:Microsoft Visual Studio 2008 以下简称vs08Microsoft SQLSe

wdmWin10下遍历PCI配置空间

图右边是引用驱动开发技术详解书中的代码:3环只增加了个死循环 驱动没变 #include <windows.h> #include <stdio.h> //使用CTL_CODE必须加入winioctl.h #include <winioctl.h> #include "Ioctls.h" DWORD In_32(HANDLE hDevice, USHORT port) { DWORD dwOutput; DWORD inputBuffer[2] =

Oracle基础-Listner的配置

1.静态配置 oracle早就支持动态的listener了,但是在使用OEM(Oracle Enterprise Manager)等高级货时还是需要用到静态配置 工具:netca+netmgr(或者直接修改/network/admin下面的listener.ora,假如这个文件木有,可以开netca配置一下得到一个简单的) ps.意味着通过这些工具我可以配置n个linstener,通过命令 lsnrctl  LISTENERnn start就可以启动了(当然前提是这些listener对应的端口都

从0开始,一起搭框架、做项目(3)公共基础数据操作类 RepositoryBase

索引 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目 目录索引 简述 今天我们写一个基础数据的操作类,如果里面有大家不理解的地方,可采取两种方式,第一:提出来,第二:会用就行.这个类呢我一般不去修改它,因为基础操作类,大家也可以直接拷贝到自己的项目中. 项目准备 我们用的工具是:VS 2013 + SqlServer 2012 + IIS7.5 希望大家对ASP.NET MVC有一个初步的理解,理论性的东西我们不做过多解释,有些地方不理解也没关系,会用就行了,用的多