pcie基础总结

1.计算机主板结构

北桥与CPU相连,挂接高速设备,如DRAM等;

南桥通过北桥间接与CPU相连,挂接低速设备;

南北桥架构属于经典的早期架构,逐渐被PCIE体系替代。

2.PCIE体系结构

2.1.PCIE RC

RC(root complex)即根复合体,里面主要是host bridge,类似于一个上行口,然后是root

port,类似于一个下行口,可以说它是CPU下的第一个下行口(可以并列不止一个)。

2.2.PCIE BUS

PCIe的总线并不是传统意义上共享线路的总线(Bus),而是一个点对点的网络,如果把PCI比喻成网络中的集线器(Hub),那么PCIe对应的就是交换机了。

换句话说,当Root Complex或者PCIe上的设备之间需要通信的时候,它们会与对方直接连接或者通过交换电路进行点对点的信号传输。

2.3.PCIE DEVICES

首先通过配置为type0或者type来区分是EP(end point),还是类桥设备(PCI Bridge)

  • Type 0:它表示一个PCIe上最终端的设备,比如我们常见的显卡,声卡,网卡等等。
  • Type 1:它表示一个PCIe Switch或者Root Port。和终端设备不同,它的主要作用是用来连接其他的PCIe设备,其中PCIe的Switch和网络中的交换机类似。

2.3.1 BDF(DBDF)

PCIe上所有的设备,无论是Type 0还是Type 1,在系统启动的时候,都会被分配一个唯一的地址,它有三个部分(或者四个,还有个Domain)组成:

Bus Number:8 bits,也就是最多256条总线;

Device Number:5 bits,也就是最多32个设备;

Function Number:3 bits,也就是最多8个功能。

Domain Number:总线域,一般就1个或者2个就够了,主要是总线隔离

这就是我们常说的BDF,它类似于网络中的IP地址,一般写作BB:DD.F(或xxxx:xx:xx.x)的格式。

所有连接到PCIe总线上的Type 0设备(终端设备),都可以来实现PCIe的Endpoint,用来发起或者接收PCIe的请求和消息。每个设备可以实现一个或者多个Endpoint,每个Endpoint都对应着一个特定的功能。比如:

一块双网口的网卡,可以每个为每个网口实现一个单独的Endpoint;

一块显卡,其中实现了4个Endpoint:一个显卡本身的Endpoint,一个Audio Endpoint,一个USB Endpoint,一个UCSI Endpoint;

这些我们都可以通过lspci或者Windows上的设备管理器来查看:

2.3.2 PCI Bridge

我们在RC里面可以看到有Host Bridge,root port,其实这都是PCI Bridge设备,桥设备是用来连接总线的,上行口连接上游总线(Primary Bus),下行口连接下游总线(Secondary Bus),一个桥设备上下游均只能接一个总线,要扩展更多就得用到下面的PCI Switch。

2.3.3 switch

PCI Switch和网络中的switch类似,都是用来做转发的,它不会对TLP(事务,即信息)报文做任何修改。如下图所示,可以把switch看作是很多个虚拟桥设备组成的,它有一个上行口(虚拟桥设备),n个下行口(虚拟桥设备),上行口和下行口之间可以互通。

2.3.4 End Point

终端设备(节点),pcie设备树拓扑中,挂在最后并且不能挂载其他设备的设备,比如网卡,显卡等。

3. lspci和setpci工具

3.1 lspci

lspci会打印出所有的pcie设备(root port,switch,any devices)

-tv会以树形结构展示:

-s bdf 指定设备

-d vendorid: 查找特定厂商的设备

-s bdf -vvv 打印指定设备的详细信息,每加一个v信息就更多一些,但一般两个或三个就打完整了

-s bdf -xxx 打印配置空间的reg值,1个x打印64byte,2个打印128,3个打印256

3.2 setpci

setpci --help(获取用法)

setpci --dumpregs 该命令可以打印出所有能访问的寄存器名称以及对应的地址(cap名称和地址不是直接映射)

首先配置空间开始256byte根据type0还是type1界定是bridge还是device,这部分的地址和名称是一一映射不会改变的。

比如想要查看设备0c:00.0的DEVICE_ID,既可以setpci -s 0c:00.0 02.w,也可以setpci -s 0x:00.0 DEVICE_ID.w.

这里w指word,长度是2个byte,还可以使用b、l,分别代表1个byte、4个byte。

然后扩展功能,可以通过名称从官方spec(4.0)中找到第一个寄存器,相当于基地址,再加上偏移即可定位寄存器(个人感觉这种映射方式比较模糊,看以后有没有更直接的对照吧)。

比如CAP_PM可以在spec中找到对应寄存器为Power Management Capabilities Register(Offset 00h),然后加上偏移可以定位到该功能(Capabilities)其他寄存器。

不使用名称的话可以通过lspci直接看到该扩展功能的基地址(看图中红色的框框),比如笔者想要修改扩展功能中的DevCtl寄存器,及地址就是0x80,offset是0x08。修改时可以使用命令setpci 先读出,再修改对应bit。而后使用lspci打印该设备信息,你会看到对应bit位的“-”(0)变成了“+”(1)。

setpci -s 66:04.0 0x80+0x8.w 127 setpci -s 66:04.0 0x80+0x8.w=120

由此,setpci使用名称或者使用地址都可以互相映照了。

此外还有个scanpci,没用过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值