PCIE原理-003_1:PCIE是如何获取BUS number的

1、PCIE bus number是什么?

如图所示为PCIE 2.0协议规定的3DW配置请求head的格式。其中字节8包含了bus number、device number、以及function number。

Bus number指的当前PCIE设备在PCIE系统结构中被分配的总线号。PCIE的部分TLP传输需要确定bus number才能完成。

2、PCIE 是如何获取bus number的?

为支持ID路由,每个PCIE设备(端点和交换开关)中都应设置有贮存设备总线号的寄存器,PCIE协议中并没在PCIe配置头空间定义bus number,bus number号存在事务层的寄存器中。复位时,该寄存器清0。每当PCIe设备收到有效的Type0类型的cfgwr时,PCIe设备就将TLP header中的第8字节写入bus number寄存器。此处需要注意:必须是有效的cfgwr0才会触发bus number捕写入动作,即没有明显的错误,即不是Poison TLP。

两个对接的PCIE设备,主设备是RC端,从设备是EP端,那么上电复位后,EP是如何获取自身的bus number的呢?

在这样的一个PCIE结构中,上电复位后,RC端发起一个对EP的配置写事务,EP会解析配置请求中的bus number,并保存下来,作为自身的bus number号。之后就可以相应其他TLP事务了。也就是说,上电复位后,EP必须先接收到一个配置写,然后才能相应其他TLP事务。

3、PCIE EP是如何响应不同的bus number和device number的

每次在链路上接收到type0类型的配置写时,pcie endpoint都会从配置写TLP报文头byte8~9字段中提取bus_number和device number作为自身的bus_number和device number,并且保持下来。

以一对一的验证环境为例,VIP PCIE对接PCIE EP。VIP PCIE可以发起配置读写和存储读写,此案例中,默认pcie ep是单funciton设备,因此function number为0。Cfgrd默认读取vendor id,cfgwr写默认写bar地址。

从表格中访问序列1、4、5,可以看到每次接收到cfgwr写bar地址,pcie ep都会返回状态为Successful Completion的报文,即使每次收到的cfgwr的bus_number和device number不一致。而从访问序列3 可以看到cfgrd携带的bus_number和device number如果和目标ep的bus_number和device number不一致,将无法访问成功,则pcie ep会返回完成状态为Unsupported Request的cpl。

访问序列

类型

Bus

number

device

number

Function num

Cpl 状态

1

cfgwr

0

0

0

Successful Completion

2

Cfgrd

0

0

0

Successful Completion

3

Cfgrd

0

1

0

Unsupported Request

4

cfgwr

0

1

0

Successful Completion

5

cfgwr

1

0

0

Successful Completion

参考文献:

PCI、PCI-X和PCIExpress的原理及体系结构-马鸣锦  P79

MindShare PCI Express Technology 3.0  P215  Endpoints: One Check

import paramiko import pytest import psutil from common.abs_common import log @pytest.fixture(scope="module") def ssh_client(): print('-----ssh远程连接-------') ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('10.67.6.56', username='root', password='1') yield ssh ssh.close() print("获取PCIe设备的bus number,带宽和速度") def test_network_interface(ssh_client): stdin, stdout, stderr = ssh_client.exec_command("lspci|grep -i 'non' | cut -f1 -d ' '") interface = stdout.read().decode() stdin, stdout, stderr = ssh_client.exec_command(f"lspci -s {interface} -vvv |grep -i Lnkcap | cut -f2 -d ','") widthcap = stdout.read().decode().strip() outputwidthcap = stdout.read().decode("utf-8") stdin, stdout, stderr = ssh_client.exec_command(f"lspci -s {interface} -vvv |grep -i Lnksta | cut -f2 -d ','") widthsta = stdout.read().decode().strip() outputwidthsta = stdout.read().decode("utf-8") stdin, stdout, stderr = ssh_client.exec_command(f"lspci -s {interface} -vvv |grep -i Lnkcap | cut -f3 -d ','") speedcap = stdout.read().decode().strip() outputspeedcap = stdout.read().decode("utf-8") stdin, stdout, stderr = ssh_client.exec_command(f"lspci -s {interface} -vvv |grep -i Lnksta | cut -f3 -d ','") speedsta = stdout.read().decode().strip() outputspeedsta = stdout.read().decode("utf-8") print("比较lspci中PCIe设备的带宽和速度Lnkcap和Lnksta") assert widthcap == widthsta assert speedcap == speedsta print(outputwidthcap,outputwidthsta,outputspeedcap,outputspeedsta) if __name__ == '__main__': pytest.main(['-o log_cli=True --html=./test_get_nic_width.html -s'])
06-10
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值