写在前面:
1、本文参考来源PCIe 6.2,2024.02.25
2、仅作为个人学习记录和分享,转载请注明出处
3、个人能力有限,协议的理解均基于个人,如有错误还望指出
4、本文不包含计算公式过程,主要是一些概念和规则介绍,具体的计算过程和工作过程在之后的博文中进行介绍
目录
一、简介
FC(Flow Control)是用来防止接收端缓存溢出并且确保遵守事务顺序规则。一般来讲FC机制是给Requester来追踪对端是否具备可使用的队列或者缓存空间,即FC在一条link中是点对点的而非端对端(不控制或者表明请求到达最终完成方)。简单理解FC即FC在初始化时会告知对方设备自身有多少数量的可使用的Credit,自身在接收到TLP报文后会消耗掉相对应的Credit,然后将更新的Credit报告给对方设备,对方设备设备在发送前也会检查当前Credit是否允许发送transaction。Credit是FC管理的基本单位。
在NFM下每个VC具备独立的FC Credit池。在FM下共享的FC机制可以被用来降低VC资源使用。一般来说FM下每个VC的相关资源包含两部分:一部分为专用资源(典型情况下比较小,主要是PF/VC独立的资源,用来避免死锁--至少允许其能够传输一个TLP),一部分为共享资源(典型情况下比较大)。另外其还存在Merged FC用来使能Posted Request和Completion的共享缓存,进一步减少了资源消耗。
FC是由事务层和数据链路层合作处理的。事务层会对接收到的TLP进行FC计数并根据可使用的credit来阻止TLP的传输,即便这些TLP最终是无效的。也就是说所有通过事务层发送的TLP在到达数据链路层和物理层之前都必须首先通过FC控制。此外,如果数据链路层由于链路上的错误而重复发送TLP,发送和接收FC均不会感知到。
注意:FC是事务层功能,所以如下类型的信息传输跟FC Credit无关--LCRC/Packeting Framing Symbol/其他特殊Symbol/数据链路层到数据链路层的内部通信packet。
二、FC相关规则
1.FC信息传输包
FC信息的交换采用的是FCP(Flow Control Packets),是DLLP的一种类型,在某些情况下为Optimixed_Update_FC(在FM下用来对UpdateFC的补充),其主要类型为InitFC1--InitFC2--UpdateFC
图1 InitFC1的DLLP格式
图2 InitFC2的DLLP格式
图3 UpdateFC的DLLP格式
图4 Optimixed_Update_FC
注意:DLLP中会包含专用和共享FC的标志位以及缩放系数
表1 Header和Data缩放编码表
Header/Data缩放值 | 是否支持缩放FC | 缩放系数 | HdrFC域 | DataFC域 |
---|---|---|---|---|
00b | 不支持 | 1 | HdrFC[7:0] | DataFC[11:0] |
01b | 支持 | 1 | HdrFC[7:0] | DataFC[11:0] |
10b | 支持 | 4 | HdrFC[9:2] | DataFC[13:2] |
11b | 支持 | 16 | HdrFC[11:4] | DataFC[15:4] |
1.1 InitFC1/InitFC2/UpdateFC
HdrFC域包含的是Header的credit,其中分三种类型,分别指定P/NP/CPL的credit
DataFC域包含的是数据负载的credit,其中分三种类型,分别指定P/NP/CPL的credit
如果支持Scaled FC的话,则HdrScale/DataScale域包含如表1所示的缩放系数,当然了也区分P/NP/CPL三种类型。反之如果不支持Scaled FC的话,则对应域为Reserved状态。并且如果传输的为Scaled FC的话,对应的域不可以为00b,只能为01b/10b/11b中的一种。
对UpdateFC来说,只支持传输不为00b的HdrScale和DataScale(如果支持Scaled FC并且其处于activated状态,即link两端的端口都置1 Loacl Scaled Flow Control Supported和Remote Scaled Flow Control Supported)
InitFC1和InitFC2只适用于VC的初始化
同样会检查数据完整性,如果失败则响应的credit会被丢弃。
1.2 Optimixed_Updata_FC
在FM下,需要额外支持Optimixed_Update_FC。其不包含HdrScale和DataScale域,所以transmitter和receiver需要采用在初始化期间协定的缩放值。为了调试和便于调试工具(如Logic analyzer)使用,device必须每10 μs发送至少一个DLLP(每个VC发送一个Update_FC DLLP),并带有缩放后的credit信息。协议中强烈建议,在VC之间的传输周期中,只要有相应的VC释放credit,就通过有限的非0 credit的Optimized_Update_FC来实现。
注意:如果上述四种类型的DLLP的对象为未使能的VC,则会被丢弃并且不产生任何影响。
2. FC Unit Size
FC Unit Size(以下用FCUS代指)表示的是一个FC credit覆盖的DW个数,可以认为是credit的DW单位大小。
对数据来说,FCUS的大小为4DW
对NFM下的Header来说:
- 如果Receiver不支持End-End TLP Prefixes,FCUS是最大的Header和TLP Digest的和(4+1DW)
- 如果Receiver支持End-End TLP Prefixes,FCUS是最大的Header、TLP Digest和TLP允许的最大End-End TLP Prefix个数的和
- 对于支持Local TLP Prefixes的Receiver的FC的管理取决于Local TLP Prefix类型
对FM下的Header来说:
- 对Switch Port Receiver来说,FCUS是一个最大大小的Header Base,OHC-A,OHC-B,OHC-C,OHC-E如果支持的话和一个最大大小的TLP Trailer(4+7+2+1+1+1+1DW)
- 对Ep上游端口和RP Receiver来说FCUS是一个Header Base支持的最大大小,OHC-A,OHC-B,OHC-C,OHC-E如果支持的话和支持的TLP Trailer的最大大小的和
3.其他规则
对FM下的专用Credit或者NFM,其每个VC都有独立的FC
在FM下,每个VC都有一定的独立FC指向专用Credit,还有部分指向共享Credit。但是当只实现了一个单独的VC并且不使用Merge时,其没有专用Credit,全部的FC均使用共享Credit。注意即便是存在足够的共享Credit的情况下,也允许Transmitter使用专用Credit(存在可用的Credit情况下)来进行TLP的传输。Transmitter通过置1 Flit Mode Local TLP Prefix中的TLP Used Dediacted Credits比特位来表示当前TLP采用专用Credit,如果此位位使能或者不存在TLP Prefix则必须采用共享Credit来传输此TLP。
参考TLP的排序类型,FC也采用三种不同的类型来区分管理,分别为:
- Posted Request(P)--消息和Memory写
- Non-Posted Request(NP)--所有读/IO写/配置写/原子操作和DMWr
- Completion(CPL)--跟NP请求对应的完成包
此外针对上述三种类型FC还将其均区分为如下两种类型:Headers(H)/Data(D)。所以一共存在六种类型,分别为PH/PD/NPH/NPD/CPLH/CPLD
每种类型的TLP包消耗的Credit如表2所示。
表2 TLP FC Credit消耗示例
TLP | 消耗的Credit |
Memory/IO/配置读请求 | 1 NPHU(U表示Unit) |
Memory写请求 | 1 PHU+ n PDU(n表示length/FCUS的向上取整结果,注意长度的单位为DW) |
IO/配置写请求 | 1 NPHU+1 NPDU(注意这里length不超过1DW) |
原子操作/DMWr请求 | 1 PHU+ n PDU |
不携带数据的消息请求 | 1 PHU |
携带数据的消息请求 | 1 PHU+ n PDU |
Memory读完成 | 1 CPLHU+ n CPLDU |
IO/配置读完成 | 1 CPLHU+ 1 CPLDU |
IO/配置写/DMWr完成 | 1 CPLHU |
原子操作完成 | 1 CPLHU+ 1 CPLDU(注意完成包的数据不超过4DW) |
对VC0的FC初始化必须由硬件自动初始化,一般来说VC0的初始化开始于复位后-数据链路层处于DL_Init状态。如果软件使能了其他的VC(通过在link两端置1 VC Enable比特位)则由数据链路层按照如下章节进行初始化(允许多个VC同时进行FC初始化,每个都是独立的进程)。如果软件失效link两端的VC(在FM下,先失效然后在link_up期间又重新使能,这种情况下VC的行为是未定义的),则会重置VC中的FC跟踪机制,此外在FM下只会影响专用FC Credit的跟踪并不会影响共享FC Credit的追踪。
协议中建议按照表3的内容初始化VC Credit值(大于或等于),如果不支持Scaled FC或者支持但是激活的话,采用表中“缩放系数1”中的值,如果Scaled FC支持并被激活的话,则使用表中对应缩放系数中的值。如果是多功能设备(不同的Function包含不同的Rx_MPS_Limit)则采用最大的Rx_MPS_Limit。
表3 初始化FC的建议最小值
Credit类型 | 最小建议值 | ||
无缩放/缩放系数1 | 缩放系数4 | 缩放系数16 | |
PH | 1个单位 FM下的共享Credit为4个单位 | 4个单位 | 16个单位 |
PD | 向上取整(Rx_MPS_Limit/FCUS) FM下的共享Credit为向上取整(Rx_MPS_Limit/FCUS)+4 | 向上取整(Rx_MPS_Limit/(FCUS*4))+1 | 向上取整(Rx_MPS_Limit/(FCUS*16))+1 |
NPH | 1个单位 FM下的共享Credit为4个单位 | 4个单位 | 16个单位 |
NPD | 向上取整(Rx_NP_MPS_Limit/FCUS) FM下的共享Credit为向上取整(Rx_NP_MPS_Limit/FCUS)与4的最大值+4 | 向上取整(Rx_NP_MPS_Limit/(FCUS*4))+1 | 向上取整(Rx_NP_MPS_Limit/(FCUS*16))+1 |
CPLH | RC(在RP之间支持peer-to-peer流量)和Switch:1 FCU;FM下的共享Crdit为4FCU RC(在RP之间不支持peer-to-peer流量)和Ep:无限FCU 在FM下,如果使能Merge,CPLH在共享池中使用 | RC(在RP之间支持peer-to-peer流量)和Switch:4 FCU RC(在RP之间不支持peer-to-peer流量)和Ep:无限FCU 在FM下,如果使能Merge,CPLH在共享池中使用 | RC(在RP之间支持peer-to-peer流量)和Switch:16 FCU RC(在RP之间不支持peer-to-peer流量)和Ep:无限FCU 在FM下,如果使能Merge,CPLH在共享池中使用 |
CPLD | RC(在RP之间支持peer-to-peer流量)和Switch: 向上取整(Rx_MPS_Limit/FCUS) FM下的共享Credit为向上取整(Rx_MPS_Limit/FCUS)和4之间的最大值+4 RC(在RP之间不支持peer-to-peer流量)和Ep:无限FCU 在FM下,如果使能Merge,CPLH在共享池中使用 | RC(在RP之间支持peer-to-peer流量)和Switch: 向上取整(Rx_MPS_Limit/(FCUS*4))+1 RC(在RP之间不支持peer-to-peer流量)和Ep:无限FCU 在FM下,如果使能Merge,CPLH在共享池中使用 | RC(在RP之间支持peer-to-peer流量)和Switch: 向上取整(Rx_MPS_Limit/(FCUS*16))+1 RC(在RP之间不支持peer-to-peer流量)和Ep:无限FCU 在FM下,如果使能Merge,CPLH在共享池中使用 |
表3中的相关解释:
- 无限FCU简单理解就是Transmitter永远不会对齐进行限流,包括无限Header和无限Data
- Rx_NP_MPS_Limit表示的是Receiver接收的最大NP TLP Payload大小。大于:
任意TLP类型支持的最大负载大小
支持DMWr路由能力或者DMWr完成能力的Receiver:
DMWr Rquest Routing Supported置1--128Bytes(8 credit unit)
DMWr Rquest Routing Supported置0&&DMWr Completer Supported置1&&DMWr Lengths Support 置00b--64Bytes(4 credit unit)
DMWr Rquest Routing Supported置0&&DMWr Completer Supported置1&&DMWr Lengths Support 置非00b--128Bytes(8 credit unit)
支持原子操作路由能力或者原子操作完成能力的Receiver:
AtomicOp Routing Supported置1:32Bytes(2 credit unit)
AtomicOp Routing Supported置0&&128-bit CAS Completer Supported置0:16Bytes(1 credit unit)
AtomicOp Routing Supported置0&&128-bit CAS Completer Supported置1:32Bytes(2 credit unit)
16Bytes(1 credit unit)
在FM下,初始化的共享Credit的建议值(包括任意Credit类型)必须为如下的其中一种:
- 对所有VC来说建议均为DataScale/HdrScale=00b(DataFC/HdrScale为0)
- 对所有VC来说建议为DataScale/HdrScale=01b或者非DataScale/HdrScale=01b的组合
对如上的第二种的补充说明:
- 如果支持多VC的话,允许对所有VC建议ataScale/HdrScale=01b的共享Credit
- 所有建议非DataScale/HdrScale=01b的共享Credit必须具备相同的缩放系数
- 如果任意VC建议使用非DataScale/HdrScale=01b的共享Credit则所有使用非DataScale/HdrScale=01b的共享Credit的VC在之后的UpdateFC中必须使用相同的缩放系数;所有VC之间的Credit总和必须大于等于表3中的值*VC个数(如使用MergeFC的话,则为3中的值*VC个数*2),表3中的值为单个VC所建议的最小值;
在FM下,专用Credit允许在任一VC上对任一Credit类型使用任一缩放系数
Receiver不支持Scaled FC必须不累计超过2047(data)或者127(header)未完成未使用的credit给Transmitter,对支持Scaled FC则不能超过如表3中最大Credit值所示的值。
如果在初始化过程中采用了Infinite.1/2/3的话,则不需要在之后的初始化过程中产生FC Update
注意:FM跟NFM下的DLLP格式不相同,简单理解就是FM下的DLLP不包含16bit的CRC,但是对NFM下所有的DLLP均包含16-bit CRC;另外在此不讨论MR-IOV,之后单独章节介绍。
三、Data Link Layer FC初始化
在上电或者内部复位完成后要开始正常操作前,有必要对默认VC(即VC0)进行FC初始化操作。此外,如果使能了别的VC的话,FC需要在每个新使能的VC被使用前进行初始化。在FM下共享的FC是使能的,在NFM下则是失效的。对FC初始化来说,其存在两个状态,分别FC_INIT1和FC_INIT2。
1.FC_INIT1
在任意VC的FC初始化过程中的任意时间点,如果对应VC被disable的话,则其FC初始化过程中断。
进入FC_INIT1状态:进入数据链路层状态--DL_Init并且软件配置VC使能
在FC_INTI1状态中:
- 事务层必须阻塞使用初始化VC的传输;
- 在NFM下按照如下顺序进行三种类型的DLLP的传输--InitFC1-P(专用,顺序第一个)/InitFC1-NP(专用,顺序第二个)/InitFC1-CPL(专用,顺序第三个);
- 在NFM下则为6种--InitFC1-P(专用,顺序第一个)/InitFC1-NP(专用,顺序第二个)/InitFC1-CPL(专用,顺序第三个)/InitFC1-P(共享,顺序第四个)/InitFC1-NP(共享,顺序第五个)/InitFC1-CPL(共享,顺序第六个);
- 以上的几种DLLP必须在每间隔34微秒进行一次传输,此时间不受花费在LTSSM中的Rcovery或者Configuration状态上的影响,并且强烈建议频繁的传输此类DLLP,特别是在没有可用于传输的TLP或者DLLP时;
- 除非是需要达到InitFC1 DLLP传输的最低频率要求,数据链路层不可以阻塞其他传输(包括物理层的初始化传输--OS/Ack和Nak DLLP/之前完成初始化的VC的TLP传输);
- 在接收到InitFC1和InitFC2 DLLP后进行的操作:记录HdrFC和DataFc值;如果Receiver支持Scaled FC,记录HdrScale和DataScale;在每个P/NP/CPL的FC unit值被记录后置1 FI1(在NFM下需要三种均被记录后拉高,FM则为六种均被记录后)
退出到FC_INIT2状态:FI1表示被拉高
2.FC_INIT2
在FC_INIT2状态中:
- 事务层必须阻塞使用初始化VC的传输;
- 在NFM下按照如下顺序进行三种类型的DLLP的传输--InitFC2-P(专用,顺序第一个)/InitFC2-NP(专用,顺序第二个)/InitFC2-CPL(专用,顺序第三个);
- 在NFM下则为6种--InitFC2-P(专用,顺序第一个)/InitFC2-NP(专用,顺序第二个)/InitFC2-CPL(专用,顺序第三个)/InitFC2-P(共享,顺序第四个)/InitFC2-NP(共享,顺序第五个)/InitFC2-CPL(共享,顺序第六个);
- 以上的几种DLLP必须在每间隔34微秒进行一次传输,此时间不受花费在LTSSM中的Rcovery或者Configuration状态上的影响,并且强烈建议频繁的传输此类DLLP,特别是在没有可用于传输的TLP或者DLLP时;
- 除非是需要达到InitFC2 DLLP传输的最低频率要求,数据链路层不可以阻塞其他传输(包括物理层的初始化传输--OS/Ack和Nak DLLP/之前完成初始化的VC的TLP传输);
- 在接收到InitFC1和InitFC2 DLLP后进行的操作:忽略收到的HdrFC/HdrScale/DataFC/DataScale值;对收到的每个InitFC2 DLLP拉高FI2标志;
- 在VC上接收到的任意TLP/UpdateFC DLLP/在FM下的Optimized_Update_FC均拉高FI2标志
完成和退出状态:
- FI2标志被拉高;
- 如果链路上的Scaled FC被激活,则transmitter在VC上传输UpdateFC时必须包含01b/10b/11b的HdrScale和DataScale,相反并且不支持Scaled FC的情况下HdrScale和DataScale为00b
3.Scaled FC
Scaled Flow Control机制是用来解决因FC credit不足导致的链路性能影响,特别的是127header credit和2047data credit导致的在高速链路速度下的性能影响。所有端口都被允许支持Scaled Flow Control。端口如果支持16.0GT/s或者更高的速度则必须支持Scaled Flow Control。Scaled FC的激活不会影响16.0 GT/s和更高数据速率的运行能力。
当link上的Scaled FC没有被activate时需要遵循如下规则:
- InitFC1/InitFC2/UpdateFC DLLP必须包含值为00b的HdrScale和DataScale域
- HdrFC/DataFC为8bit/12bit,且包含所有bit位
当link上的Scaled FC被activate时需要遵循如下规则:
- InitFC1/InitFC2 DLLP必须包含值为01b/10b/11b的HdrScale和DataScale域,具体如表2所示。
表2 Scaled FC的缩放系数
缩放系数 | 是否支持并且激活Scaled FC | credit类型 | 最小credit | 最大credit | 域宽度 | FC DLLP域 | |
传输 | 接收 | ||||||
00b | 不支持 | Hdr | 1 | 127 | 8bit | HdrFC | HdrFC |
Data | 1 | 2047 | 12bit | DataFC | DataFC | ||
01b | 支持 | Hdr | 1 | 127 | 8bit | HdrFC | HdrFC |
Data | 1 | 2047 | 12bit | DataFC | DataFC | ||
10b | 支持 | Hdr | 4 | 508 | 10bit | HdrFC>>2 | HdrFC>>2 |
Data | 4 | 8188 | 14bit | DataFC>>2 | DataFC>>2 | ||
11b | 支持 | Hdr | 16 | 2032 | 12bit | HdrFC>>4 | HdrFC>>4 |
Data | 16 | 32752 | 16bit | DataFC>>4 | DataFC>>4 |
4. InitFC1/InitFC2选项
4.1 一些概念解释
- NFM并且no Scaled FC(DataFC或者Scaled FC为0):
Infinite.1--DataScale/HdrScale == 00b
Reserved--DataScale/HdrScale == 01b,10b,11b
- NFM并且Scale FC(DataFC或者Scaled FC为0):
Infinite.2--DataScale/HdrScale == 01b,10b,11b
Reserved--DataScale/HdrScale == 00b
- FM(DataFC或者Scaled FC为0):
Infinite.3--DataScale/HdrScale == 00b
Zero--DataScale/HdrScale == 01b
Merged--DataScale/HdrScale == 10b
Reserved--DataScale/HdrScale == 11b
- Extended VC Count:
此域表明发送端口支持的VC资源个数。此域只在FM下有效,在NFM下此域必须为0。其主要分成Local和Remote两类,但是两类均指向三个寄存器域,分别为:
Multi-Function Virtual Channel Extended Capability中的Extended VC Count:表明除默认VC外设备支持的VC个数。其最小值为零(表示设备值支持默认VC并且此VC只具备一个MFVC VC资源寄存器),最大值为7
Virtual Channel Extended Capability中的Extended VC Count:表明除默认VC外设备支持的VC个数。其最小值为零(表示设备值支持默认VC并且此VC只具备一个VC资源寄存器),最大值为7
Streamlined Virtual Channel Extended Capability中的Extended VC Count:表明除默认VC外设备支持的VC个数。其最小值为零(表示设备值支持默认VC并且此VC只具备一个SVC资源寄存器)
4.2 具体选项内容表格
表5 InitFC1/InitFC2选项--NFM
行 | Scaled FC支持并激活 | Local和Remot拓展VC计数 | Merged | InitFC个数 | 专用/共享 | DataScale和HdrScale | DataFC和HdrFC | Note |
---|---|---|---|---|---|---|---|---|
1 | No Scaled FC | 0(Reserved) | 不适用 | 3 | 0b(Reserved) | Infinite.1 | ||
00b | ≠0 | |||||||
2 | Scaled FC | 0(Reserved) | 不适用 | 3 | 0b(Reserved) | Infinite.2 | ||
{01b|10b|11b} | ≠0 |
表6 InitFC1/InitFC2选项--FM
4.3 表格Note解释
Note这里为标号(仅为观看舒适度不要与章节混合)
- for empty
- for empty
- 拓展VC计数为0,即仅支持1个VC。无专属Credit被分配,所有Credit均为共享
- 拓展VC计数为0,即仅支持1个VC。无专属NP Credit被分配,所有NP Credit均为共享
- 当Local≠0并且Remote=0时,行3和行4是被建议的,但是行9和行10是允许的
- Zero表示无额外的共享Credit被分配。所有共享Credit都被其他VC分配掉了(可以被该GC使用)。当超过一个VC通过缩放系数(01b/10b/11b)来采用了建议的共享Credit,那么不论VC均可以通过对应缩放系数访问到共享Credit。例如当VC0和VC1均采用了120Header Credit,那么其必须使用01b之外的缩放系数,因为此缩放系数对应的最大未完成个数为127(小于可以访问到的240个)。
Intinite.3表示VC之间的共享Credit均是一样的。如果其中一个VC使对给定的Credit类型使用Intinite.3,则剩余的VC也必须使用Intinite.3。此外使用01b/10b/11b的缩放系数在VC之间也必须是一样的,除非VC使用Zero
如果一个VC使用了Zero,那么至少一个VC使用了01b/10b/11b的缩放系数,并且此给定Credit类型必须使用非00b的缩放值(UpdateFC DLLP),包括在初始化期间被建议为Zero的VC。
允许所有VC使用Zero共享Credit,这样就只能使用专属Credit,也就是说每个TLP都需要包含一个Flit Mode Local TLP Prefix - 共享完成Credit的Merge表明共享完成和共享posted Credit共享Credit的同一个通用池。Merge不允许被使用在共享Posted或者共享Non-Posted Credit上。专属Credit永远不可以被Merge。此外Merge在VC之间也是一致的,只要有一个VC Merge了,那么所有的VC都必须Merge。此外其在Hdr和Data之间也是一致的。如果使用了Merge并且P Hdr/Data不是Infinite.3,那么CPLH/CPLD的UpdateFC必须采用跟PH/PD相同的缩放系数。如果使用了Merge并且P Hdr/Data不是Infinite.3,那么至少有一个VC使用非Zero P Hdr/Data共享Credit。
- 当Local≠0并且Remote=0时,行5到行8是被建议的,但是行11到行13是允许的
- TLP使用Flit Mode Local TLP Prefix,从而消耗额外的DW。在第3-4行,所有的Credit都是共享的。
- 为了避免死锁,Posted和Completion不允许是Zero。