PCIe Dynamic Bandwidth Changes

PCIe 3.0 更高的数据速率和更宽的链路比前几代产品提供了更高的性能,但功耗也更高。因此,2.0 规范的制定者选择添加另一组电源管理机制,允许硬件动态调整链路速度和宽度。当需要性能时,这些机制允许链路使用最高速度和尽可能宽的链路;当需要降低速度或减小链路宽度时,或者两者兼而有之以降低功耗。与更改链路或设备电源状态相比,这种方法有两个明显的优势。

首先,无论发生什么变化,链路始终能够通信,并且切换所需的服务中断时间相对较短。其次,可以节省更多电量。例如,在 L0 中,x16 链路作为 x1 链路运行时的功耗肯定低于作为 x16 链路运行时的功耗。

其次,除了节能之外,减少带宽还可以解决可靠性问题。例如,高速链路的可靠性可能不可接受,在这种情况下,允许任一链路组件将违规速度从其通告的支持速度列表中移除。组件如何做出可靠性判断尚未明确。有趣的是,组件还可以进入Recovery状态,并通告一组不同的支持速度,而无需在此过程中请求更改速度。

更改链路速度或链路宽度需要重新训练链路。当链路处于 L0 状态且需要更改速度时,需要更改速度的端口的 LTSSM 会开始向其相邻端口发送 TS1(Training sequence 1)。这样做会导致两个相关端口的 LTSSM 进入Recovery状态,在此状态下更改链路速度,然后恢复到 L0。

类似地,想要更改链路宽度的端口开始向其邻居发送 TS1。这样做会导致两个相关端口的 LTSSM 先经历Recovery状态,然后进入配置状态,链路宽度随之更改。LTSSM 最终返回到 L0 状态,并确定新的链路宽度。

由于 LTSSM 涉及动态链路带宽管理,因此在以下章节中讨论链路带宽管理的两个方面(动态链路速度变化和动态链路宽度变化)是有意义的。让我们分别考虑这两个选项,首先从链路速度变化开始。

Dynamic Link Speed Changes

为了便于回顾,图 14-45 展示了 LTSSM 的状态,以便于回忆状态流。虽然根据 Gen1 规范,速度变化指示在轮询状态下执行,但后续的 Gen2 规范将此功能移至Recovery状态。

 在轮询状态下,链路邻居之间会交换 TS1,其中包含多种信息,如 图 14-46 所示。这里最有趣的部分是第 4 个字节,即速率标识符。位 1、2 和 3 指示可用的数据速率,规范指出必须始终支持 2.5 GT/s,而如果支持 8.0 GT/s,也必须支持 5.0 GT/s。

第 6 位的含义取决于端口是面向上游还是下游,以及端口的 LTSSM 状态。然而,对于速度变化的情况,选项会减少,因为它只有来自上游端口才有意义,并且仅指示速度变化是否是自主事件。“自主”表示端口请求此更改是出于自身硬件特定的原因,而不是可靠性问题。上游端口使用第 7 位来请求速度变化。这些值在 TS2 中非常相似,尽管第 6 位现在有了另一种含义,与自主链路宽度变化有关,我们将在稍后讨论。

 

 

Upstream Port Initiates Speed Change

速度变化必须由上游端口(面向上游的端口)发起,并通过转换到Recovery状态来完成。Recovery状态的子状态如图 14-48 所示,椭圆形突出显示了本次讨论的重点部分。接下来的讨论是对整个速度变化过程的相对概括,不会涉及 LTSSM 操作的细节。要了解更多信息,请参阅第 571 页的“Recovery State”讨论。

 

Speed Change Example

为了说明该过程,请参考图 14-49 中所示的速度变化示例。请注意,本例中已删除均衡子状态(Equalization substate),以使图表更简洁易懂。该示例显示从 2.5 GT/s 到 5.0 GT/s 的变化,因此均衡子状态未使用。更改为 8.0 GT/s 也会经历相同的过程,但会在过程结束时增加一次均衡子状态的跳变。要了解有关均衡过程的更多信息,请参阅第 587 页的“Recovery.Equalization”。

本例中的端点(只能拥有一个上行端口)连接到根联合体(Root Complex),而根联合体只能拥有一个下行端口。只有上行端口可以启动速度更改过程,这是因为其定向速度更改标志先前已根据某些硬件特定条件设置。要启动该序列,它会将其 LTSSM 更改为Recovery状态,进入 Recovery.RcvrLock 子状态,并发送设置了速度更改位并列出其将支持的速度的 TS1,如图 14-49 所示。当下行端口看到传入的 TS1 时,它也会更改为Recovery状态并开始发回 TS1。由于传入的 TS1 中设置了速度更改位,因此这将设置根端口(Root Port)中的定向速度更改标志,并且传出的 TS1 也将设置该位。链接尝试使用的速度将是通常支持的最高速度,因此,如果设备想要使用较低的速度,它就不会列出此时支持的较高速度。

 当上行端口检测到 TS1 返回时,其状态机将切换到 Recovery.RcvrCfg 子状态,并开始发送仍设置了 Speed Change 位的 TS2,如图 14-50 所示。如果此更改不是由链路上的可靠性问题引起的,则这些 TS2 也会设置 Autonomous Change 位。当下行端口检测到传入的 TS2 时,它也会切换到 Recovery.RcvrCfg 子状态,并返回设置了 Speed Change 位的 TS2。但是,在Recovery期间,Autonomous Change 位在 TS2 中为下行端口保留。

 一旦每个端口接收到 8 个连续的 TS2 并设置了“速度变化”位,它们就知道下一步将进入“Recovery.Speed”子状态,如图 14-51 所示。此时,下游端口需要在传入的 TS2 中注册“自主变化(Autonomous Change)”位的设置。为了支持此功能,PCIe 功能寄存器中添加了一些额外的字段。

链路带宽变化的状态位位于链路状态寄存器中,如图 14-52 所示。如果设备具备并已启用此功能,则状态变化还可用于生成中断,以通知软件这些事件。此功能由链路带宽通知功能位报告,如图 14-53 所示,并由链路控制寄存器中的中断启用位启用,如图 14-54 所示。请注意,有两种情况:自主(Autonomous)和带宽管理。自主表示变化不是由可靠性问题引起的,而带宽管理表示变化是由可靠性问题引起的。

 

 

 

 一旦达到 Recovery.Speed 子状态,链路将双向进入电气空闲状态,并在内部更改速度。所选速度将为 TS1 和 TS2 的速率 ID 字段中报告的最高通用支持速度。在本例中,该速度为 5.0 GT/s,因此将更改为该速度。超时后,链路邻居将转换回 Recovery.RcvrLock 状态,并通过再次发送 TS1 退出电气空闲状态,如图 14-55 所示。当上行端口发现 TS1 返回时,它将转换到 Recovery.RcvrCfg 状态并开始发送 TS2,就像之前一样。不过,这次速度更改位未设置。最终,会发现从下行端口返回的 TS2 也未设置速度更改位,此时状态机将转换到 Recovery.Idle 状态并返回 L0。

如果由于某种原因速度更改失败,则组件在返回 L0 后至少 200 毫秒内不得尝试该速度或更高的速度,或者直到链路邻居宣布支持更高的速度(以先到者为准)。

 

Software Control of Speed Changes

软件无法控制硬件何时做出有关改变速度的决策,但可以限制或禁用此功能。通过设置链路控制 2 寄存器中的目标链路速度值可以实现限制,如图 14-56 所示。这作为上行端口可用速度的上限,上行端口将尝试维持该值或两个链路邻居支持的最高速度(以较低者为准)。软件还可以通过设置上行组件中的目标链路速度,然后设置链路控制寄存器中的重新训练链路位来强制使用特定速度,如图 14-57 所示。如前所述,链路带宽通知机制会将任何基于硬件的链路速度或宽度变化通知给软件。最后,可以通过设置硬件自主速度禁用位来禁用速度变化机制。

 

Dynamic Link Width Changes

更改链路速度的基本操作也可用于更改链路宽度,但由于涉及更多 LTSSM 步骤,因此其顺序略微复杂。在启用链路宽度更改之前,软件需要注意的一点是,链路邻居是否支持从窄链路恢复到宽链路(称为“链路上行配置”)。设备会在训练期间发送的 TS2 的速率 ID 字段的第 6 位中报告此功能,如图 14-58 所示。如果组件不支持此功能,则意味着更改为较窄的链路宽度将是单向事件,并且仅适用于链路出现可靠性问题的情况。

 Link Width Change Example

考虑图 14-59 中连接到端点(千兆以太网设备)的根端口的示例。只有上游端口会发起此更改,并且它会像以前一样首先进入Recovery状态。不过,这次速度更改位未设置。为了确定新的链路宽度,上游端口需要告知下游端口在返回 L0 之前从Recovery状态转换到配置状态,如图 14-60 所示。配置状态中有多个子状态,其简化版本如图 14-61 所示。我们将逐一介绍该顺序,以清楚地了解各个步骤的工作原理。

 

 

 与之前一样,上行端口通过进入Recovery模式并发送 TS1 来启动此过程。这些 TS1 未设置速度变化位,如图 14-59 所示的示例所示,其中以太网设备在其上行端口上启动此过程。作为响应,下行端口发送回 TS1,速度变化位也清除。链路和通道号仍然显示为与上次链路训练时相同。回顾图 14-48,下一个状态是 Recovery.RcvrCfg,在此期间,链路伙伴交换 TS2。

 由于未请求更改速度,下一个状态为 Recovery.Idle。在该状态下,端口通常会发送逻辑空闲符号(全零),下行端口也照做,如图 14-63 所示。然而,上行端口被指示更改链路宽度,因此它不会发送预期的空闲符号。相反,它会发送带有 PAD 的 TS1,该 PAD 包含链路号和通道号。下行端口识别出先前配置的通道现在具有 PAD 的通道号,这导致它转换到第一个配置子状态:Config.Linkwidth.Start。

 下行端口现在启动下一步,发送 TS1,这些 TS1 包含最初协商的链路号,但所有通道号都带有 PAD 标记,如图 14-64 所示。上行端口在其希望“激活”的通道上响应匹配的 TS1,但在希望非激活的通道上,响应链路号和通道号的 PAD 标记。当下行端口看到此响应时,它将转换到 Config.Linkwidth.Accept 子状态。注意,这些 TS1 的“自主更改(Autonomous Change)”位已设置。

 根端口通过更改其 TS1 来响应,以显示与活动通道对应的通道号,但使用 PAD 来显示所有被视为非活动通道的链路和通道号。上游端口以相同的 TS1 进行响应,如图 14-65 所示,状态更改为 Config.Lanenum.Accept。此时,根端口更新状态位,以表明检测到了自主更改,并更改为 Config.Complete 子状态。

 下一步,根端口(Root Port)开始在活动通道上发送 TS2,并将非活动通道置于电气空闲 (Electrical Idle) 状态。回想一下,TS2 会报告组件是否具备“upconfigure capable”(可上行配置)功能,在本例中,两个链路伙伴都支持此功能。端点返回相同的信息:活动通道上发送 TS2,非活动通道上发送电气空闲 (Electrical Idle)。看到这些后,根端口的状态机切换至配置空闲 (Config.Idle) 状态,并开始在活动通道上发送逻辑空闲 (Logical Idle)。端点响应相同的信息,链路状态切换回 L0。链路现已准备好正常运行,但为了节省功耗,带宽会有所减少。

 与动态速度变化的情况一样,软件无法启动链路宽度变化,但可以通过设置链路控制寄存器中的位来禁用此机制,如图 14-67 所示。与速度变化情况不同,没有定义软件机制来允许设置特定的链路宽度。

 

posted @ 2025-06-25 19:07  闹闹爸爸  阅读(139)  评论(0)    收藏  举报