PCIE兼容了大部分PCI总线的特性,区别在于使用串行差分总线代替了并行总线,并实现了协议分层。PCIE的带宽与LANE数量和时钟频率相关,时钟频率支持2.5G和5G,Lane支持x1/x2/x4/x8/x12/x16/x32,每个Lane由一对差分信号组成。

1、PCIE总线拓扑结构

PCIE总线拓扑结构主要由RC(Root Complex)、SW(Switch)和EP(Endpoint)组成,通过总线号、设备号唯一标识每个PCIE设备,每个设备拥有1~8个功能号。根据PCIE协议规范定义,一个PCIE总线拓扑结构中,最多支持256级总线,每条总线上最多挂载32个PCIE设备,SW可以理解为一种特殊的PCIE设备。每个SW代表一级Bus,挂载在该SW下的所有PCIE设备(包括SW和EP)都属于这一级Bus。这样,通过总线号、设备号、功能号就可以匹配到指定的功能设备。

1.1、Root Complex(RC)

CPU连接到根聚合体(Root Complex),RC负责完成CPU地址域和PCIE总线域的转换,并且实现各种总线的聚合。将一部分CPU地址映射到内存,一部分地址映射到相应的相应的PCIE设备。

1)Root Complex是I/O层次结构的根节点,用来连接CPU/Memory子系统到I/O子系统,相当于PCI总线结构中的主桥(北桥)。

2)一个Root Complex可以支持一个或者多个PCI Express Ports,每个端口表示一个独立的I/O层次结构域,每个I/O层次结构域由一个单独的Endpoint组成或者由一个或者多个Switch组件和Endpoints组成。

3)I/O层次结构域通过Root Complex进行P2P对等网络传输是可选功能,实现方式也是独立的。

4)Root Complex作为Requester时,支持组包configuration request、I/O request和locked request

1.2、Endpoint

Endpoint是PCIE体系结构的根节点,可以作为传输的请求方(Requester)或者结束方(Completer)。Endpoint可以分为Legacy Endpoint、PCIE Endpoint和Root Complex Integrated Endpoint三种。传统端点设备支持I/O传输、锁定传输,不需要支持64位寻址;PCIE端点不需要支持I/O或者锁定传输,必须支持64位寻址。

Endpoint是指只具有上游端口(即指向Root Complex或者Switch的端口)的一个具体的PCIE设备。

1.3、Switch

Switch由多个虚拟PCI-to-PCI Bridge设备组成,用于多设备互连,实现路由寻址转发、仲裁等功能。它包含以下特性:

1)一个Switch由至少两个PCI-to-PCI Bridges组成

2)Switch使用PCI桥的机制实现数据传输,如基于地址的路由机制

3)Swtich必须支持在任意端口之间传输任意类型的TLP(Transaction Layer Packet)

4)Swtich必须支持Locked Request,但是下游端口作为发起方时,发起的Locked Request不需要支持

5)每一个使能的Swtich Port必须遵循流控协议(Flow Control)

6)Swtich不可以将TLP数据包分割成多个小数据包进行传输

7)当同一个VC(Virtual Channel)发生竞态时,Swtich的Ingress Ports(inbound Link)之间的仲裁机制通过round robin或者weighted round robin算法实现

1.4、PCIE设备枚举

由前述可知,PCIE总线系统中,通过Bus号和Device号唯一标识PCIE设备,通过Function号唯一标识PCIE设备的功能。

Bus号和Device号是PCIE初始化时进行PCIE设备枚举产生的,而Function号是通过硬件编码设置的,这是因为不同的拓扑结构下,PCIE设备在拓扑网络中的位置不是固定的,而每个PCIE设备支持的功能是可以确定的。

PCIE设备枚举就是在PCIE总线初始化的过程中,使用深度优先算法动态检测PCIE总线拓扑网络结构,为每一个PCIE设备(包括SW和EP)确定Bus号和Device号。

PCIE设备枚举主要基于以下几点因素实现:

1)每个PCIE设备至少支持一个Function(最多支持8个Function),而且第一个Function号必须为0,其他Function号可以不连续编址。每一个Function均包含一组PCIE配置空间,PCIE配置空间的前64字节为PCIE配置空间头部信息,EP支持Type 0格式的头部信息,RC和SW支持Type 1格式的头部信息。

可以看到,Device ID和Vendor ID的字段是一致的,用来标识厂家ID和设备ID。PCIE协议规定Device ID和Vendor ID的取值不能为0xFFFF,当RC发起configure read操作时,如果总线上不存在对应的PCIE设备(Bus/Dev/Fun号不匹配)时,就会返回0xFFFF,由此确定PCIE设备是否存在。

2)RC的Bus号通过硬件编码为0,因此PCIE设备枚举从Bus 0, Device 0, Function 0开始,首先扫描RC下挂载的PCIE设备(每个PCIE设备必须支持Fun 0,所以只有Dev号是不确定的),由此确定Device号(每个Bus下最多可以挂载32个PCIE设备,由此确定了Device号边界)。

3)当确定某个PCIE设备存在时,则通过PCIE配置空间头的Header Type字段确定该PCIE设备是SW还是EP,如果是EP,是一个多功能设备还是单功能设备(支持多少个Function)

4)如果步骤3检测到SW,则扫描下一级总线(Bus号递增,Bus号取值范围为0~255,由此确定的Bus号的边界),根据递归的深度设置0x18字段的Primary Bus Number(上级Bus号)、Secondary Bus Number(下游Bus号,同一层次)、Subordinate Bus Number(当前Bus下最远的Bus号);如果为多功能EP,则继续枚举Function(Function号递增)

根据上述步骤,完成PCIE设备枚举,为每个PCIE设备确定Bus号和Device号,并检测到每一个PCIE设备支持的Function号。

2、PCIE分层协议

PCIE分层协议分为三层——传输层、数据链路层和物理层,每一个协议层根据传输方向分为inbound和outbound两部分。

PCIE使用packet的形式传输数据,packet在传输层和数据链路层组包。类似于网络协议,每一层均添加额外的信息标识。

2.1、传输层

传输层负责组包和解包TLPs(Transaction Layer Packets),TLP可以是读数据包、写数据包或者特定事件。传输层也负责TLP流控。

TLP就是用户和PCIE IP核交互的接口。

TLP分为应答型和非应答型,每个TLP必须有一个特定的标识(Transaction ID)。

PCIE设备有四种地址空间——Memory,I/O,Configuration,Message地址空间,对应四种传输类型,传输层支持不同传输类型TLP的寻址——TLP路由

2.1.1、TLP routing (TLP路由)

首先,我们知道ARM是统一编址,即ARM的物理地址空间是内存地址空间和I/O地址空间统一编制形成的。PCIE总线拓扑网络中使用Bus号和Device号给PCIE设备编址,进一步通过Function号给每个PCIE设备的具体功能编址,每个PCIE功能设备有四种地址空间(配置空间是确定的,其他地址空间是独立的还是共享待商榷)。

RC负责CPU域的物理地址空间和PCIE总线域的地址转换。

某种意义上讲,PCIE总线的核心就是实现CPU对PCIE设备的四种地址空间进行直接读写,即实现地址映射机制。CPU通过RC发起读写请求,RC负责产生TLP,传输层(RC+SW)负责TLP路由。

有三种TLP路由机制——基于地址路由、基于ID路由和隐式路由。

2.1.2、ATU(Address Translation Unit)

TLP的FMT和Type字段定义了四种传输类型,TLP路由就是基于这两个字段识别请求类型,从而采用不同的TLP路由机制。

ATU(地址转换单元)负责实现TLP路由,即进行CPU域的物理地址和PCIE域的总线地址(Bus/Device/Function或者BAR)之间的转换。

如果PCIE总线上发起访问对应CPU域物理地址的请求,将通过ATU生成TLP,TLP中的地址就是ATU转换后的地址。ATU中必须配置TLP类型,如上所述,不同的TLP类型的TLP路由策略是不一样的,而路由策略直接影响到地址转换。

Configuration请求,基于ID的路由,地址被解析成“总线号+设备号+功能号+偏移”,访问的是PCIE设备4KB配置空间。

I/O请求或者Memory请求,基于地址的路由,通过和PCIE总线上各个PCIE设备的BAR地址空间范围比较来确认所请求的物理地址落在哪个PCIE设备的BAR空间上,然后进行相应的读写操作。

Message请求,基于ID或者Implicit路由。

2.1.3、BAR(Base Address Register)

每个PCIE设备的内存地址空间都是从0开始编址,当一个PCIE控制器同时接入多个PCIE设备时,需要确保PCIE总线上每一个PCIE设备的内存地址空间彼此独立,所以需要分别配置BAR(Base Address Register),从而避免PCIE设备发生物理地址冲突。

BAR在PCIE设备配置地址空间特定字段设置。

2.2、数据链路层

数据链路层负责链路管理、数据完整性校验和纠正。

下行方向,数据链路层接收传输层TLP数据包,添加TLP序列号和CRC校验码,然后发送给物理层;上行方向校验TLP数据包完整性,然后发送给传输层。

一旦检测到TLP数据包错误,数据链路层负责请求TLP重传直到接收到完整的TLP数据包,或者检测到链路异常。

数据链路层自己也会产生和处理链路管理数据包,称为DLLP(Data Link Layer Packet)。

2.3、物理层

物理层负责端口管理,包括驱动能力和数据缓冲区、串并转换、PLL和阻抗匹配电路。它负责把数据链路层下发的数据包转换成串行数据、并在PCI Express Link(每个Link包含至少1个Lane)之间以一定的速率和带宽进行传输。

3、PCIE地址空间

3.1、PCIE内存地址空间

PCIE设备内存地址空间位于PCIE设备上,用于进行大块数据存放和交换,如内存、显存、扩展ROM、设备缓冲区等。

PCIE设备内存地址空间设置好BAR(Base Address Register)后,物理地址就能在Linux内核中通过ioremap映射到内核虚拟地址空间,通过readb/writeb/readl/writel等IO访问接口读写。

3.2、PCIE I/O地址空间

为了访问I/O设备而设立,一般用于查询和控制设备的工作状态以及少量数据交换。

访问外部设备寄存器的地址空间?

3.3、PCIE配置地址空间

PCIE设备通过配置地址空间向系统提供设备自身的基本信息,每个PCIE设备都有自己的配置地址空间,由PCIE规范定义统一的格式。

PCIE设备配置地址空间实质上是一段特殊的I/O地址空间,可以为PCIE内存地址空间和PCIE I/O地址空间分配物理地址基地址,即BAR(Base Address Register)。

参考文献

1、DWC_pcie_reference

2、PCI_Express_Base_Rev_2.0_20Dec06a

3、Xilinx PCI Express

4、PCI Express System Architecture

PCIE手札的更多相关文章

  1. 使用FIO对SATA、SSD和PCIe Flash进行测试

    首先声明,同事做的实验 使用fio对SATA.SSD.PCIE进行了测试 测试说明: 1.测试命名   sync_write_4k_32      sync表示测试方式,可以是sync或者libaio ...

  2. 基于WDF的PCI/PCIe接口卡Windows驱动程序(5)-如何为硬件移植驱动程序

    原文地址:http://www.cnblogs.com/jacklu/p/6139347.html 正如前几篇博客所说,使用WDF开发PCIe驱动程序是我本科毕业设计的主要工作.在读研的两年,我也分别 ...

  3. PCIE学习

    PCIe在传输中用8b/10b编码,所以单PCEe2.0的有效带度是4Gb/s x2模式将用于内部接口而非插槽模式 PCIe卡能使用在至少与之传输通道相当的插槽上(例如x1接口的卡也能工作在x4或x1 ...

  4. KVM 介绍(4):I/O 设备直接分配和 SR-IOV [KVM PCI/PCIe Pass-Through SR-IOV]

    学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...

  5. 基于WDF的PCI/PCIe接口卡Windows驱动程序(4)- 驱动程序代码(源文件)

    原文出处:http://www.cnblogs.com/jacklu/p/4687325.html 本篇文章将对PCIe驱动程序的源文件代码作详细解释与说明.整个WDF驱动程序工程共包含4个头文件(已 ...

  6. 基于WDF的PCI/PCIe接口卡Windows驱动程序(3)- 驱动程序代码(头文件)

    原文出处:http://www.cnblogs.com/jacklu/p/4679304.html 在WDF的PCIe驱动程序中,共有四个.h文件(Public.h  Driver.h  Device ...

  7. 基于WDF的PCI/PCIe接口卡Windows驱动程序(2)-开发者需要了解的WDF中的一些重要的概念

    原文出处:http://www.cnblogs.com/jacklu/p/4646601.html 本科毕业设计是这方面的工作,所以想开几篇博客来介绍使用WDF开发PCI/PCIe接口卡的驱动程序方法 ...

  8. 基于WDF的PCI/PCIe接口卡Windows驱动程序(1)-WDF概述及开发环境搭建

    原文出处:http://www.cnblogs.com/jacklu/p/4619110.html 本科毕业设计是这方面的工作,所以想开几篇博客来介绍使用WDF开发PCI/PCIe接口卡的驱动程序方法 ...

  9. 转-Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable

    转-http://snowolf.iteye.com/blog/1628861/ Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariab ...

随机推荐

  1. Node.js+koa2

    const Koa = require('koa') const app = new Koa() const bodyParser = require('koa-bodyparser') app.us ...

  2. vue eslint 规范配置

    vue eslint 规范配置 为了代码格式统一,避免一些低级或者不合理的错误,现强行使用eslint的 standard规范 项目配置 目前都是使用 vue 提供的脚手架进行开发的,虽然 vue-c ...

  3. c# 杀死占用某个文件的进程

    原文:c# 杀死占用某个文件的进程 需要使用微软提供的工具Handle.exe string fileName = @"H:\abc.dll";//要检查被那个进程占用的文件 Pr ...

  4. 【问题解决方案】Xshell连接服务器并实现上传和下载文件

    参考链接: Xshell连接服务器并实现上传和下载文件 第一步:xshell登录完成 略 第二步: 在服务器安装lrzsz 如果服务器的操作系统是 CentOS,则输入命令[yum install l ...

  5. Elastic Search安装-windows

    转载自:https://blog.csdn.net/linkkb/article/details/82805145 其中稍作修改 ElasticSearch介绍 ES是一个基于Lucene的分布式全文 ...

  6. 3.css3文字与字体

    1.css3文字与字体: ①Font-size:大小. ⑴通常使用px.百分比.em来设置大小: ⑵xx-small.x-small.small.medium.large.x-large.xx-lar ...

  7. react随笔

    对React children 的深入理解     https://www.jianshu.com/p/d1975493b5ea [react]利用prop-types第三方库对组件的props中的变 ...

  8. Gradle Settings 类的学习

    # 任务 了解 Settings 类作用于 Gradle 构建的哪个阶段? 了解 Settings 类与 settings.gradle 的关系 了解和使用 inlcude 方法 hook 初始化阶段 ...

  9. python生成图片验证码

    import PIL from PIL import Image from PIL import ImageDraw,ImageFont import random def get_random_co ...

  10. linux常用的小命令

    查看linux版本 uname -a 图上可知,linux内核版本为2.6.32 查看cpu核数 cat /proc/cpuinfo |grep "cores"| uniq 系统中 ...