当前位置: 首页 > news >正文

【PCI】PCI入门介绍(包含部分PCIe讲解)

先解释一下寻址空间:
机器是32bit的话,意味着4G(2的32次方)寻址空间,内存条作为它的实际物理存储设备。大部分在跑内存程序运行,少部分用来存放其他东西。这是一个常见的4G寻址空间分布(不一定是从 0xC0000000后开始是其他,这只是一个典型分布案例)。而之后会提到的PCI的Memory-Mapping IO配置空间就是分布在0xF0000000之后(地址值大于等于0xF0000000)。

地址范围用途
0x00000000–0xBFFFFFFF可用内存(最多 3GB)
0xC0000000–0xFFFFFFFFMemory-Mapping IO、显存、BIOS 映射等

仅作为bios里需要了解到的PCI知识介绍,不怎么涉及硬件知识,分为4个部分讲:
1.PCI介绍
2.PCI IRQ routing table(Legacy的东西,可不看)
3.PCI config space配置空间
4.如何识别PCIe设备

文章目录

  • 1. PCI介绍
    • 1.1 PCI总线(PCI bus)历史
    • 1.2 PCI总线优点
    • 1.3 PCI结构图
    • 1.4 PCI Bus/Device/Function
    • 1.5 PCI拓扑
    • 1.6 PCI总线信号
    • 1.7 PCI Bridge/PCI device配置空间
  • 2. PCI IRQ routing table(Legacy的东西,可不看)
  • 3. 如何访问PCI config space配置空间
    • 3.1 IO Port(仅用于x86平台,且读写的是Offeset FFh以内的信息)
    • 3.2 MMIO(推荐)
  • 4. 如何识别PCI-e设备

1. PCI介绍

1.1 PCI总线(PCI bus)历史

PCI全称Peripheral Component Interconnect外围部件互连
PCI总线是由ISA(Industy Standard Architecture)总线发展而来的,ISA总线由于CPU资源占用太高,数据传输带宽太小,作为插槽接口已经被淘汰。1992年Intel提出PCI总线,用来连接CPU和外围设备的局部总线,解决了CPU和外围设备尤其是显卡的数据瓶颈(在此之前MCA设备也挺慢,就比ISA好一点)。

PCI规范已经到7.0了,详情可以去官网上看。

1.2 PCI总线优点

高性能,32位同步复用总线,工作频率为33MHz;
线路简化,最少只需47个引脚;
可扩展,通过PCI bridge;
动态配置,init的时候有枚举过程;
中断可共享;
使用方便。

1.3 PCI结构图

在这里插入图片描述
Processer和Cache可以整体看做CPU。
Bridge/memory controller这里看做北桥南桥芯片集合,北桥接内存DRAM,南桥接PCI。
(注意,南桥/主芯片组会对不同类型的设备进行桥接和抽象,使得操作系统可以用统一的方式访问不同总线的设备。即使是PCI发展出的PCIe设备直接连接到CPU,硬件和芯片组也会提供一致的配置空间访问手段。一块板上的PCIe设备不一定只能连接到南桥或只连接到CPU,而是取决于主板设计、芯片组支持和设备类型。不再细讲。)
Bus上连各种PCI设备(图里的是举例,并不是真的都连在Bus0上,Bus0是初始的PCI总线,它上面有PCI设备也有PCI桥,PCI桥一对一连到另外的PCI bus,PCI bus上再接设备或PCI桥,终点是PCI bus。PCI bus号是深度优先来算的,并不是Bus0通过直连bridge后的bus就是bus1,bus2…,后面讲):
比如Audio音频设备,Motion Video视频设备,LAN(实际上是PCI网卡),SCSI(SCSI PCI转换卡,用来接SCSI标准的硬盘/光驱等存储设备),Graphics显卡。

1.4 PCI Bus/Device/Function

这三个是PCI信息读取的重要参数。
Bus:总线号,表示一个PCI设备/PCI桥挂在哪个Bus底下(PCI桥连接上游[数字小的那个,也就是靠Bus0较近的那个]一个bus、下游一个bus,它的bus号是她的上游总线号)。
Host桥(可以看做一个抽象概念,就是连到CPU的东西)引出Bus0,Bus0可以接多个PCI桥(PCI桥只能上游一个bus下游一个bus),PCI桥引出下一级Bus总线。最多可以有256个总线=2的8次方。

非总线0上的设备的bus号由引出该总线的PCI桥的配置空间的offset 19H那一字节代表的
secondary bus number给出。
(之后可以看PCI桥配置空间表格)

Device号:PCI的设备号。一个Bus最多可以接32个Device=2的8次方。
由PCI设备IDSEL引脚所连接的地址线决定。
Function:PCI的功能号,有PCI设备自身决定。PCI桥和设备都可以有多个功能。一个Device最多可以有8个Function=2的3次方。

1.5 PCI拓扑

自己画的,比网上某些清楚多了(。)
可以看到Host Bridge引出Bus 0,Bus 0引出PCI桥进行拓扑,PCI设备挂在PCI Bus上。
在这里插入图片描述

1.6 PCI总线信号

物理电器上的Pin脚(对应实际设备上的金手指)
在这里插入图片描述

左边是必要的pin脚,右边是可选的(64bit的PCI设备卡长度更长,插槽也更长,因为金手指变多)。
图是这样画的,实际上一个Pin脚就是设备某一侧的金手指,设备两侧加起来一共有最少47个金手指。当然设备也可以设计更多金手指,实际使用数量<=提供的数量。
如果是master device的话,就需要REQ和GNT那两个引脚,需要49Pin。所以说32bit PCI最少只需要47Pin。
注意interrupts,中断INT,之后会讲。

(#代表低电平有效,也可以写成字母上面有一道横线)
AD[31:0], 地址线和数据线是复用的。
C/BE[3:0]#,命令和字节使能。
PME#, 电源管理事件。
CLK, 时钟信号,给所有PCI设备提供时钟。
RST#, 复位信号,低电平时有效,会将PCI设备重置为初始状态。
INTA#-INTD#, 中断请求信号。
IDSEL, SEL是select的意思,初始化信号设备选择信号。访问一个设备配置寄存器时作为一个片选信号,决定该设备的设备号。
在这里插入图片描述
每个Bus的PCI device之所以最多32个,是因为AD从0到31。
每个PCI插槽上PCI设备的IDSEL引脚被主板硬件连接到某一根AD线(比如AD18)。
当主机发起配置访问时,它会在地址总线上输出一个地址,其中某一位(比如 AD18)被置为高电平。由于 AD18 和 PCI 插槽 2 的 IDSEL 引脚是连在一起的,所以:AD18 = 高电平 → 插槽 2 的 IDSEL = 高电平
IDSEL 接到哪根 AD 线是由主板硬件布线决定的,所以某一个PCI插槽的device号是固定的,而它的Bus号由BIOS/固件动态分配特别是部署PCI桥的时候,Function号就更不用说了、设备自身定义。

1.7 PCI Bridge/PCI device配置空间

配置空间对于芯片来说其实放的是配置空间寄存器configuration space register各自的值。
PCI device/PCI bridge的配置空间寄存器在其内部。也就是PCI device的配置空间寄存器在PCI设备比如显卡声卡内部(某些PCI device就在主板上,不是外插的);PCI桥的配置空间寄存器在主板的桥芯片组里,逻辑上分出很多bridge但是物理上就是一组bridge配置空间寄存器。
bridge和device的空间配置寄存器配置不一样,配置空间当然也不一样。

配置空间相当于每个register对应某bus device function在写值,多个寄存器总结出来就是下方这种表(没显示全,实际会到FF h)。
比如vendor ID Device ID这一行的值在某个SATA PCI型号设备里是一个叫Identifiers的寄存器对应写的4字节(各个厂商spec规范里都会写,都是符合PCI规范要求的)。
确定了bus device function号,才能获取唯一数据的配置空间,换了任一bus/device/function号,都不是完全一样的数据了。

PCI Bridge配置空间
在这里插入图片描述
PCI桥的00h到0Fh和PCI设备的这部分都是一样的结构(后面会放PCI设备的空间配置图)。先介绍一下pci bridge独有的部分:
Primary Bus Number(Offset 18h):PCl桥的上游总线号(桥不是两头接总线吗,它的上游总线号是数字小的/靠近host bridge的)
Secondary Bus Number(Offset 19h):PCI的下游总线号(数字大的/远离host bridge的)
Subordinate Bus Number(Offset 1Ah):PCI桥下游最大的总线号(拓扑图里桥连接的最末端里bus号最大的)
这3个寄存器是在PCI Bus Scan的时候由BIOS填入的。

PCI device配置空间
在这里插入图片描述

讲一下主要的几个地方的值含义:

Vendor ID (Offset 00~01h)
示例 :ASMedia PCIe-to-PCI Bridge(用于扩展传统PCI插槽) 0x1B21 (代表ASMedia Technology Inc)

Device ID (Offset 02~03h)
示例 :同上的设备 0x1080(代表ASMedia ASM1083/1085 PCIe to PCI Bridge)
所以读这个设备的配置空间的时候第一行是1080 1B21,如果用RU工具查看:21 1B 80 10(从低到高)

Class Code(Offset 09h~0Bh)
这三个字节实际上是Programming Interface(09h)+Sub-Class(0Ah)+Base Class(0Bh)
代表PCI的类别,例如网络类、显示类。
Base Class这字节如果显示02,就表示Network Controller网络类(PCI spec里有写对应类型)。
spec里都有写对应的,照着看就能明白具体类型了。
在这里插入图片描述
Command (Offset 04~07h)
每一bit代表的含义spec都有写,其他的也一样,照着PCI spec看就行了。
在这里插入图片描述

Header Type(Offset 0Eh)
Bit 7 : multiple function。是否是多功能,也就是相同的Bus和Device号,有其他Function号。0表示单功能,1表示多功能。
Bit 6 - 0 : 如果值为0=PCI device,1=PCI to PCI bridge,2=Card Bus bridge。
(举例:如果0E偏移这里的1字节读出来是01h,则表明这是一个单功能PCI bridge;如果是读出来是80h,则是多功能PCI device)

Interrupt Line(Offset 3Ch) :该设备所使用的IRQ Number(值范围是0-0Fh)
什么是IRQ?它是物理上连接到CPU的硬件线(pin脚),用来传递中断信号。当设备需要中断CPU时,会通过具体的IRQ线发送中断请求。而我们需要用PCI的Interrupt Pin去连IRQ。
硬件中断线编号从0到15(0Fh),对应于主要的硬件中断线(如硬盘、声卡、键盘等),这15条中断线(IRQ0-IRQ15)对应不同的pin脚,通常如下:
IRQ0:系统计时器
IRQ1:键盘控制器
IRQ2:级联中断链路
IRQ3:串行端口
IRQ4:串行端口
IRQ5:声卡、其他设备
IRQ6:硬盘控制器
IRQ7:并口
IRQ8-IRQ15:不同的外围设备

Interrupt Pin(Offset 3Dh):该设备所使用的中断引脚
值为0:该设备没用使用中断引脚,1:用中断引脚INTA#,2:INTB#,3:INTC#,4:INTD#,FFh:reserved
参考之前的PCI pin脚图里:
在这里插入图片描述

Capabilities Pointer(Offset 34h) :存储1字节的指针,可以理解为单链表的头指针(例如图上的这一个字节数据A4h代表指到A4h去索引本PCI的第一个Capability)

PCI的Capability(能力结构)是存放在设备配置空间中的一段特殊数据结构。它允许设备定义一些扩展功能,比如电源管理、MSI(消息中断)、热插拔支持等。
每个Capability 结构都有唯一的ID号,每一个Capability 寄存器都有一个指针,这个指针指向下一个Capability 结构,从而组成一个单向链表结构,这个链表的最后一个Capability 结构的指针为0

所以我们只用考虑初始 capability pointer值每个Capability结构里包的指针值
如图:34h里的值是A4h,所以去看A4h偏移,A4h这一字节的内容是这个Capability X的ID,随后的A5一字节是下一个Capability Y的偏移地址,再往后的区域就是这个Capability X的具体内容(具体占多少字节对照PCI规范)。就像图里这样不断寻址链表,直到Capability 结构的指针为0(例如图里的Capability Z)。被寻址到的Capability即为有对应功能的,没有实现某个能力的情况下,链表中就不会有“这个Capability的ID和内容”
在这里插入图片描述

2. PCI IRQ routing table(Legacy的东西,可不看)

IRQ是可以共享,每个IRQ可以供多个PCI device的INT引脚连接。

Windows 98需要知道主板上每个PCI设备的中断引脚(INTX Pin)和PCI Router中断引脚的对应关系。这个对应关系OS无法自动侦测。
Bios在build的时候提供PCI IRQ Routing Table。Post的时候Bios把这个table从Bios Rom里读出到内存的低段(F000段,可以看做20位地址F)。
Bios或OS根据PCI IRQ Routing Table分配IRQ给PCI设备。

如图所示低段存储着IRQ Table。
在这里插入图片描述

这是debug工具查找出来的:
(-s F000:FFFF "$PIR"表示从F0000开始查询FFFF个字节到FFFFF,搜索$PIR)
$PIR是IRQ routing table的标头,在FC5C0找到了(不熟悉这个查询的可以网上找一下资料,F000代表段,C5C0代表偏移,段左移4bit+偏移就是地址),之后就可以按照上面的IRQ Table来对照数据了。

在这里插入图片描述
从32offset开始每16字节就是一份Slot信息,里面包含了Bus号、Device号、对4个INT的Link Value和IRQ Bitmap(这部分是最重要的router信息)等等。
在这里插入图片描述

3. 如何访问PCI config space配置空间

前面介绍了PCI的bridge和device两种类型的配置空间,接下来说一下如何访问PCI配置空间里的值。

3.1 IO Port(仅用于x86平台,且读写的是Offeset FFh以内的信息)

x86体系中,IO端口是通过专门的指令(如IN/OUT)访问的,这是硬件设计的一部分,对于ARM就不适用了。而且它只能访问PCI设备的0-FFh,访问其他板子上PCIe设备扩展的100-FFFh就不行了。
(当然这里只是说一下配置空间访问,实际上PCIe直连CPU的,PCIe规格的设备当然不能插仅支持PCI的板子上用,之后有机会再介绍区别)
在这里插入图片描述
我们要先换算一串32bit数据到CF8(CONFIG_ADDRESS)中表明信息,然后CFC(CONFIG_DATA)进行寄存器读/写(如果不清楚x86的io口读写的自己搜搜资料看看)。
注意:PCI寄存器和配置空间任一改值都会同步,IO读写实际上是在通过IO口改PCI里的寄存器,后面的MMIO改的是内存里的一部分(被PCI寄存器映射出来的配置空间),只针对x86上PCI的话他俩最终效果一样,因为PCI寄存器和内存里的配置空间会同步更新。
上图就是换算数据的每一bit,包含了之前说的非常重要的bus device function属性。bit31置1,bit30:24全置0这是规范,而这个Register对应PCI配置空间图上的偏移,实际上数据是bit 7:0这一整个字节,但是由于规范,我们要对齐来读4字节数据,所以只能让最后2bit置00(详细解释看我另一篇csdn:关于PCI的IO Port读取为什么写入0CF8的32位里最后2bit规定是0)。


举例1,我们要 bus2 device1 function1 register2Ch 的数据,下图是填入数据,最终得到8002092C去填CF8。
在这里插入图片描述

汇编代码:

mov dx,0CF8h
mov eax,8002092Ch
out dx,eax
mov dx,0CFCh
in eax,dx

eax就会向我们展示获取到的4字节PCI寄存器数据。


举例2, bus2 device1 function1 register2Ch 的数据为80868086h:

汇编代码:

mov dx,0CF8h
mov eax,8002092Ch
out dx,eax
mov dx,0CFCh
mov eax,80868086h
out dx,eax

3.2 MMIO(推荐)

MMIO全称memory-mapping io,PCI寄存器映射到内存末端的区域,我们对其进行访问读写。
为什么推荐:1.arm也可以用;2.PCIe设备寄存器多达FFFh=前0-FFh PCI寄存器+后100-FFFh扩展寄存器,而io读写方式寄存器只有8bit,对于扩展部分肯定访问不到。

具体实现C语言mmio相关read/write函数,这里不细说了,只说它要输入的数值,也就是访问的内存空间(PCI映射的配置空间)。

举例:访问Bus2 Dev1 Func1 Reg100h(PCIe设备的扩展寄存器,不然的话PCI寄存器在0~FFh区间)
在这里插入图片描述
同样是需要4字节数据,前4位要求是1111,接8位bus号,5位device号,3位function号,再接12位register(也就是要去访问配置空间的偏移)。同理io口访问,也是最后2bit必须写00来保持对齐4字节访问。得到数据F0209100。

4. 如何识别PCI-e设备

答:用capability list

在这里插入图片描述
1.确认是否支持capability list(status的寄存器也就是偏移06h的bit4),是1意味着设备支持能力链
2.找到capability链表初始指针(从34h开始)
3.追capability链表(链表结束标识是Next是00h)
4.判断是否其中一个capability ID是10h,有的话则是PCIe设备

提一下,PCIe的0~FFh的PCI配置空间capability链表跟PCI一样是以找到next是00h就结束,而扩展部分(100-FFFh)第一个capability就在是100h这里开始。
在这里插入图片描述

参考文档:PCI规范

相关文章:

  • win11安装踩坑笔记 win11 u盘安装
  • 67.实现AI流式回答的后端实现(2)
  • Windows下编译zlib
  • 属性映射框架-MapStruct
  • 使用交叉编译工具提示stubs-32.h:7:11: fatal error: gnu/stubs-soft.h: 没有那个文件或目录的解决办法
  • 【LaTex公式】在Latex公式中模拟表格
  • 34、请求处理-【源码分析】-Model、Map原理
  • VulnStack|红日靶场——红队评估四
  • python中将一个列表样式的字符串转换成真正列表的办法以及json.dumps()和 json.loads()
  • SAR ADC 同步逻辑设计
  • 2. 手写数字预测 gui版
  • 声纹技术体系:从理论基础到工程实践的完整技术架构
  • VAE在扩散模型中的技术实现与应用
  • 算法训练第三天
  • 跑步前热身动作
  • Python应用for循环遍历寻b
  • RAGFlow从理论到实战的检索增强生成指南
  • 在win10/11下Node.js安装配置教程
  • Java 认识异常
  • 桥 接 模 式
  • 上海网站建设 公司案例/seo优化实训报告
  • wordpress文章列表 框/seo网站seo
  • 成都微信网站开发/广告设计需要学什么
  • 企业建设网站风险/西安网络优化培训机构公司
  • 怎么做网站后台界面/百度搜索官方网站
  • 企业建设网站的功能是什么/系统优化