简介

PCI/PCIe设备有自己的独立地址空间,这部分空间会映射到整个系统的地址空间。

映射地址在BIOS/UEFI下指定(如果有的话,对于使用非BIOS启动的OS,不清楚),它有两种类型,一种是MMIO,一种是IO。对于MMIO的访问,跟访问内存的方式一样,它从称为PCIEXBAR的基地址开始,有很大的一段空间,这个PCIEXBAR的值根据不同的平台可能不同,大致可能值有0xC0000000、0xE0000000等,关于这个值是怎么使用的后面的章节会讲到;对于IO,它是一种比较老的访问PCI/PCIe设备的方式,而且占有的空间相比MMIO非常小,好像只有64K的空间。

PCI/PCIe设备使用的空间也有两个部分,一部分称为配置空间(通过MMIO);另一部分通过配置空间的BAR寄存器指定,是设备实现功能所需要用到的地址空间(有MMIO也有IO, 不过IO用的比较少了)。

PCI/PCIe配置空间的访问方式

PCI/PCIe设备的配置空间通过PCIEXBAR加上设备的Bus、Device、Fun号的转换来得到,BDF到地址的转换关系如下:

/**

Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an

address that can be passed to the PCI Library functions.

@param Bus PCI Bus number. Range 0..255.

@param Device PCI Device number. Range 0..31.

@param Function PCI Function number. Range 0..7.

@param Register PCI Register number. Range 0..255 for PCI. Range 0..4095

for PCI Express.

@return The encoded PCI address.

**/

#define PCI_LIB_ADDRESS(Bus,Device,Function,Register) \

(((Register) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20))

其中的Register是具体要访问的寄存器。

这是最常用的一种方式,通过将B/D/F转换成MMIO的地址,之后就可以通过MMIO的方式来访问,下面是一个例子:

UINT8

EFIAPI

PciExpressRead8 (

IN UINTN Address

)

{

ASSERT_INVALID_PCI_ADDRESS (Address);

return MmioRead8 ((UINTN) GetPciExpressBaseAddress () + Address);

}

不过这里有个问题,通过PCI_LIB_ADDRESS得到的并不是实际的系统地址空间,它算是一个偏移,还需要加上一个基地址(就是这个通过函数GetPciExpressBaseAddress()得到的)。在UEFI中这个基地址被设置成一个PCD变量:PcdPciExpressBaseAddress。它的值根据不同平台可能会不同。

不过重点不是它的值,重点是如何设置这个值,因为只有设置了这个值才能使用上面说的方式来读写PCI/PCIe配置空间。

而PCIEXBAR也是要写到PCI设备的配置空间中的,它会被写到B0/D0/F0/R060h这个寄存器(不同平台可能不同)。

这里就遇到了一个问题,该通过什么方式来写这个值呢?

实际上,需要注意几点:

1. 上述提供的访问PCI/PCIe配置空间的方式是PCIe的方式;

2. 早期在没有PCIe的时候,要访问配置空间时,使用的是两个IO端口,CFCh和CF8h,通过往一个端口指定寄存器,另一个端口写值的方式为指定寄存器赋值。

所以我们要注意,有两个配置空间的方式:

1. 传统方式,写IO端口CFCh和CF8h。只能访问PCI/PCIe设备的开始256个字节(因为PCI设备的配置空间本来就只有256个字节);

2. PCIe的方式,就是上面提到的方式,它可以方位4K个字节的配置空间。

PCI配置空间

由于PCI/PCIe设备分为Bridge和Agent两种,所以配置空间也有两种类型:

其中Agent的配置空间类型称为Type 00h:

简单介绍其中的几个寄存器的意义:

Vendor ID,Device ID:标记了一个设备的生产厂商和具体的设备,比如Intel的设备Vendor ID通常是0x8086,Device ID就需要厂家自定义了,总之能够识别到具体是哪个设备就可以了。

Status:设备状态字,具体每个BIT的意义见下图:

Command:设备状态字:

Base Address Registers:决定PCI/PCIe设备空间映射到系统空间具体位置的寄存器,映射方式有两种,分别是IO和Memory映射:

处理器系统资源分为IO资源和MMIO资源两种,因此PCI/PCIe空间地址对应也有两种。

下面是Bridge的配置空间,它的类型被称为Type 01h:

Type 01h中也有Vendor ID,Device ID,Status,Command等寄存器。

另外需要注意的是这里的BAR计算得到的系统空间是该桥下挂的所有设备的系统空间的总和。

另外Subordinate Bus Number、Secondary Bus Number和Primary Bus Number,这些寄存器共同确定了该桥上行和下行的所有Bus号。

PCIe配置空间

PCIe是在PCI基础上发展的协议,PCIe也有上述的PCI配置空间,并且在此基础之上进行了扩展,其扩展形式是通过一种称为Capability的寄存器块来完成的。

PCI配置空间的大小是256个字节,即0x00~0xFF,而PCIe的配置空间扩大到了0x00~0xFFF,下图是具体的布局。

在原来的配置空间中,有一个寄存器指定了第一个Capability的位置,而第一个Capability又指定下一个Capability,构成了一串Capability,具体如下图所示:

各个不同的Capability的作用不同,且不同的设备有不同的Capability,在这里不一一介绍了。

其它说明

处理器系统中会为所有的PCI/PCIe设备留足足够的空间,但是几乎没有系统会满配,所以很多的配置空间实际上是空的,此时如果去访问,就会得到全FF,表示设备不存在。

下面是linux下访问PCI/PCIe配置空间的一个例子:

注:以上是一个Intel网卡的PCI/PCIe配置空间,这是虚拟机下的结果,真实机器上可能有所不同。

pci配置基地址_PCI/PCIe基础——配置空间相关推荐

  1. pci配置基地址_PCI配置空间简介

    配置空间 操作系统 PCI总线推出以来,以其独有的特性受到众多厂商的青睐,已经成为计算机扩展总线的主流.目前,国内的许多技术人员已经具备开发PCI总线接口设备的能力.但是PCI总线的编程技术,也就是对 ...

  2. SVN CentOS7 下配置svn的安装及基础配置介绍

    CentOS7 下配置svn的安装及基础配置介绍 by:授客 QQ:1033553122 目录 一.         实践环境... 1 二.         安装操作系统... 1 三.       ...

  3. STM32CUBEMX配置教程(一)基础配置

    STM32CUBEMX配置教程(一)基础配置 基于STM32H743VI 使用STM32CUBEMX两年了,始终觉得这个工具非常的方便,但因为不是经常使用,导致有些要点总是会有些遗忘,因此写下这一系列 ...

  4. CentOS7 下配置svn的安装及基础配置介绍

    一.         实践环境 二.         安装操作系统 三.         安装SVN 四.         基础配置 五.         启动SVN 六.         客户端访问 ...

  5. linux基础配置脚本,Linux中selinux基础配置教程详解

    selinux(Security-Enhanced Linux)安全增强型linux,是一个Linux内核模块,也是Linux的一个安全子系统. 三种模式: Enforcing:强制模式,在selin ...

  6. linux多网卡配置ip地址(linux一个网卡配置多个ip)

    Linux如何配置ip地址 1.打开Linux终端系统,然后在系统中输入如下代码. 2.然后开始填写ip地址.子网掩码.网关等命令代码,如图所示. 3.在终端填写完之后,进行保存然后退出. 4.接着把 ...

  7. Linux 配置网卡、主机名(基础配置、网卡会话配置、网卡绑定配置)

    目录 配置网卡基本信息 通过nmcli命令配置网卡 通过配置网卡文件配置网卡 通过nmtui命令配置网卡 通过nm-connection-editor命令配置网卡 网卡高级配置 配置网络会话 配置网卡 ...

  8. 网站怎么配置服务器地址,如何给网站配置服务器地址

    如何给网站配置服务器地址 内容精选 换一换 客户端IP指的是访问者(用户设备)的IP地址.在Web应用开发中,通常需要获取客户端真实的IP地址.例如,投票系统为了防止刷票,需要通过获取客户端真实IP地 ...

  9. ftp服务器防火墙配置文件,H3C SecPath系列防火墙 配置指导(V7)(E9524_E9333)-5W301_基础配置指导_FTP和TFTP配置-新华三集团-H3C...

    1.1  FTP简介 FTP(File Transfer Protocol,文件传输协议)用于在FTP服务器和FTP客户端之间传输文件,是IP网络上传输文件的通用协议. FTP协议使用TCP端口20和 ...

最新文章

  1. 一个完整的DS1302时钟在STM32上的应用实例
  2. Openshift 4.4 静态 IP 离线安装系列:准备离线资源
  3. libuv 原理_Nodejs的运行原理-libuv篇
  4. cesium 页面截图_Cesium开发入门篇 | 02Cesium开发环境搭建及第一个示例
  5. kubernetes视频教程笔记 (11)-pod容器生命周期、Init容器
  6. (转载)o(1), o(n), o(logn), o(nlogn) 时间复杂度
  7. Java实现一个简单的两人五子棋游戏(二) 画棋盘
  8. pcb地线应该不应该做成环路_电源PCB设计流程及要点全解析
  9. 实习生去公司都干些啥
  10. RPS基准点系统 2020
  11. gcd时间复杂度分析
  12. 基于以太坊的58同城 | DApp开发与应用案例
  13. matlab寻峰代码,寻峰的函数!! - 程序语言 - MATLAB/Mathematica - 小木虫论坛-学术科研互动平台...
  14. QEMU 7.1发布
  15. 迷茫的寻路人,未知领域的探索者~
  16. 【新特性速递】优化Shift/Ctrl行多选逻辑,和Windows的文件资源管理器保持一致!...
  17. 淘宝开放平台API族
  18. android电话录音(整理自网络)
  19. maven 实战经验
  20. 大话设计模型 Task03:工厂、制造、观察

热门文章

  1. 浅谈Android中的异步加载之ListView中图片的缓存及优化三
  2. 数学二、英语二、政治
  3. 基于飞浆ERNIE3.0百亿级大模型实现中文短文本分类任务
  4. Diagnosing OSGi uses conflicts
  5. PgSql时间格式转换
  6. Python列表/元组/字典/集合详解
  7. excel数据自动录入网页_Excel自动抓取网页数据,数据抓取一键搞定
  8. FigDraw 13. SCI 文章绘图之桑葚图及文章复现(Sankey)
  9. 八字易经算法之用JAVA实现硬币卜卦辅助工具
  10. 设置app icon角标