LJgibbs · 2022年12月22日

PCI Express Technology 3.0 链路初始化与训练 Configuration

14.6 Configuration State // 配置状态

设备初始化时,Configuration 状态在 2.5GT/s 速率下配置链路以及通道编号。5GT/s 和 8GT/s 速率时,设备也可能从 Recovery 状态进入 Configuration 状态。此时状态转换的主要目的是为了进行多通道设备的链路位宽动态转换。动态转换仅支持 5GT/s 和 8GT/s 速率的设备。这些高速率设备详细的状态转换过程将在原文 552 页开始的 “详细 Configuration 子状态” 一节中讨论。

14.6.1 Configuration 状态综述

本状态的主要目标是弄清楚设备端口(Port)和各个通道(Lane)的连接情况,以及为连接的通道分配通道编号。举例来说,对一个连接了 8 个通道的端口来说,可能只有其中的 2 个通道是可用的,再比如这些通道可以被组合为多条链路,比如组合成两个 x4 的链路(每个链路有 4 个通道),Configuration 状态的目的就是为了搞清楚这方面的信息。另外,和其他状态不同的是,端口在此状态的行为区分为面向上游端口或者面向下游端口两种情况,两类端口在 Configuration 状态中被定义为不同的角色。因此,在本状态中会分别讨论面向上游和下游通道的行为。

DSP (Downstream Port,向下游发送数据)端口在剩余的链路初始化过程中扮演 “领导者”,而 USP (Upstream Port,向上游发送数据)端口的角色是 “跟随者”。"领导者",也就是 DSP,会为 USP 确定链路以及通道的编号,USP 则只是简单地重复他接收到的值给 DSP,除非出现了编号冲突的情况,我们会在本节后续内容中讨论这种意外情况。Configuration 状态中,双方设备交换的 TS1 序列中会反映分配的链路以及通道编号,如原文 540 页的图 14-13 红圈部分所示,这两个数值域在被分配具体的数值前,使用填充符号(PAD symbol)作为占位符。

图 14-13 TS1/TS2 中链路编号和通道编号的编码示意图

14.6.2 设计支持链路合并的设备

设计者一般根据性能与成本的考虑,决定在一条链路上实现多少个通道。PCIe 链路支持多个窄链路聚合成一个更宽的链路,同样的,较宽的链路也可以分拆成多个窄链路。原文 541 页的图 14-14 中是一个有一个上游端口和四个 x2 下游端口的交换机。在本例中,这些通道也可以组成两个 x4 的链路。值得注意的是,PCIe 协议要求每个端口必须有作为一个 x1 链路工作的能力。

如图左侧可见,交换机内部包含 1 个面向上游的逻辑桥以及 4 个面向下游的逻辑桥。事实上,每个端口都需要一个逻辑桥,因此,交换机需要包含 4 个面向下游的逻辑桥,以支持 4 个面向下游的端口。然而,如果这个交换机如图右方式连接的话,那么剩下的两个逻辑桥就将不工作。在链路训练期间,每个 DSP 中的 LTSSM 将决定具体实现哪些其所支持的连接选项。

图 14-14 链路聚合(Link Merging),将通道聚合成更宽的链路

14.6.3 Configuration 状态训练示例

14.6.3.1 引言

在 Configuration 状态中,链路以及通道的编号工作由 DSP 作为 “领导者” 发起(比如根节点端口或者交换机的面向下游端口)。而终端(Endpoint)以及交换机面向上游端口无法发起这一过程,只能作为 “跟随者” 响应。接下来让我们通过一些示例,来使相关的概念更容易理解。

14.6.3.2 链路配置示例 1

如原文 543 页的图 14-15 所示,在这个例子中假定双方设备都只支持单个链路,但通道宽度可以是 x4,x2 或者 x1。通道编号分配在设备内部完成,必须从 0 开始连续编号。物理上的通道编号显示在图中所画的设备框内,而逻辑上的,或者说通告的(reported)通道编号,在 TS 有序集中反映。一般来说,逻辑和物理编号是一致的,但是也不尽然。

链路编号协商

  1. 考虑到本例中只支持一条链路,DSP(Downstream Port,向下游发送数据的端口)在所有通道上发送链路编号都为 'N' 的 TS1 有序集,这些 TS1 的通道编号都用 PAD 符号填充。
  2. 在配置状态中,USP(Upstream Port)起初发送链路编号和通道编号域都用 PAD 符号填充的 TS1,但是在接收到 DSP 发送的链路编号不为 PAD 符号的 TS1 后,USP 在所有已连接的通道上回复链路编号同样是 'N',通道编号用 PAD 符号填充的 TS1。基于 USP 的响应,DSP 的 LTSSM 识别到所有四个通道都发出了响应,并使用相同的链路编号 ‘N’ ,所以四个通道被配置为同一个链路。通道编号的值 'N' 是一个由具体实现决定的值,这个值不会保存在任何协议定义的寄存器中,并且与通道编号等其他值无关。

图 14-15 示例 1 中的 step1 与 step2

通道编号协商

  1. DSP 开始在各个通道上发送链路编号相同,但是为各通道各自分配了 0,1,2,3 通道编号的 TS1,如原文 544 页图 14-16 所示。
  2. 接收到通道编号不为 PAD 填充符号的 TS1 后,USP 在回复之前首先验证接收到的通道编号和自身物理编号一致。(译注:此处原文为 the Upstream Port will verify that the incoming Lane numbers match the Lane numbers they are received on.)在本例中,DSP 和 USP 的各个通道是正确连接的,编号验证无误,所以 USP 在各通道回复 DSP 的 TS1 中通告了自身的通道编号。当 DSP 接收到编号不为 PAD 符号的 TS1 后,将接收到的通道编号与发送的数值进行比较,如果他们匹配,则这一过程顺利完成。如果不匹配,那么需要采取后续措施,比如部分通道不匹配,而剩余通道匹配,那么链路宽度需要对应调整。如果通道间的连接顺序被颠倒了,那么需要 DSP 支持可选的通道顺序颠倒特性,因为这项特性是可选的,那么有可能会出现这么一种情况,通道连接顺序被颠倒,却没有任何一方的设备有能力将其纠正。这是一项重大的电路板设计失误,此时链路配置可能将无法完成。

图 14-16 示例 1 中的 step3 与 step4

确认链路与通道编号

  1. 因为 DSP 在所有通道上接收到的链路编号以及通道编号和发送数值一致,所以 DSP 开始发送 TS2 序列表示自己已经准备好确认协商结果,并且转移到下一个状态 L0,TS2 中的链路编号以及通道编号和协商结果一致。
  2. USP 在接收链路编号以及通道编号和协商结果一致的 TS2 后,也开始发送 TS2 序列表示自己同样做好离开 Configuration 状态,转移到下一个状态 L0,这个过程如原文 545 图 14-17 所示。
  3. 双方端口在收到至少 8 个 TS2 以及至少发送 16 个 TS2 后,发送一些逻辑空闲数据后,转移状态到 L0。

图 14-17 示例 1 中的 step5 与 step6

14.6.3.3 链路配置示例 2

第二个需要掌握的例子,首先还是那个有 4 个面向下游通道的设备,不过不同的是,这个例子中这个设备可以配置为单个 x4 链路,或者配置为两个 x2 链路的组合,或者配置为四个 x1 链路的组合,甚至还有一个 x2 链路和两个 x1 链路的组合,如原文 546 页图 14-18 所示。

如果四个通道全部检测到接收端存在,并全部进入 Configuration,那么就会有这么几种可能的连接:

  • 一个 x4 链路
  • 两个 x2 链路
  • 一个 x2 链路和两个 x1 链路
  • 四个 x1 链路

接下来描述的是协议中决定实施何种配置的一个示例方法。

链路编号协商

  1. 在本示例方法中,DSP 首先在每个通道上分配并通告(advertise)单独的链路编号。通道 0 上的链路编号是 N,通道 1 上就是 N+1,并以此类推。如原文 546 页图 14-18 所示,图中的链路编号只是一个例子,实际上他们可以是不连续的数字。另外,一件重要的事情是 DSP 此时并不知道和它连接的对端设备情况,在这个过程中 DSP 将尽力去搞清楚每个通道可实现的连接方式。

图 14-18 示例 2 中的 step 1

  1. 在收到 USP 返回的 TS1 序列后(译注:如图 14-19 所示,四个通道分成了两组,分别有不同的的链路编号),DSP 得到两个信息:所有四个通道都处于工作状态,并且它们分别连接到了两个 USP,也就意味当前的 DSP 将需要分为两个 DSP。每个 DSP 拥有 0 和 1 两个通道,如原文 548 图 14-20 所示。

图 14-19 示例 2 中的 step 2

通道编号协商

  1. 各个通道上的通道编号协商会独立进行,不过他们的过程是相同: DSP 会在发送的 TS1 中通告其分配给接收通道的通道编号。其中值得注意的是,此时 DSP 在 TS1 的链路编号域中,对于链路所有通道,只是简单地返回 USP 发送的链路编号值。左侧链路两个通道接收到的都是 N,而右边链路两个通道接收到的都是 N+2。
  2. 在本例中,左侧链路的 DSP 和 USP 之间的通道编号是对应的。但是右侧链路的通道连接则是相反的,DSP 的通道 0 连接到了 USP 的通道 1,另一条通道也是颠倒连接的。USP 在接收到 TS1 后意识到了通道连接颠倒的现象,如果 USP 支持链路编号颠倒功能的话,它会在内部交换通道 0 和 1 的编号,从而在返回给 DSP 的 TS1 中保持原本 DSP 提议的通道编号不变,如图 14-20 所示。如果 USP 并不支持这项特性,那么它会在返回的 TS1 中通告自己的物理通道编号情况(和 DSP 提议的通道编号顺序相反),这样一来 DSP 也能意识到这个问题,并有机会在 DSP 内部颠倒通道的逻辑编号来解决这个问题。
  3. 通道顺序颠倒是一项双方端口可选的特性。如果 USP 检测到通道编号颠倒,并有能力颠倒自己通道的逻辑编号,那么 USP 会在内部颠倒自己通道的逻辑编号,并返回通道编号不变的 TS1。这样一来,DSP 都不会意识到这个问题的存在。如果 USP 不支持这项功能,那么 DSP 会发现其接收到的 TS1 的通道编号相比它发送的 TS1 是颠倒的。如果 DSP 支持这项特性,那么它会纠正自身通道逻辑编号的顺序,并在 TS2 中发送纠正后的通道编号做为确认。

图 14-20 示例 2 中的 step 3、4、5

确认链路与通道编号

  1. DSP 在接收到链路编号和通道编号与所通告编号一致的 TS1 后,各个 DSP 端口独立地开始发送 TS2,作为它们已经准备好使用协商值,并进入 L0 状态的通知。
  2. USP 在收到链路和通道编号没有变化的 TS2 后,也可以发送相同的 TS2 序列。
  3. 双方端口在收到至少 8 个 TS2 以及至少发送 16 个 TS2 后,发送一些逻辑空闲数据后,转移状态到 L0。在本例中,右侧链路的 USP 进行了内部通道编号颠倒。

14.6.3.4 链路配置示例 3:如果通道配置失败

最后我们来再看看再配置过程中,某个通道如果不能正常工作会发生什么。这个例子基于 USP 的通道 2 不能正常工作,如原文 550 页图 14-21 所示。值得注意的是这个通道的问题并没有严重到断开物理连接,因为如果那样,DSP 将不会把它识别为接收端,并不会把它纳入链路。然而,即使通道的物理连接性没有问题,通道 2 的接收端或者发送端将无法完成配置工作。(或者两者都是)

在本例中,链路训练过程可能会显著变长,因为在大多数状态跳转过程中,都需要等待所有通道就绪,如果只有一部分通道就绪,剩下一些没有,那么就需要等待超时条件满足才能跳转状态。

接下来的步骤描述了通过 Configuration 状态机各子状态跳转,处理这种异常情况的过程。

链路编号协商

  1. 虽然 USP 通道 2 接收端存在问题,但是 DSP 在进入 Configuration 状态后还是按照流程行事。DSP 在所有通道上发送链路编号域为 'N',通道编号域填充的 TS1 序列。
  2. 通道 0、1、3 收到了 DSP 发送链路编号域为非填充值的 TS1,所以按照协议回复 DSP 相同的 TS1。然而,通道 2 因为接收故障,没能收到 DSP 发送的 TS1,所以通道 2 发送端继续发送链路编号和通道编号都为填充字符的 TS1,如原文 550 页图 14-21 所示。

图 14-21 示例 3 的 step 1 和 2

通道编号协商

  1. DSP 在收到通道 0、1、3 发送的带有相同链路编号的 TS1 后,开始等待通道 2 也完成同样的工作,直至超出协议规定的最大超时时间。如果此时通道 2 还是没有动作,那么 DSP 就会意识到这个链路只能被训练为 x2 宽度的链路。在接受这个现实情况后,DSP 会向通道 0 和 1 通告为他们分配的通道编号,但在通道 2 和 3 上只发送链路编号和通道编号都使用填充字符的 TS1。
  2. 当 USP 在通道 0 和 1 上收到携带有效通道编号的 TS1,而通道 3 上的链路编号又变回填充符号时,USP 回复相同的通道编号,而其他通道开始(指通道3,对于通道 2 则是继续)发送链路编号和通道编号都使用填充字符的 TS1,如原文 551 页图 14-22 所示。

图 14-22 示例 3 的 step 3 和 4

确认链路与通道编号

  1. 因为在通道 0 和 1 上收到的 TS1 通道和链路编号和预期匹配,所以 DSP 开始发送 TS2,作为它们已经准备好使用协商值,并进入 L0 状态的通知,通道和链路编号保持不变。而在其他通道上,则继续发送链路编号和通道编号都使用填充字符的 TS1。
  2. USP 在通道 0 和 1 上收到链路和通道编号没有变化的 TS2 后,也发送相同的 TS2 序列给 DSP,表示愿意结束协商,进入 L0 状态。而在其他通道上继续发送链路编号和通道编号都使用填充字符的 TS1,如原文 552 页图 14-23 所示。

图 14-23 图 14-22 示例 3 的 step 5 和 6

在双方端口在收到至少 8 个 TS2 以及至少发送 16 个 TS2 后,发送一些逻辑空闲数据后,转移状态到 L0。其他未完成配置的通道,如本例中的通道 2 和 3,转为电气空闲状态,直到下一次 DSP 发起链路训练操作,那个时候会继续尝试正常的训练过程,以期故障排除并完成配置。

14.6.4 Configuration 状态各子状态详细讨论

本小节将详细讨论 Configuration 各子状态,其如原文 553 页图 14-24 所示。在前一小节讨论过链路训练的例子之后,这些子状态应该很容易理解。

图 14-24 Configuration 状态机

14.6.4.1 Configuration.Linkwidth.Start

有两种情况会进入该状态,一种是 Polling 状态正常结束跳转(在原文 527 页 “Polling.Configuration” 详述),另一种则是在 Recovery 状态中发现链路或者通道编号相较于前次指定时发生了变化,因此无法正常完成 Recovery 状态时跳转(在原文 571 页 “Recovery State” 详细描述了这种状态)。

A. Downstream 通道

Configuration.Linkwidth.Start 期间

DSP (Downstream Port)将作为链路的发起者(Leader),在所有工作的通道上发送链路编号不为填充符号的 TS1 序列(仅在 LinkUp 标志尚未置起,以及链路宽度的配置尚未进行时)。TS1 中的链路编号虽然从填充符号变成了有效编号,但是通道编号仍然尚为填充符号。协议中对链路编号具体数值的唯一规定是:如果设备支持多通道,那么分配给不同链路的编号不能相同。举例而言,一个 x8 宽度链路在所有 8 个通道上的链路编号一致,但是如果其能够被配置为两个 x4 链路, 4 个通道一组,两组通道间的链路编号需要不同,比如一组的编号是 5,另一组的编号是 6。链路编号的数值是两个链路伙伴之间的本地值,软件无需追踪所有链路的编号数值,也没有必要使整个系统中的所有链路编号值保持不同。

如果 upconfigure_capable 标志被设置为 1b, 那么也会在不工作的通道上发送 TS1,只要在这些通道上曾经收到过两个连续的链路和通道编号为填充符号的 TS1。

  • 从 Polling 状态进入此子状态时,所有检测到接收端的通道会被视作工作通道(Active Lane)。
  • 从 Recovery 状态进入此子状态时,所有历经 Configuration.Complete 状态的链路上的通道,都会被视作工作通道(Active Lane)。
  • DSP 必须在发送的 TS1 中通告自身所有支持的速率,其中也需要包括端口不打算使用的速率。

Crosslinks 交叉链路. 对于支持交叉链路特性的 DSP 来说,当 LinkUp = 0b 时,需要在所有检测到接收端的通道上至少发送 16-32 个 TS1,其中链路编号非填充符号,而通道编号是填充符号。之后,DSP 将根据接收到的内容判断对端是否存在交叉链路。

Upconfiguring the Link Width 恢复链路宽度. 在 LinkUp = 1b 时,如果 LTSSM 想要恢复较大的链路宽度,那么会在所有当前工作的通道上、想要激活的非工作通道以及接收到 TS1 的通道上,发送链路编号和通道编号使用填充符号填充的 TS1。当 DSP 在某个通道上接收到两个连续的 TS1 回复后,延时 1ms,然后发送指定链路编号的 TS1。

  • 在激活不工作的通道时,发送端必须等待发送共模电压(Tx common mode voltage)稳定,才能退出电气空闲状态并开始发送 TS1。
  • 对于组合为同一链路的通道,他们的链路编号必须相同。只能在支持多链路配置的不同链路之间分配不同的链路编号。

进入“在未满足以下任何有效跳转条件时,则触发 24ms 超时” 状态

任何收到过至少一个链路和通道编号均为填充符号的 TS1 序列的通道,如果现在收到两个连续的链路编号有效,而通道编号仍然为填充符号的 TS1,那么 LTSSM 将退出至 Configuration.Linkwidth.Accept 子状态。

退出至 ”Configuration.Linkwidth.Start“ 状态

如果 DSP 接收到的第一批 TS1 中,链路编号就已经不是填充符号了,那么 DSP 通过这种现象就意识到存在交叉链路(Crosslink),链路对端设备此时也是 DSP。针对这种情况,面向下游的通道将转换为面向上游通道,DSP 等待长度随机的超时时间后,重新进入 Configuration.Linkwidth.Start 状态,只不过此时该通道将变成面向上游的通道。

这项特性支持链路双方都是 DSP 的情况,是一种可选配的特性。解决办法是将双方都从 DSP 转换成 USP,并为双方指定一个长度随机的超时。在超时结束后,将超时端口转换为 DSP。因为双方的超时时间长度是不同的,最终将有一个端口成为 DSP ,而另一个端口仍然是 USP,这样一来训练就可以继续进行。超时时间长度必须是随机,这样即使链路双方的端口实现完全相同,也不会出现死锁的情况。

如果支持交叉链路特性,那么在接收的 TS1 的链路编号从 PAD 转换到非 PAD 符号的过程中,不允许出现 TS2 打断这个过程。

退出至 Disable 状态

如果端口受到更高层逻辑的指示,发送 Disable Link 比特置位的 TS1 或者 TS2,那么将退出至 Disable 状态。一般来说这个过程是由 DSP 发起的,但是在可选支持 Crosslink 的场景中,这可能是由 USP 发起的。DSP 在收到连续两个 Loopback 比特置位(译注:原文如此,应该是 Disable 比特置位)的 TS1 后,下一个状态将跳转为 Disable 状态。

退出至 Loopback 状态

如果支持 Loopback 的发送端受到更高层逻辑的指示,发送 Loopback 比特置位的 TS1 或者 TS2,或者正在发送 TS1 的通道收到连续两个 Loopback 比特置位的 TS1 后,将退出至 Loopback 状态。任意发送 Loopback 比特置位的端口将变成 Loopback master,而收到他们的端口将变成 Loopback slave。

退出至 Detect 状态

如果在 24ms 超时到期后,仍然没有任何满足有效跳转条件,那么退出至 Detect 状态。

B. Upstream 通道

Configuration.Linkwidth.Start 期间

USP (Upstream Port) 在该状态是链路训练的响应者(follower),开始发送链路编号和通道编号为填充字符的 TS1。USP 持续发送 TS1 直至接收到 DSP(链路训练发起者,leader)链路编号不为填充字符的 TS1。

USP 会在三类通道上发送链路编号和通道编号为填充字符的 TS1,分别是:

  1. 所有工作通道(active lane)
  2. USP 想要恢复链路宽度(upconfigure)而配置的通道
  3. 所有曾经接收到过连续两个链路编号和通道编号为填充字符的 TS1 的非工作状态(inactive)通道,当变量 upconfigure\_capable 为 1 时。

另外注意:

  • 从 Polling 状态进入此子状态时,所有检测到接收端的通道会被视作工作通道(Active Lane)。
  • 从 Recovery 状态进入此子状态时,所有历经 Configuration.Complete 状态的链路上的通道,都会被视作工作通道(Active Lane)。如果此时的状态跳转不是由 LTSSM 超时触发的,那么此时发送方应该在 Configuration 状态中发送的 TS1 中置位 Autonomous Change 比特 (Symbol 4, bit 6) ,表示发送方出于自身(Autonomous )原因想要改变链路宽度,从而进入 Configuration 状态。
  • DSP 必须在发送的 TS1 中通告自身所有支持的速率,其中需要包括端口不打算使用的速率。

Crosslinks 交叉链路. 对于支持交叉链路特性的 USP 来说,当 LinkUp = 0b 时,需要在所有检测到接收端的通道上至少发送 16-32 个 TS1,其中链路编号和通道编号采用填充符号。之后,USP 将根据接收到的内容判断对端是否存在交叉链路。

进入“在未满足以下任何有效跳转条件时,则触发 24ms 超时” 状态

如果一些通道接收到了两个连续的链路编号有效,通道编号为填充符号的 TS1,那么这个端口就会进入 Configuration.Linkwidth.Accept 子状态,USP 选取其中一个接收到的链路编号作为这些通道的链路编号,并在所有收到链路编号非空的 TS1 的通道上,回复采用该链路编号的 TS1,通道编号继续使用填充字符。对于剩下的通道,如果他们检测到了接收方,但是还没有收到链路编号,那么则发送链路编号和通道编号都采用填充符号的 TS1。

  • 如果 USP 打算恢复链路宽度,LTSSM 首先等待下述两个条件任意满足一个:
  • 所有待激活的通道上都接收到两个连续的链路编号有效,通道编号为填充符号的 TS1
  • 任意一个待激活通道进入本状态超过 1ms

接着,USP 开始发送链路编号为选定的有效编号,通道编号为填充符号的 TS1。

  • 为了避免将链路的宽度配置小于正常宽度,协议建议如果在多通道链路上发现某些通道出现错误或者失去 Block Alignment 状态,那么延迟一段时间后再进行本过程。8b/10b 编码时等待至少 2 个 TS1,128b/130b 编码时至少等待 34 个 TS1,但任何情况下不要等待超过 1ms。
  • 在激活不工作的通道后,发送端必须等待发送共模电压(Tx common mode voltage)稳定,才能退出电气空闲状态并开始发送 TS1。

退出至 ”Configuration.Linkwidth.Start“ 状态

在等待 Crosslink 规定的超时时间后,发送 16 到 32 个 TS2,其中链路编号和通道编号采用填充符号。之后,Upstream 链路转换为 Downstream 链路,下一个状态仍然是 Configuration.Linkwidth.Start 状态,但链路双方的角色已经反转了。此情形用于支持 Crosslink 的情况下,两个 USP 相连的情况,该过程允许其中一个 USP 转而成为 DSP。

退出至 Disable 状态

如果下列条件中任意一项满足,那么退出至 Disable 状态:

  • 任意正在发送 TS1 的通道收到了 Disable link 比特为 1 的 TS1。
  • 支持选配特性 crosslink 时,所有通道连续收到两个 Disable link 比特为 1 的 TS1,或者链路其中一方被高层软件关闭链路,使其在所有检测到接收方的通道上发送的 TS1 和 TS2 中,置位 Disable link 比特。

退出至 Loopback 状态

译注:加粗部分为 USP 和 DSP 不同之处

如果支持 loopback 的发送端受到更高层逻辑的指示,发送 Loopback 比特置位的 TS1 或者 TS2,或者所有正在发送以及接收 TS1 的通道收到连续两个 Loopback 比特置位的 TS1 后,将退出至 Loopback 状态。任意发送 Loopback 比特置位的端口将变成 Loopback master,而收到他们的端口将变成 Loopback slave。

退出至 Detect 状态

如果在 24ms 超时到期后,仍然没有任何满足有效跳转条件,那么退出至 Detect 状态。

14.6.4.2 Configuration.Linkwidth.Accept

此时,USP 正在其所有通道上发送 TS1 进行回应,所有通道上的 TS1 中的链路编号都保持一致。链路编号来自于 DSP 的倡议,USP 直接在所有通道的 TS1 中反应了该链路编号值。这样一来 DSP 通过计算有多少通道响应该链路编号值,明确了链路宽度。接下来 DSP 需要发起提议,为这些通道指定各自的通道编号。所以 DSP 作为训练的主导者(leader),继续发送 TS1 序列,不过此时各通道的 TS1 各自携带有为其指定的通道编号值,而不再是填充符号。当然,这些 TS1 的链路编号仍然是相同的。接下来本节详细讨论 DSP 和 USP 在该状态的行为。

A. Downstream 通道

Configuration.Linkwidth.Accept期间

DSP 提议通道编号值。如果一条链路可以由多个通道合并组成,这些通道都可以收到两个连续的,链路编号值相同的 TS1,那么 DSP 会为他们发送链路编号一致,但是通道编号各不相同的 TS1。

退出至 ”Configuration.Lanenum.Wait“ 状态

DSP 不会在 Configuration.Linkwidth.Accept 子状态长时间停留。一旦 DSP 收到了 USP 发送的必须数量的 TS1,明确了链路宽度之后,DSP 会更新一些必须的内部状态,开始如上一段所述,发送通道编号不为填充字符的 TS1,并立刻转为 Configuration.Linkwidth.Wait 状态,等待 USP 确认通道编号分配。

B. Upstream 通道

Configuration.Linkwidth.Accept期间

USP 在从 DSP 提供的链路编号中选择其中一个,填充至所有通道的 TS1 中,反馈发送给 DSP。这里所有通道指的是那些所有接收链路编号不为填充字符 TS1 的通道。在所有剩余的通道中,如果检测到对端接收方,但是没有接收到有效链路编号的通道,将继续发送链路编号和通道编号采用填充符号的 TS1。

退出至 ”Configuration.Lanenum.Wait“ 状态

USP 必须对 DSP 提出的通道编号分配做出响应。如果一个链路可以由多个发送链路编号非填充字符 TS1 的通道合并组成,并且它们接收到两个连续 TS1,其中链路编号相等,通道编号不为填充字符,那么 USP 应该在可行的情况下,发送通道编号相同的 TS1 表示接受分配,或者在必要的时候回应不同的编号值提议。(比如应用了选配的通道顺序翻转特性时)

14.6.4.3 Configuration.Lanenum.Wait

在讨论 Configuration.Lanenum.Wait 状态之前,本节将首先提供一些帮助性的背景知识。链路通道的编号方式,是从 0 到这条链路所支持的最大编号。比如说一个 x8 链路,将会把它的通道编号为 0-7。端口需要支持链路容纳其所拥有的最大通道数,也需要支持链路容纳最少至一个通道。通道总是从 0 开始编号,并且需要是连续编号不中断的。比如,如果一个 x8 链路上有些通道不工作,它可能可以转而配置成一个 x4 链路,这种情况下它必须使用通道 0-3。再举一个例子,如果是链路的通道 2 无法正常工作,无法使用通道 0,1,3,4 组成一个 x4 链路,因为它们的编号是不连续的。链路上任何剩余的通道必须发送链路和通道编号都使用填充符号的 TS1。

协议在 Configuration 状态部分多次强调了一项时序要求,本节不再多次重复这一部分,但需要意识到这项限制对 DSP 和 USP 都有效:

为了避免将链路的宽度配置小于正常宽度,协议建议如果在多通道链路上发现某些通道出现错误或者失去 Block Alignment 状态,那么延迟一段时间后再进行本过程。8b/10b 编码时等待至少 2 个 TS1,128b/130b 编码时至少等待 34 个 TS1,但任何情况下不要等待超过 1ms。

退出至 Detect 状态

如果没有链路能够被配置(比如 lane0 不工作,且通道翻转没有启用时),或者所有通道接收到两个连续的 TS1,其链路和通道编号都为填充符号,那么在 2ms 之后触发超时,链路返回 Detect 状态。

A. Downstream 通道

Configuration.Lanenum.Wait期间

在 Configuration.Lanenum.Wait 状态期间,DSP 会继续发送链路和通道编号为非填充值的 TS1,直至满足某个跳转到其他状态的条件。

退出至 ”Configuration.Lanenum.Accept“ 状态

如果下述两个条件之一满足,那么跳转到 Configuration.Lanenum.Accept 状态:

  • 如果在所有通道上都接收到连续两个 TS1,它们携带的链路和通道编号都和 DSP 在这些通道上发送的一致。
  • 如果在任意一个检测到接收方的通道上,接收到连续两个 TS1,它们的通道编号和刚进入本状态时接收到的 TS1 中的数值不一致,并且至少有一些通道接收到了有效的链路编号。协议指出这种情况是通信双方达成了一致,确定了双方都能够接收的链路宽度。

退出至 Detect 状态

触发了上述的 2ms 超时事件,或者所有通道接收到两个连续的 TS1,其链路和通道编号都为填充符号。

B. Upstream 通道

Configuration.Lanenum.Wait期间

在 Configuration.Lanenum.Wait 状态期间,USP 会继续发送链路和通道编号为非填充值的 TS1,直至满足某个跳转到其他状态的条件。

退出至 ”Configuration.Lanenum.Accept“ 状态

如果下述两个条件之一满足,那么跳转到 Configuration.Lanenum.Accept 状态:

  • 如果在所有通道上都接收到连续两个 TS2。
  • 如果在任意一个检测到接收方的通道上,接收到连续两个 TS1,它们的通道编号和刚进入本状态时接收到的 TS1 中的数值不一致,并且至少有一些通道接收到了有效的链路编号。协议指出这种情况是通信双方达成了一致,确定了双方都能够接收的链路宽度。

退出至 Detect 状态

触发了上述的 2ms 超时事件,或者所有通道接收到两个连续的 TS1,其链路和通道编号都为填充符号。

14.6.4.4 Configuration.Lanenum.Accept

A. Downstream 通道

Configuration.Lanenum.Accept期间

DSP 已经在上一个状态中接收到了链路和通道编号为非填充值的 TS1。在本状态中,DSP 必须决定是否能够按照 USP 返回的通道编号顺序建立一条链路。下面列出了三种可能的状态跳变方式。

退出至 ”Configuration.Complete“ 状态

如果 DSP 在所有通道上都接收到连续两个 TS1,它们携带的链路和通道编号都和 DSP 在这些通道上发送的数值一致,那么代表 USP 同意了 DSP 通告的链路编号和通道编号,DSP 随之进入 Configuration.Complete 状态。如果 DSP 接收到的通道编号顺序与通告的顺序相颠倒,如果 DSP 支持通道顺序颠倒,那么 DSP 同样进入 Configuration.Complete 状态,并采用接收到的,颠倒的通道编号顺序。

值得注意的是,协议指出通道编号顺序颠倒的条件是限定的,只能是通道 0 接收到最大的通道编号 (假设通道数目为 N,那么收到的即为 N-1),通道 N-1 接收到通道编号为 0。这项协议规定可以回答一个在课堂上经常被学生问到的一个问题:通道编号是否能够混编,不按顺序?答案是不行,它们的顺序必须是 0 到 n-1,或者是 n-1 到 0,不支持其他选项。

如果是从 Recovery 状态进入的 Configuration 状态,那么在配置过程中可能被要求改变带宽。如果这样,那么需要置位相应的状态标志位来标识需要改变带宽的原因。主要是系统需要报告带宽改变是因为链路可靠性问题导致的,还是因为硬件正在管理链路的电源状态导致的。状态标识位的几种情形如下所述:

  • 如果带宽改变由 DSP 因为链路的可靠性问题发起,那么链路带宽管理状态比特(Link Bandwidth Management Status bit)设置为 1'b1。
  • 如果带宽改变不是由 DSP 发起,而是因为 DSP 连续收到两个自主改变(Autonomous Change )比特为 1'b0 的 TS1,那么链路带宽管理状态比特(Link Bandwidth Management Status bit)设置为 1'b1。
  • 除此之外的链路带宽改变,链路自主带宽状态比特(Link Autonomous Bandwidth Status bit)置位为 1'b1。

退出至 ”Configuration.Lanenum.Wait“ 状态

如果一条正在被配置的链路可以由一部分而不是全部的可用通道组成,这些通道都收到连续两个 TS1 ,链路编号为相同有效的数值,并且通道编号也不为填充符号。那么在这部分通道上发送链路编号相同,通道编号重新编制的 TS1,旨在用更少数量的通道来编成一条链路。

新的通道编号必须从 0 开始顺序递增,指派给链路所使用的通道。任何没有接收到 TS1 的通道不能成为链路的一部分,并且中断通道编号递增。举例而言,如果共有 8 条通道,但是通道 2 没有接收到 TS1,那么这组通道将不能组成包括通道 2 的链路。这样一来,不能组成 x8 或者 x4 的链路,只能组成 x2 或者 x1 的链路。剩下不使用的通道,必须在其上发送链路和通道编号都为填充符号的 TS1。

退出至 Detect 状态

如果没有链路可以被配置,或者所有通道接收到两个连续的 TS1,其链路和通道编号都为填充符号。

B. Upstream 通道

Configuration.Lanenum.Accept期间

USP 已经在上一个状态中接收到了链路和通道编号为非填充值的 TS1 或者 TS2。在本状态中,USP 必须决定是否能够按照 DSP 提议的通道编号顺序建立一条链路。下面列出了三种可能的状态跳变方式。

退出至 ”Configuration.Complete“ 状态

如果 USP 在所有通道上都接收到连续两个 TS2,它们携带的链路和通道编号都和 USP 在这些通道上发送的 TS1 中的数值一致,那么USP 进入 Configuration.Complete 状态。

退出至 ”Configuration.Lanenum.Wait“ 状态

如果一条正被配置的链路可以由一部分可用通道的子集组成,这些通道都收到连续两个 TS1 ,链路编号为相同有效的数值,并且通道编号也不为填充符号。那么在这部分通道上发送链路编号相同,通道编号重新编制的 TS1,旨在用更少数量的通道来编成一条链路,并跳转至 Configuration.Lanenum.Wait 状态。

和 DSP 时的情形一样,新的通道编号必须从 0 开始顺序递增,指派给链路所使用的通道。任何没有接收到 TS1 的通道不能成为链路的一部分,并且中断通道编号递增。剩下不使用的通道,必须在其上发送链路和通道编号都为填充符号的 TS1。

退出至 Detect 状态

如果没有链路可以被配置,或者所有通道接收到两个连续的链路和通道编号都为填充符号的 TS1。

14.6.4.5 Configuration.Complete

Configuration.Complete 是唯一的 TS2 序列交换的状态。正如前文讨论的那样,TS2 交换是链路两端的设备间,互相确认已经准备好状态跳转的握手确认机制。这是对先前状态中 TS1 序列交换的链路编号以及通道编号的最终确认。

值得注意的是协议允许双方设备在进入本状态时,改变它们的支持速率列表和链路宽度恢复能力(upconfigure capability),但一旦进入本状态后,这些设置就不再允许修改。因为设备进入本状态后将记录对方在 TS2 中通告的这些能力和设置,具体内容将在本节进行讨论。

A. Downstream 通道

Configuration.Complete期间

在 Configuration.Complete 状态期间,DSP 将发送 TS2 序列,其中的链路和通道编号与接收到的 TS1 中的内容。如果当前端口有一条使用 lane 0 的 x1 链路,并支持增加链路宽度恢复(upconfigure),那么 DSP 将置位 TS2 序列中的 Upconfigure Capability 比特。

使用 8b/10b 编码时,必须在离开当前状态前完成通道间去偏移。另外,如果所有配置中的通道都收到了两个连续的 TS2,其中关闭加扰(Disable Scrambling)比特设置为 1'b1,那么停止对编码进行加扰(scrambling) 。发送这些 TS2 的端口也必须停止加扰。值得注意的是,在 128b/130b 编码模式时,无法关闭加扰,因为添加的扰码对信号完整性的帮助不可或缺。

DSP 在本状态中发送 TS2 序列,并接收观察对端返回的 TS2 序列。DSP 会记录接收到的 TS2 中的 N\_FTS 域数值,其表示(译者添加:对端)退出 L0s 状态必需的 FTS 数量,以备后续使用。

退出至 ”Configuration.Idle“ 状态

当所有发送 TS2 的通道都接收到 8 个满足条件的 TS2 时,并且在接收到一个 TS2 后该通道已经发送至少 16 个 TS2 后,状态机将跳转至下一个状态:Configuration.Idle。这些条件指的是所有接收的 TS2 中都携带有匹配的链路编号和通道编号(非填充符号),匹配的速率标识符( rate identifier),以及匹配的链路 Upconfig Capability 比特。

如果设备支持 2.5 GT/s 以上的速率,那么它必须记录在任何已配置通道上的速率标识符,并覆盖所有此前记录的数值。“changed_speed_recovery” 用于在 Recivery 状态中追踪速率编号的变量,此时清除为 0。

变量 “upconfigure_capable” 将被设置为 1b,如果设备发出的 TS2 中的 Link Upconfigure Capability 域设置为 1b,并且接收到 8 个连续的 TS2 序列在该比特上的设置同样为 1。否则,该变量清除为 0。

任何没有配置为链路一部分的通道将与当前的 LTSSM 不再有关联,并且必须设置为下述各种状态中的一种:

  • 与新的 LTSSM 相关联,或者
  • 转为电气空闲状态
  • 这里涉及一种特殊的状态,即这些未被配置进链路的通道曾经在 L0 状态中被配置为链路的一部分,并且 从那之后 LinkUp 状态位一直被设置为 1b。如果链路支持 upconfigure,那么它们需要仍然和原来的 LTSSM 相关联。这种情况下,协议建议这些通道仍然保持打开对接收端的终结(termination)特性,因为在 upconfigured 之后,它们又会重新变成链路的一份子。如果不保持终结特性打开,那么在 LTSSM 从 Configuration.Complete 状态转为 Recovery.RcvrCfg 状态时,也需要再次打开。不过,如果这些通道并非曾经是链路的一部分,那么它们无法通过该过程成为链路的一部分。
  • 对于可选配的 crosslink 特性,接收阻抗必须保持在 Z RX‐HIGH‐IMP‐DC‐POS 和 Z RX‐HIGH‐IMP‐DC‐NEG 之间。
  • 在 LTSSM 返回 Detect 状态后,这些通道会重新和其关联。
  • 这些通道进入电器空闲状态之前无需发送 EIOS 序列,并且状态转变也并不一定需要发生在符号或者命令集的边界上。

在 2ms 的超时发生后:

退出至 ”Configuration.Idle“ 状态

如果 idle_to_rlock_transitioned 变量小于 FFh,并且当前数据速率为 8GT/s,那么接下来转入 Configuration.Idle 状态。

在这次状态跳变中,changed_speed_recovery 变量清除为 0。并且,变量 upconfigure_capable 也可能会被更新,尽管这不是必须的,当至少一个通道上见到 8 个连续的 TS2 序列,它们都携带有匹配的链路编号和通道编号(非填充符号),如果链路收发双方的 Upconfig Capability 比特都为 1,那么 upconfigure_capable 变量更新为 1b,否则清除为 0。

任何没有配置为链路一部分的通道将与当前的 LTSSM 不再有关联,其他所需的条件与上述列出的非超时时的条件一致。

退出至 Detect 状态

在超时后,如果未满足上一段的条件,则转入 Detect 状态。

B. Upstream 通道

Configuration.Complete期间

在 Configuration.Complete 状态期间,USP 将发送 TS2 序列,其中的链路和通道编号与接收到的 TS2 中的内容。如果当前端口有一条使用 lane 0 的 x1 链路,并支持增加链路宽度恢复(upconfigure),那么 USP 可以置位 TS2 序列中的 Upconfigure Capability 比特。

使用 8b/10b 编码时,必须在离开当前状态前完成通道间去偏移。另外,如果所有配置中的通道都收到了两个连续的 TS2,其中关闭加扰(Disable Scrambling)比特设置为 1'b1,那么停止对编码进行加扰(scrambling) 。发送这些 TS2 的端口也必须停止加扰。值得注意的是,在 128b/130b 编码模式时,无法关闭加扰,因为添加的扰码对信号完整性的帮助不可或缺。

USP 在本状态中从 DSP 接收 TS2 序列,USP 会记录接收到的 TS2 中的 N_FTS 域数值,其表示(译者添加:对端)退出 L0s 状态必需的 FTS 数量,以备后续使用。

退出至 ”Configuration.Idle“ 状态

当所有发送 TS2 的通道都接收到 8 个满足条件的 TS2 时,并且在接收到一个 TS2 后该通道已经发送至少 16 个 TS2 后,状态机将跳转至下一个状态:Configuration.Idle。这些条件指的是所有接收的 TS2 中都携带有匹配的链路编号和通道编号(非填充符号),匹配的速率标识符( rate identifier),以及匹配的链路 Upconfig Capability 比特。

如果设备支持 2.5 GT/s 以上的速率,那么它必须记录在任何已配置通道上的速率标识符,并覆盖所有此前记录的数值。“changed_speed_recovery” 用于在 Recivery 状态中追踪速率编号的变量,此时清除为 0。

变量 “upconfigure_capable” 将被设置为 1b,如果设备发出的 TS2 中的 Link Upconfigure Capability 域设置为 1b,并且接收到 8 个连续的 TS2 序列在该比特上的设置同样为 1。否则,该变量清除为 0。

任何没有配置为链路一部分的通道将与当前的 LTSSM 不再有关联,并且必须设置为下述各种状态中的一种:

  • 可选的,与新的 crosslink LTSSM 相关联(如果支持 crosslink 特性),或者
  • 转为电气空闲状态
  • 这里涉及一种特殊的状态,即这些未被配置进链路的通道曾经在 L0 状态中被配置为链路的一部分,并且 从那之后 LinkUp 状态位一直被设置为 1b。如果链路支持 upconfigure,那么它们需要仍然和原来的 LTSSM 相关联。这种情况下,协议建议这些通道仍然保持打开对接收端的终结(termination)特性,因为在 upconfigured 之后,它们又会重新变成链路的一份子。如果不保持终结特性打开,那么在 LTSSM 从 Configuration.Complete 状态转为 Recovery.RcvrCfg 状态时,也需要再次打开。不过,如果这些通道并非曾经是链路的一部分,那么它们无法通过该过程成为链路的一部分。
  • 接收阻抗必须保持在 Z RX‐HIGH‐IMP‐DC‐POS 和 Z RX‐HIGH‐IMP‐DC‐NEG 之间。
  • 在 LTSSM 返回 Detect 状态后,这些通道会重新和其关联。
  • 这些通道进入电器空闲状态之前无需发送 EIOS 序列,并且状态转变也并不一定需要发生在符号或者命令集的边界上。

在 2ms 的超时发生后:

退出至 ”Configuration.Idle“ 状态

如果 idle_to_rlock_transitioned 变量小于 FFh,并且当前数据速率为 8GT/s,那么接下来转入 Configuration.Idle 状态。

在这次状态跳变中,changed_speed_recovery 变量清除为 0。并且,变量 upconfigure_capable 也可能会被更新,尽管这不是必须的,当至少一个通道上见到 8 个连续的 TS2 序列,它们都携带有匹配的链路编号和通道编号(非填充符号),如果链路收发双方的 Upconfig Capability 比特都为 1,那么 upconfigure_capable 变量更新为 1b,否则清除为 0。

任何没有配置为链路一部分的通道将与当前的 LTSSM 不再有关联,其他所需的条件与上述列出的非超时时的条件一致。

退出至 Detect 状态

在超时后,如果未满足上一段的条件,则转入 Detect 状态。

14.6.4.6 Configuration.Idle

Configuration.Idle 期间

在 Configuration.Idle 子状态中,发送方不断发送空闲数据,等待接收到足够数量的空闲数据后,将链路转为 L0 状态。此时,物理层向上层报告链路已经处于就绪状态(Linkup = 1b)。

对于 8b/10b 编码而言,发送方在所有已配置的通道上发送空闲数据,所谓空闲数据其实就是数值零经过加扰和编码之后的数值。

对于 128b/130b 编码而言,发送方在所有已配置通道发送一个 SDS 有序命令集,后面紧接着发送空闲数据。通道 0 上的第一个空闲符号是数据流的第一个符号。

退出至 ”L0“ 状态

如果采用 8b/10b 编码方式,那么在全部已配置通道上接收到 8 个连续符号周期空闲数据,并且在收到一个空闲符号后已经发送了 16 个符号周期的空闲数据后,进入 L0 状态。

如果采用 128b/130b 编码方式,那么在全部已配置通道上接收到 8 个连续符号周期空闲数据,并且在收到一个空闲符号后已经发送了 16 个符号周期的空闲数据,并且不是在 Configuration.Complete 状态超时后下进入的本状态,那么跳转至 L0 状态。

需要注意以下几点:

  • 各通道间去偏斜必须在开始处理数据流之前完成
  • 空闲符号必须在数据块内收到
  • 如果此次由 configuration 状态或者 Recovery 状态至 L0 状态的跳转,是软件通过置位链路状态寄存器(Link Control register)中的重新训练链路(Retrain Link)比特触发的。那么 DSP 必须置位链路状态寄存器(Link Status register)中的链路带宽管理(Link Bandwidth Management)比特,表示此次状态跳转不是由硬件发起的(autonomous)
  • 在进入 L0 状态前,将变量 “idle_to_rlock_transitioned” 清零。

未满足上述条件,并触发 2ms 超时后:

退出至具体的 Recovery 子状态

如果变量 “idle_to_rlock_transitioned” 小于 FFh,那么下一个跳转状态是 Recovery(Recovery.Rcvrlock)。跳转后:

a) 8.0 GT/s 时,变量 idle_to_rlock_transitioned 自增 1。

b) 2.5 或者 5.0 GT/s 时,变量 idle_to_rlock_transitioned 设置为 FFh。

c) 注意:该变量记录了因为配置过程没有起作用,从而导致状态机从 Configuration.Idle 状态跳转到 Recovery 状态的次数。这可能是因为均衡设置不合适,或者当前选择的速率无法正常工作导致的,Recovery 状态内会采取措施尝试解决这些问题。该变量限制了从本状态跳转至 Recovery 状态的尝试次数,从而避免了永久的无限循环。如果链路在 256 次尝试后(变量计数至 FFh)仍然没法正常工作,那么跳转回 Detect 状态重新开始,并希望这次能有更好的结果。

退出至 Detect 状态

否则,即 idle_to_rlock_transitioned 为 FFh 时,跳转至 Detect 状态。


原文: Mindshare
译者: LJGibbs

文章来源:https://zhuanlan.zhihu.com/p/590655007

《PCI Express Technology 3.0》翻译系列

更多IC设计技术干货请关注FPGA的逻辑技术专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
10614
内容数
577
FPGA Logic 二三事
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息