转载地址:http://blog.chinaaet.com/justlxy/p/5100053465
在任何事务层包(TLP)发送之前,PCIe总线必须要先完成Flow Control初始化。当物理层完成链路初始化后,便会将LinkUp信号变为有效,告知数据链路层可以开始Flow Control初始化了。如下图所示:
注:由于VC0是默认使能的,所以当Flow Control初始化开始时,其会被自动的初始化。其他的Virtual Channel是可选的,只有当被配置为使能的时候才会被初始化。
Flow Control初始化被分为两个步骤,FC_Init1和FC_Init2,其在整个数据链路控制和管理状态机(Data Link Control & Management State Machine)的位置如下图所示:
在FC_Init1步骤中,PCIe设备会连续地发送三个InitFC1类型的Flow Control DLLP来报告其接收Buffer 的大小。三个DLLP的顺序是固定的:Posted、Non-Posted然后是Completions。如下图所示:
FC_Init2与FC-Init1类似,同样是连续的发送三个InitFC2类型的DLLP,当完成后,DLCMSM(上一篇文章中提到的状态机)会切换到DL_Active状态,表明数据链路层初始化完成。
注:可能有人会有疑惑了,FC_Init1和FC_Init2干的活不是差不多嘛,为什么还需要FC_Init2呢?原因是,不同的设备完成FC_Init1的时间可能是不同的,增加FC_Init2是为了保证每个设备都能收到FC初始化DLLP。
FC_Init DLLP的格式如下图所示:
在完成FC初始化之后,相邻的两个设备之间会周期性的通过Updated FC DLLP更新接收Buffer的大小。如下图所示:
Update FC DLLP的格式与FC_Init的格式是类似的,具体如下:
前面说到。Update FC DLLP是周期性发送的,周期的值可以通过以下公式计算得:
具体可以参考PCIe的Spec,这里不再详细介绍,下面给出Gen1和Gen2的周期表格(根据公式计算的结果)。其中AF为AckFactor。
注:Mindshare的书中,为了便于理解,把AckFactor一词修改为UpdateFactor,实际上指的是同一个东西。
Gen1 (2.5GT/s)如下表所示:
Gen2(5GT/s)如下表所示: