RapidIO 基础与底层包类型
1.RapidIO 是基于数据包交换的互联体系结构
类似 Mac 层使用以太网的计算机网络(IEEE802.3)?
首先 RapidIO 是一个互联协议(类似计算机网络 IEEE802.3),包含硬件与软件的定义,使用基于数据帧的传输。
RapidIO 使用 差分线 进行数据交换
2. RapidIO 主要用于嵌入式系统内部互联
类比以太网,一块板子上的两个处理器通过以太网进行链接?(芯片与芯片之间、板到板之间)
3. RapidIO 采用三层体系架构
- 逻辑层:最上层,定义不同的类型的数据包帧格式。(这是软件?RapidIO 不仅包括硬件规范,还包括软件规范)
- 传输层:中间层,定义路由信息,比如当前数据包的源地址,与目的地址。(这也是软件?地址如何确定?)
- 物理层:最底层,提供电器特性,流量控制,错误管理等硬件相关的信息。(硬件?)
那么类比计算机网络:数据接收时。Mac 层触发数据收中断,把数据传递给 ARP/IP 等传输层软件协议栈。
RapidIO 数据接收时,物理层触发数据收中断,并把数据传递给传输层协议栈,进行路由信息分析,如果目的地址是本机,那么再传递给逻辑层协议栈,进行数据帧解析,并响应。
4. RapidIO 分为并行 RapidIO 与串行 RapidIO(SRIO)
并行 RapidIO 与 SRIO 的区别只存在于物理层不同。传输层与逻辑层等软件相关的处理一致。
5. RapidIO 数据传输使用请求与响应机制
也就是数据包分为请求数据包,与响应数据包,当目的地址是本机时,需要返回响应数据包,请求数据处理与响应涉及到协议栈的实现.(数据响应能否纯靠硬件?物理层的响应应该可以?)
6. RapidIO 端口一般不会直连,而是通过交换结构(fabric)连接
所以其实也可以直连,类似以太网,不过一般都是使用路由器组网。
7. RapidIO 物理层实现控制符号,用于对数据包的在物理层的应答,流量控制,维护
那么控制符号其实是一个纯硬件的实现,软件不需要关心,比如一个接收到 RapidIO 数据包的终端,应该向发送方返回一个控制符号,用于包确认,表示收到数据包。
控制符号只用于当前数据包的收发双方。
8. RapidIO 数据包格式
RapidIO 分为请求包与响应包.
请求包格式如下:
S | AckID | rsrv | Prio | TT | Ftype | Dest Addr | Src Addr | Transaction | Size | Src TID | (dev offset addr) | (payload) | CRC |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1b | 3b | 4b | 2b | 2b | 4b | 8/16b | 8/16b | 4b | 4b | 8b | (32/48/64 b) | (8-256B) | 16b |
请求包中各位域作用如下:
位域 | 长度 | 描述 |
---|---|---|
S | 1bit | 指示当前包是一个数据包(S=0),还是一个控制符号(S=1) |
AckID | 3bit | 当 S=1,此位域用于控制符号,表示某一个包已发送或接收。 |
rsrv | 4bit | 保留 |
Prio | 2bit | 包优先级,用于流量控制 |
TT | 2bit | 表示传输地址的机制类型(器件地址长度: 8bit/16bit) |
Ftype | 4bit | 与 Transaction 位域共同确定事务类型 |
Dest Addr | 8/16bit | 目的器件地址 |
Src Addr | 8/16bit | 源器件地址 |
Tansaction | 4bit | 与 Ftype 位域共同确定当前包事务类型(用于确定不同的帧类型与帧格式) |
Size | 4bit | 编码后事务长度?(不同的帧类型对该位域的解释不同) |
Src TID | 8bit | 事务 ID,逻辑层软件维护的当前事务 ID(不同的帧类型对该位域的解释不同) |
device offset address | 32/48/64 bit | 器件偏移地址,对于存储器访问事务,跟随在 SRC TID 之后的必须是器件偏移地址。(不同的帧类型对该位域的解释不同) |
payload | 1-256Byte | 有效负载,对于写事务,必须存在 payload |
CRC | 16bit | 包以16位循环冗余校验码结束 |
响应包格式如下:
S | AckID | rsrv | Prio | TT | Ftype | Dest Addr | Src Addr | Transaction | Status | Target TID | (Payload) | CRC |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1b | 3b | 4b | 2b | 2b | 4b | 8/16b | 8/16b | 4b | 4b | 8b | (8-256B) | 16b |
响应包各位域作用如下:
位域 | 长度 | 描述 |
---|---|---|
S | 1bit | 指示当前包是一个数据包(S=0),还是一个控制符号(S=1) |
AckID | 3bit | 当 S=1,此位域用于控制符号,表示某一个包已接收。 |
rsrv | 4bit | 保留 |
Prio | 2bit | 包优先级,用于流量控制 |
TT | 2bit | 表示传输地址的机制类型(器件地址长度: 8bit/16bit) |
Ftype | 4bit | 与 Transaction 位域共同确定事务类型 |
Dest Addr | 8/16bit | 目的器件地址 |
Src Addr | 8/16bit | 源器件地址 |
Tansaction | 4bit | 与 Ftype 位域共同确定当前包事务类型 |
Status | 4bit | 表示请求事务是否成功完成 |
Target TID | 8bit | 事务 ID,逻辑层软件维护的响应事务 ID, 与请求包的 Src TID 一致 |
payload | 8-256Byte | 有效负载,对于读请求事务,必须存在 payload |
CRC | 16bit | 包以16位循环冗余校验码结束 |
9. 每一个数据包(S=0)都称为一个具体的事务包
事务包的事务类型通过 Ftype 与 Ttype(transaction) 两个位域共同确定,不同的位域值确定的事务包类型与功能如下表(不同的事务包,也许有不同的帧格式):
Ftype(Format Type) | Ttype(Transaction Type) | 事务包类型 | 描述 |
---|---|---|---|
0x0/0x1 | reserve | reserve | reserve |
0x2 | 0b0100 | NREAD | 读指定的地址 |
0b1100 | ATOMIC Increment | 先往指定的地址传递数据,再把传递的数据加1 | |
0b1101 | ATOMIC decrement | 先往指定的地址中传递数据,再把传递的数据减1 | |
0b1110 | ATOMIC set | 把指定地址中的数据的每个位置1 | |
0b1111 | ATOMIC clear | 把指定地址中的数据清0 | |
0x3/0x4 | reserve | reserve | reserve |
0x5 | 0b0100 | NWRITE | 往指定的地址写数据 |
0b1101 | NWRITE_R | 往指定的地址写数据,写完成之后等待接收目标器件的响应 | |
0b1101 | ATOMIC test/swap | 对指定地址中的数据测试并交换 | |
0x6 | 0bxxxx | stream write | 以数据流的形式写指定的地址,比 NWRITE / NWRITE_R 效率更高 |
0x7 | reserve | reserve | reserve |
0x8 | 0b0000 | MAINTENANCE read req | 专用寄存器维护操作读请求 |
0b0001 | MAINTENANCE write req | 专用寄存器维护操作写请求 | |
0b0010 | MAINTENANCE read resp | 专用寄存器维护操作读响应 | |
0b0011 | MAINTENANCE write resp | 专用寄存器维护操作写响应 | |
0b0100 | MAINTENANCE write req | 端口写请求 | |
0x9 | reserve | reserve | reserve |
0xA | 0bxxxx | DOORBELL | 门铃 |
0xB | 0bxxxx | MESSAGE | 消息 |
0xC | reserve | reserve | reserve |
0xD | 0b0000 | RESP no data | 不带负载的响应 |
0b1000 | RESP with data | 带负载的响应 | |
0xE / 0xF | reserve | reserve | reserve |
根据上表,可知,rapidIO 共有三种类型的事务类型:
- 存储区读/写访问, 使用 Ftype = 0x2/0x5/0x6 实现;
- rapidIO 专有寄存器访问,使用 Ftype = 0x8 实现;
- 门铃、消息数据中断传输,使用 Ftype = 0xA/0xB 实现。
(除了第二类事务-专有寄存器访问,其他事务的响应通过 Ftype = 0xD 实现)
10. RapidIO 使用消息邮箱与门铃两个事务实现消息
传递
消息邮箱与门铃对应两种不同的事务,即不同的事务帧格式。
11. 操作(Opeations)由不同的事务包组成
操作分为:
- I/O 逻辑操作;
- 维护操作;
- 消息操作。
I/O 逻辑操作用于 RapidIO 存储空间的基本读写,可通过请求和响应事务来完成。
12. I/O 逻辑操作
I/O 逻辑操作主要包括下列几种,都是操作目标器件的存储器空间:
操作 | 使用的事务包 | 描述 |
---|---|---|
读 | NREAD, RESP | 从目标器件中的读数据,存在负载响应 |
写 | NWRITE | 往目标器件中写数据,无响应 |
有响应写 | NWRITE_R, RESP | 往目标器件中写数据,并接收响应 |
流写 | SWRITE | 数据流形式写数据,无响应 |
ATOMIC | ATOMIC, RESP | 原子操作,读-修改-写 |
由上表也可以看出,操作由一个或多个事务包完成。
13 I/O 操作请求事务包格式
I/O操作请求事务包(读、写、ATOMIC)通用格式如下:
S | AckID | rsrv | Prio | TT | Ftype | Dest Addr | Src Addr | Transaction | WrSize/RdSize | Src TID | (Extended Addr) | Address | Wdptr | Xamsbs | (payload) | CRC |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1b | 3b | 4b | 2b | 2b | 4b | 8/16b | 8/16b | 4b | 4b | 8b | 16/32b | 29b | 1b | 2b | (8-256B) | 16b |
物理层与传输层的位域定义与之前讲解的一致,只描述逻辑层的位域定义:
位域 | 长度 | 描述 |
---|---|---|
Ftype | 4bit | Format Type, 与 Transaction 位域共同确定当前事务包类型 |
Transaction(Ttype) | 4bit | 事务类型,与 Ftype 共同确定当前事务包类型 |
WrSize/RdSize | 4bit | 读、写事务包长度,这个字段配合 wdptr 位域使用 |
Src TID | 8bit | 事务 ID |
Extended Addr | 16/32bit | 可选的扩展地址,可再扩展16位或32位 |
Address | 29bit | 29 bit 的物理地址(每一个单元,表示 8 字节) |
Wdptr | 1bit | 字指针,配合 WrSize/RdSize 字段指明数据的大小以及对齐方式?(由于负载最小 8 字节,0表示读取的是低4字节,1表示读取高4字节) |
Xamsbs | 2bit | 扩展地址最高位,物理地址进一步扩展2位 |
payload | 8-256B | 数据负载 |
14. 响应事务包格式
通用的响应事务包格式如下:
S | AckID | rsrv | Prio | TT | Ftype | Dest Addr | Src Addr | Transaction | Status | Target TID | (Payload) | CRC |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1b | 3b | 4b | 2b | 2b | 4b | 8/16b | 8/16b | 4b | 4b | 8b | (8-256B) | 16b |
物理层与传输层不再赘述,逻辑层各位域值的描述如下:
位域 | 值 | 描述 |
---|---|---|
Ftype | 0b1101 | 0xD 类事务,表示响应 |
Tansaction | 0b0000 | 不携带数据的响应 |
0b1000 | 携带数据的响应 | |
其他 | reserve | |
Status | 0b0000 | DONE 状态,表示请求事务正确处理 |
0b0111 | ERROR状态,表示请求事务出现粗偶 | |
Target TID | 事务 ID,逻辑层软件维护的响应事务 ID, 与请求包的 Src TID 一致 | |
payload | 有效负载,对于携带数据的响应,必须存在。 |
15.流写请求事务包
流写请求事务包不存在 Transaction(Ttype)、WrSize/RdSize、Src TID 这三个位域。
流写操作无响应事务包。
16.维护操作及事务包结构
维护操作用于访问 RapidIO 能力寄存器、命令和状态寄存器、本地定义的寄存器以及数据结构。
维护操作的请求与响应事务包都是用第 8 (Ftype = 0x8)类事务包。
维护操作的请求事务包的逻辑层帧结构如下(物理层与传输层不再赘述):
Ftype | Ttype | WrSize/RdSize | Src TID | Hopcount | Config Offset | Wdptr | reserve | payload |
---|---|---|---|---|---|---|---|---|
4b | 4b | 4b | 8b | 8b | 21b | 1b | 2b | 8-256B |
维护操作的响应事务包的逻辑层帧结构如下(物理层与传输层不再赘述):
Ftype | Ttype | Status | Target TID | Hopcount | reserve | payload |
---|---|---|---|---|---|---|
4b | 4b | 4b | 8b | 8b | 24b | 8-256B |
各位域的值描述如下:
位域 | 值 | 描述 |
---|---|---|
Ftype | 0b1000 | 0x8, 表示这个一个维护操作事务包(请求或响应) |
Ttype | 0b0000 | 表示这是一个维护操作读请求 |
0b0001 | 表示这是一个维护操作写请求 | |
0b0010 | 表示这是一个维护操作读响应 | |
0b0011 | 表示这是一个维护操作写响应 | |
0b0100 | 表示这是一个维护写端口请求 | |
WrSize/RdSize | 表示负载最大数据量 | |
Hopcount | 跳数其实是传输层位域,用于确定交换器件,供寻址路由机制使用,当事务包每一次被交换机转发,那么 HopCount 减 1,如果为0, 那么维护操作的目标器件就是当前交换机 | |
Config Offset | 用于读写 CAR/CSR 寄存器的双字节偏移量 | |
Src TID | 请求事务包 ID | |
Target TID | 响应事务包 ID | |
Status | 0b0000 | DONE 状态,表明请求包事务成功完成 |
0b0111 | ERROR 状态,表明检查到不可恢复的错误 | |
0b1100-0b1111 | 用户自定义 |
17.消息操作及事务包格式
RapidIO 消息传递逻辑规范定义了两种不同的包格式用于消息事务:
- 第10(Ftype = 0xA)类事务包格式用于发送非常短的16位数据负载,第10(0xA)类事务包也称为门铃(DOORBELL)事务;
- 第11(Ftype = 0xB)类事务包用于传递多事务消息,一次消息最多可发送 4096 字节有效负载。
18.门铃事务(DOORBELL)
门铃事务是第10 (Ftype = 0xA)类事务包,没有数据负载,逻辑层帧格式如下(物理层与传输层不在赘述):
Ftype | Reserver | Src TID | info(MSB) | info(LSB) |
---|---|---|---|---|
4b | 8b | 8b | 8b | 8b |
各位域描述如下:
位域 | 值 | 描述 |
---|---|---|
Ftype | 0b1010 | 第10(0xA)类事务包,表示这是一个门铃事务 |
Reserver | 0b0000 0000 | 包含通用请求包的 Ttype 与 Size 位域,reserve |
Src TID | 门铃事务ID | |
info(MSB) | 发送信息的高8位(高字节) | |
info(LSB) | 发送信息的低8位(低字节) |
门铃事务存在响应事务包(Ftype = 0xD),通常是 DONE.
19. 消息事务及包格式
第11(Ftype = 0xB)类事务包为消息事务包,这一类包总有数据负载,并且数据负载是双字对齐。
消息事务包的逻辑层帧格式如下(物理层与传输层不在赘述):
Ftype | MsgLen | Ssize | Letter | Mbox | MsgSeg/Xmbox | payload |
---|---|---|---|---|---|---|
4b | 4b | 4b | 2b | 2b | 4b | 8-256B |
各位域描述如下:
位域 | 值 | 描述 |
---|---|---|
Ftype | 0b1011 | 第11类事务包,表示这是一个 Message 事务 |
MsgLen | 消息长度,表示组成当前消息的事务包总数,0表示单包消息,0b1111 表示消息由16个消息事务包组成 | |
Ssize | 标准消息包数大小,用于告诉接收者,除了消息的最后一个事务包之外,其他消息事务包的负载大小。 | |
0b1001 | 除了消息的最后一个消息事务包,其他消息事务包负载长度8字节 | |
0b1010 | 除了消息的最后一个消息事务包,其他消息事务包负载长度16字节 | |
0b1011 | 除了消息的最后一个消息事务包,其他消息事务包负载长度32字节 | |
0b1100 | 除了消息的最后一个消息事务包,其他消息事务包负载长度64字节 | |
0b1101 | 除了消息的最后一个消息事务包,其他消息事务包负载长度128字节 | |
0b1110 | 除了消息的最后一个消息事务包,其他消息事务包负载长度256字节 | |
Letter | 该位域用于识别信箱(MailBox)中的一个槽(SLOT,窗口),(接收器件的每一个信箱有 4 个BANK?) | |
Mbox | 该位域指示消息的目的信箱,接收器件最多4个信箱(每个信箱最多可接收 16 个消息事务包) | |
MsgSeg | 消息分段(message segment), 该字段表明当前消息事务包属于消息的第几个包,0表示第1包消息,0b1111 表示第16个消息事务包 | |
Xmbox | 该位域与 MsgSeg 使用相同的字段,只用于单包消息,用于指示目标信箱的高4位(即把多包信箱拆分为单包消息信箱,最多 64 个信箱) |
可以注意到: 消息事务包没有 Src TID.
尽管消息事务包存在 Letter、Mbox、MsgSeg、与 Xmbox 这几个位域,但是这些位域在逻辑上只占用 8 位空间,即可以用来标识 256 个不同的消息事务包。
每一个消息事务包在接收器件上都有唯一的存储空间:
消息存储地址 = 信箱 Mbox 地址 + 消息分段 * 标准长度;
20.消息事务包的响应
消息的响应事务包也是由第13(Ftype = 0xD)类包产生,不过响应包不在包含 Target TID 位域,而是解释为 Target Info 位域,响应包格式如下(逻辑层格式):
Ftype | Ttype | Status | Target Info | Payload |
---|---|---|---|---|
4b | 4b | 4b | 8b | 8-256B |
Target Info 位域由 Letter、Mbox、MsgSeg 组成(每一个消息事务包都需要一个响应)。
RapidIO 系统寻址
1.RapidIO 系统使用器件 ID 唯一地识别组成一个 RapidIO 系统器件的所有器件
器件 ID 分为 8位 ID 与16 位 ID。
器件 ID 分别对应传输层的三个位域:
位域 | 长度 | 描述 |
---|---|---|
TT | 2bit | 表示传输地址的机制类型(器件地址长度: 8bit/16bit) |
Dest Addr | 8/16bit | 目的器件地址 |
Src Addr | 8/16bit | 源器件地址 |
器件 ID 并不固定,由枚举主机分配,交换结构 switch 通过器件 ID 实现路由。
2.交换结构 switch 有一张路由表,保存器件 ID 与端口信息
RapidIO 系统中的 switch 不需要器件 ID,但是 RapidIO 的端点器件必须分配器件 ID,
3. 使用维护事务包访问交换机
由于交换机没有器件 ID,那么当系统枚举时,我们通过维护事务包中的 hop_count 位域来访问目标交换机(配置路由表),其他类型的事务包无法访问交换机。
RapidIO 启动与初始化
可以将某一片地址空间映射为与某一 rapidIO 器件相关,类似 pci 设备映射。
我们必须编写驱动软件来处理 rapidIO 的消息事务,这与 pci 不同?
rapidIO 驱动需要分配端点器件 ID,配置交换机路由表,建立存储器空间与 RapidIO 端点之间的映射。
1. RapidIO 系统初始化过程概述
初始化过程概述如下:
- host cpu 中的 RapidIO 驱动进行枚举;
- host 配置路由表,建立最佳路径路由;
- host 映射存储空间给每一个 RapidIO 端点;
RapidIO 系统中存在三类器件:
- 主机器件:host cpu 端点器件,初始化时器件ID配置为 0x00;
- 引导代码器件(可以不考虑):保存 cpu 系统镜像的 rapidIO 端点器件, 初始化时器件 ID 配置为 0xFE;
- 既非主机器件也非引导代码器件:初始化时器件 ID 配置为 0xFF;
RapidIO 驱动初始化执行完成之后,每一个器件都会拥有唯一的器件 ID 值。
RapidIO 总线硬件的初始化,软件不需要关心,由硬件完成(类似 PCI 总线)。
2. 枚举
枚举过程中,RapidIO 驱动会为所有 RapidIO 端点器件分配唯一的器件 ID。
对于每一个 RapidIO 网络系统,存在一个限制:仅有两个主机可以枚举一个网络。(实际上只有一个主机执行枚举,由系统设计之初确定)
枚举的主机在执行枚举之前,需要将自身的器件 ID 设置为唯一值,通过写**主机基本器件 ID 锁定 CSR
** 实现,可设置为 0x00/0x01, 0x01 的 优先级更高。
枚举的主机在执行枚举之前,需要置 1 主机使能位,通过写**端口通用控制 CSR
** 实现,交换机没有主机使能位。
枚举完成后,已建立系统路由互连信息,可能需要继续执行地址空间映射操作。
3. 地址空间映射
RapidIO 端点器件(host 主机)可以把自身的可寻址空间,映射为某一个目标 RapidIO 器件的存储区。
通过查询目标器件(需要映射的 RapidIO 端点器件)的**处理部件特征 CAR
, 可以获得目标器件支持的地址长度,随后通过写处理部件逻辑层控制 CSR
** 来选择实际的长度。
目标 RapidIO 器件的存储区与 host 自身可寻址空间地址映射完成之后,即可通过地址转换逻辑将可寻址空间与端点器件 ID联系在一起。即对某一地址的访问,会转换为对某一器件 ID 端点的存储区的访问。
4. RapidIO HAL 库?(官网上有吧?)
RapidIO 官网提供的 HAL 库用于支持统一的 RapidIO 应用编程接口,并消除应用软件与底层硬件寄存器的直接交互。
专有器件函数需要根据硬件差异进行适配。为 HAL 库的底层接口。
5. RapidIO HAL 库提供的 API
API 几乎都至少包括了三个参数:
- localport : 本地 rapidIO 端口,表示从当前端口发出或接收事务;
- destID : 目标器件 ID,目标 RapidIO 端点的 8/16 位器件 ID,32位宽;
- hopcount : 当维护事务的目标器件是交换机时,使用 hopcount 来确定目标交换机,事务每由交换机转发一次,该位域减1,减至0时,表示到达寻址的目标交换机。
6. HAL 函数
HAL 库的目标是提供统一的软件接口来配置本地和远程端点器件的寄存器。
HAL 库使用统一的寻址逻辑来配置本地与远程端点寄存器:
- 当配置本地端点寄存器时:destID = 0xFFFFFFFF, hopcount = 0x0(hopcount = 0xffff?); 不同的本地端口使用 localport 来区分。
- 配置远程端点器件时:destID 设置为目标器件 ID,hopcount = 0xFF。
- 配置交换机时:hopcount 设置为目标跳数,destID 设置为 0xFFFFFFFF?