第 2 章 事务
本章概述了节点间的通信通道、相关的数据包字段以及事务结构。它包含以下部分:
• 第 2-32 页的通道概述。
• 第 2-33 页的通道字段。
• 第 2-39 页的事务结构。
• 第 2-73 页的事务标识符字段。
• 第 2-74 页的事务标识符字段详情。
• 第 2-77 页的事务标识符字段流。
• 第 2-98 页的逻辑处理器标识符。
• 第 2-99 页的排序。
• 第 2-109 页的地址、控制和数据。
• 第 2-118 页的数据传输。
• 第 2-129 页的请求重试。
2.1 通道概述
节点之间的通信是基于通道的。表 2-1 显示了在 RN 和 SN 节点处的通道命名和通道指定。
本节使用通道的简写名称来描述事务结构。表 2-1 显示了 RN 或 SN 组件上存在的简写名称和物理通道名称。
物理通道在 RN 和 SN 组件上的映射见第 12-315 页的通道。
表 2-1 RN 和 SN 节点处的通道命名和指定
| 通道 | REQ | WDAT | SRSP | CRSP | RDAT | SNP |
|---|---|---|---|---|---|---|
| RN 通道指定 | TXREQ。出站请求。 | TXDAT。出站数据。 用于写数据、原子数据、监听数据、转发数据。 | TXRSP。出站响应。 用于监听响应和完成确认。 | RXRSP。入站响应。 用于来自完成者的响应。 | RXDAT。入站数据。 用于读数据、原子数据。 | RXSNP。入站监听请求。 |
| SN 通道指定 | RXREQ。入站请求。 | RXDAT。入站数据。 用于写数据、原子数据。 | - | TXRSP。出站响应。 用于来自完成者的响应。 | TXDAT。出站数据。 用于读数据、原子数据。 | - |
2.2 通道字段
本节简要概述通道字段,并指出哪些字段会影响事务结构。与每个通道相关的字段在以下部分中描述:
• 事务请求字段。
• 第 2-35 页的监听请求字段。
• 第 2-36 页的数据字段。
• 第 2-38 页的响应字段。
2.2.1 事务请求字段
表 2-2 显示了与请求数据包相关的字段。
术语"事务结构"用于描述构成事务的不同数据包,事务结构可能因多种因素而异。表 2-2 显示了哪些请求字段可以影响事务结构。关于不同事务结构的更多信息,请参见第 2-39 页的事务结构和第 12-324 页的微片数据包定义。
表 2-2 请求通道字段
| 字段 | 影响结构 | 描述 |
|---|---|---|
| QoS | 否 | 服务质量优先级。为事务指定 16 种可能的优先级级别之一,QoS 值越高表示优先级越高。参见第 10 章 服务质量。 |
| TgtID | 否 | 目标 ID。数据包所指向的组件上端口的节点 ID。参见第 2-74 页的事务标识符字段详情和第 3-134 页的系统地址映射。 |
| SrcID | 否 | 源 ID。发送数据包的组件上端口的节点 ID。参见第 2-74 页的事务标识符字段详情。 |
| TxnID | 否 | 事务 ID。每个源节点的事务具有唯一的事务 ID。参见第 2-74 页的事务标识符字段详情。 |
| LPID | 否 | 逻辑处理器 ID。与 SrcID 字段一起使用,以唯一标识生成请求的逻辑处理器。参见第 2-98 页的逻辑处理器标识符。 |
| PGroupID | 否 | 持久性组 ID。指示请求所属的 CleanSharedPersistSep 事务集。参见第 12-331 页的 PGroupID。 |
| Deep | 否 | 深度持久性。指示在所有较早的写操作被写入最终目的地之前,不得发送持久性响应。参见第 4-151 页的持久性 CMO 中 Deep 属性的使用。 |
| ReturnNID | 否 | 返回节点 ID。带数据的响应将发送到的节点 ID。参见第 2-74 页的事务标识符字段详情。 |
| ReturnTxnID | 否 | 返回事务 ID。在从属设备的数据响应中传达 TxnID 值的唯一事务 ID。参见第 2-74 页的事务标识符字段详情。 |
| StashNID | 否 | 暂存节点 ID。暂存目标的节点 ID。参见第 12-331 页的 StashNID。 |
| StashNIDValid | 是 | 暂存节点 ID 有效。指示 StashNID 字段具有有效的暂存目标值。参见第 12-331 页的 StashNIDValid。 |
| StashLPID | 否 | 暂存逻辑处理器 ID。暂存目标的逻辑处理器 ID。参见第 12-331 页的 StashLPID。 |
| 字段 | 影响结构 | 描述 |
|---|---|---|
| StashLPIDValid | 否 | 暂存逻辑处理器 ID 有效。指示必须将 StashLPID 字段值视为暂存目标。参见第 12-331 页的 StashLPIDValid。 |
| Opcode | 是 | 请求操作码。指定事务类型,是决定事务结构的主要字段。参见第 4-144 页的请求类型和第 12-334 页的 REQ 通道操作码。 |
| Addr | 否 | 地址。对于读写请求,被访问内存位置的地址。参见第 2-109 页的地址和第 12-339 页的 Addr。 |
| NS | 否 | 非安全。确定事务是非安全还是安全。参见第 2-110 页的非安全位和第 12-339 页的 NS。 |
| Size | 是 | 数据大小。指定与事务相关的数据的大小。这决定了事务中数据包的数量。参见第 2-118 页的数据传输。 |
| AllowRetry | 是 | 允许重试。确定目标是否允许给出重试响应。参见第 2-129 页的请求重试。 |
| PCrdType | 否 | 协议信用类型。指示 AllowRetry 字段被取消断言的请求所使用的协议信用类型。参见第 2-129 页的请求重试。 |
| ExpCompAck | 是 | 期望完成确认。指示事务将包含一条完成确认消息。参见第 2-39 页的事务结构和第 2-99 页的排序。 |
| MemAttr | 否 | 内存属性。确定与事务相关的内存属性。参见第 2-110 页的内存属性。 |
| SnpAttr | 否 | 监听属性。指定与事务相关的监听属性。参见第 2-115 页的可能共享。 |
| SnoopMe | 否 | 监听我。指示主节点必须确定是否向请求者发送监听。参见第 2-62 页的原子操作。 |
| LikelyShared | 否 | 可能共享。为下游缓存提供分配提示。参见第 2-115 页的可能共享。 |
| Excl | 否 | 独占访问。指示相应的事务是独占访问事务。参见第 6 章 独占访问。 |
| Order | 是 | 排序要求。确定此请求相对于来自同一代理的其他请求的排序要求。参见第 2-99 页的排序。 |
| Endian | 否 | 字节序。指示原子事务数据包中数据的字节序。参见第 2-122 页的字节序。 |
| TraceTag | 否 | 跟踪标签。为系统的调试、跟踪和性能测量提供额外支持。参见第 11 章 系统调试、跟踪和监控。 |
| MPAM | 否 | 内存系统性能资源分区和监控。在用户之间有效利用内存资源并监控其使用情况。参见第 11-305 页的 MPAM。 |
| RSVDC | 否 | 用户定义。参见第 12-352 页的 RSVDC。 |
表 2-2 请求通道字段 (续)
2.2.2 监听请求字段
监听请求包含为请求数据包定义的字段的子集。表 2-3 显示了哪些请求字段可以影响事务结构。
表 2-3 监听请求字段
| 字段 | 影响结构 | 描述 |
|---|---|---|
| QoS | 否 | 服务质量优先级。定义见第 2-33 页的请求通道字段。参见第 10 章 服务质量。 |
| TxnID | 否 | 事务 ID。定义见第 2-33 页的请求通道字段。参见第 2-74 页的事务标识符字段详情。 |
| FwdNID | 否 | 转发节点 ID。原始请求者的节点 ID。参见第 2-74 页的事务标识符字段详情。 |
| FwdTxnID | 否 | 转发事务 ID。原始请求者在请求中使用的事务 ID。参见第 2-74 页的事务标识符字段详情。 |
| StashLPID | 否 | 暂存逻辑处理器 ID。定义见第 2-33 页的请求通道字段。参见第 7-256 页的暂存消息。 |
| StashLPIDValid | 否 | 暂存逻辑处理器 ID 有效。定义见第 2-33 页的请求通道字段。参见第 7-256 页的暂存消息。 |
| VMIDExt | 否 | 虚拟机 ID 扩展。参见第 8-268 页的 DVM 操作类型。 |
| SrcID | 否 | 源 ID。定义见第 2-33 页的请求通道字段。参见第 2-74 页的事务标识符字段详情。 |
| Opcode | 是 | 监听操作码。参见监听请求字段和第 12-337 页的 SNP 通道操作码。 |
| Addr | 否 | 地址。对于监听请求,被访问内存位置的地址。参见第 2-109 页的地址和第 12-339 页的 Addr。 |
| NS | 否 | 非安全或安全访问。定义见第 2-33 页的请求通道字段。参见第 2-110 页的非安全位和第 12-339 页的 NS。 |
| DoNotGoToSD | 否 | 禁止进入 SD 状态。控制被监听者使用 SD 状态。参见第 4-199 页的不转换到 SD 状态。 |
| DoNotDataPull | 是 | 禁止数据拉取。指示被监听者不允许使用与暂存请求相关的数据拉取特性。参见第 7-250 页的监听请求和数据拉取。 |
| RetToSrc | 是 | 返回到源。指示监听的接收者使用监听响应返回数据。参见第 4-198 页的使用监听响应返回数据。 |
| TraceTag | 否 | 跟踪标签。定义见第 2-33 页的请求通道字段。参见第 11 章 系统调试、跟踪和监控。 |
| MPAM | 否 | 内存系统性能资源分区和监控。定义见第 2-33 页的请求通道字段。参见第 11-305 页的 MPAM。 |
注意
本规范未为监听请求定义 TgtID 字段。参见第 3-137 页的监听请求消息的目标 ID 确定。
2.2.3 数据字段
表 2-4 描述了与数据包相关的字段。数据包可以在 RDAT 或 WDAT 通道上发送。数据包中的字段不影响事务结构。
表 2-4 数据包字段
| 字段 | 描述 |
|---|---|
| QoS | 服务质量优先级。定义见第 2-33 页的请求通道字段。参见第 10 章 服务质量。 |
| TgtID | 目标 ID。定义见第 2-33 页的请求通道字段。参见第 2-74 页的事务标识符字段详情。 |
| SrcID | 源 ID。定义见第 2-33 页的请求通道字段。参见第 2-74 页的事务标识符字段详情。 |
| TxnID | 事务 ID。定义见第 2-33 页的请求通道字段。参见第 2-74 页的事务标识符字段详情。 |
| HomeNID | 主节点 ID。要从请求者发送的 CompAck 响应的目标的节点 ID。参见第 2-74 页的事务标识符字段详情。 |
| CBusy | 完成者繁忙。指示完成者当前的活跃程度。参见第 11-307 页的完成者繁忙。 |
| DBID | 数据缓冲区 ID。提供的 ID,用作对此消息的响应中的 TxnID。参见第 2-74 页的事务标识符字段详情和第 2-99 页的排序。 |
| Opcode | 数据操作码。指示例如数据包是与读事务、写事务还是监听事务相关。参见第 12-338 页的 DAT 通道操作码。 |
| RespErr | 响应错误状态。指示与数据传输相关的错误状态。参见第 6 章 独占访问和第 9-281 页的错误响应字段。 |
| Resp | 响应状态。指示与数据传输相关的缓存行状态。参见第 4-166 页的响应类型。 |
| FwdState | 转发状态。指示从监听的接收者向请求者进行数据传输时相关的缓存行状态。参见第 12-348 页的 FwdState。 |
| DataPull | 数据拉取。指示在数据响应中包含隐含的读请求。参见第 7-250 页的监听请求和数据拉取。 |
| DataSource | 数据源。该值指示读数据响应中数据的来源。参见第 11-302 页的数据源指示。 |
| CCID | 关键块标识符。复制原始事务请求的地址偏移量。参见第 2-118 页的数据传输。 |
| DataID | 数据标识符。提供数据包中数据的地址偏移量。参见第 2-118 页的数据传输。 |
| BE | 字节使能。对于数据写操作,或作为对监听的响应提供的数据,指示哪些字节是有效的。参见第 2-118 页的数据传输。 |
| Data | 数据有效载荷。参见第 2-118 页的数据传输。 |
| 字段 | 描述 |
|---|---|
| DataCheck | 数据检查。检测 DAT 数据包中的数据错误。参见第 9-291 页的数据检查。 |
| Poison | 毒化。指示一组数据字节先前已被损坏。参见第 9-290 页的毒化。 |
| TraceTag | 跟踪标签。定义见第 2-33 页的请求通道字段。参见第 11 章 系统调试、跟踪和监控。 |
| RSVDC | 用户定义。参见第 12-352 页的 RSVDC。 |
表 2-4 数据包字段 (续)
2.2.4 响应字段
表 2-5 描述了与响应包相关的字段。响应包中的字段不影响事务结构。
表 2-5 响应包字段
| 字段 | 描述 |
|---|---|
| QoS | 服务质量优先级。定义见第 2-33 页的请求通道字段。参见第 10 章 服务质量。 |
| TgtID | 目标 ID。定义见第 2-33 页的请求通道字段。参见第 2-74 页的事务标识符字段详情。 |
| SrcID | 源 ID。定义见第 2-33 页的请求通道字段。参见第 2-74 页的事务标识符字段详情。 |
| TxnID | 事务 ID。定义见第 2-33 页的请求通道字段。参见第 2-74 页的事务标识符字段详情。 |
| CBusy | 完成者繁忙。定义见第 2-36 页的数据字段。参见第 11-307 页的完成者繁忙。 |
| DBID | 数据缓冲区 ID。定义见第 2-36 页的数据包字段。参见第 2-74 页的事务标识符字段详情和第 2-99 页的排序。 |
| PGroupID | 持久性组 ID。定义见第 2-33 页的请求通道字段。参见第 12-331 页的 PGroupID。 |
| PCrdType | 协议信用类型。参见第 2-131 页的 PCrdType。 |
| Opcode | 响应操作码。指定响应类型。参见第 12-336 页的 RSP 通道操作码。 |
| RespErr | 响应错误状态。定义见第 2-36 页的数据包字段。参见第 6 章 独占访问和第 9-281 页的错误响应字段。 |
| Resp | 响应状态。定义见第 2-36 页的数据包字段。参见第 4-166 页的响应类型。 |
| FwdState | 转发状态。定义见第 2-36 页的数据包字段。参见第 12-348 页的 FwdState。 |
| DataPull | 数据拉取。定义见第 2-36 页的数据包字段。参见第 7-250 页的监听请求和数据拉取。 |
| TraceTag | 跟踪标签。定义见第 2-33 页的请求通道字段。参见第 11 章 系统调试、跟踪和监控。 |
2.3 事务结构
本节描述了在第 1-23 页的事务分类中描述的事务结构,以及通道使用情况。
在足够的情况下,事务结构被描述为在单个接口上看到的样子。
本节介绍的事务类型有:
• 无重试的请求事务。
• 有重试的请求事务。
• 监听事务。
一个请求事务要完成,可能需要一个监听事务。然而,这种依赖关系在请求者处是不可见的,因此这两种事务类型通常是分开介绍的。关于请求和监听流如何相关的示例,请参见第 5 章 互联协议流。
除 PCrdReturn 和 PrefetchTgt 外,所有事务类型都可以在事务开始时有一个重试序列。为便于介绍,重试序列单独描述。参见第 2-66 页的事务重试序列。
2.3.1 请求事务结构
请求事务结构按以下分组描述:
• 可监听的读操作(不包括 ReadOnce*)。
• 第 2-44 页的 ReadNoSnp、ReadOnce、ReadOnceCleanInvalid、ReadOnceMakeInvalid。
• 第 2-50 页的带有分离的非数据响应和纯数据响应的读操作。
• 第 2-55 页的无数据操作。
• 第 2-59 页的写操作。
• 第 2-62 页的原子操作。
• 第 2-64 页的 DVM。
• 第 2-65 页的 PrefetchTgt。
可监听的读操作(不包括 ReadOnce*)
不包括 ReadOnce* 的可监听读事务有:
• ReadClean。
• ReadNotSharedDirty。
• ReadShared。
• ReadUnique。
本节中描述的可监听读事务由完全一致性请求者(RN-F)用于在需要监听其他可监听请求者(RN-F)时执行读操作。
ReadOnce* 事务(也是可监听事务)的事务结构与 ReadNoSnp 一起在本章后续部分描述。
带有 DMT 的事务结构
当数据可以直接从从属设备发送到原始请求者时,使用带有 DMT 的可监听读事务。带有 DMT 的可监听读事务的进展如下:
-
请求者在 REQ 通道上发送一个可监听的读请求:
• ReadClean。
• ReadNotSharedDirty。
• ReadShared。
• ReadUnique。
-
ICN 在 REQ 通道上向 SN 发送一个 ReadNoSnp 请求:
-
SN 作为完成者,使用 CompData 操作码在 RDAT 通道上将读数据和任何相关的事务响应直接转发给请求者。
读数据可以使用多次传输发送。参见第 2-118 页的数据传输。
-
由于事务请求的 ExpCompAck 位被设置,请求者必须使用 SRSP 通道上的 CompAck 操作码返回一个确认,以指示事务已完成。
图 2-1 显示了事务结构。

图 2-1 可监听读 DMT 结构
请求/响应规则为:
• CompData 只能在完成者接收到相关请求后发送。
• 请求者必须在接收到至少一个 CompData 数据包后才能发送 CompAck。
注意
在 CHI Issue C 之前,CompAck 必须在接收到读数据的所有数据包之后才能发送。
图 2-1 所示的可监听读事务可以包含单独的 Comp 和 Data 响应,而不是 CompData 响应。带有分离的 Comp 和 Data 响应的读事务结构在第 2-50 页的带有分离的非数据响应和纯数据响应的读操作中描述。
注意
在 CHI issue C 之前,不允许单独的 Comp 和 Data 响应。
DMT 限制
以下限制适用于 DMT 事务:
• 请求者只有在可能使用该 TxnID 的所有响应都已返回后,才能重用该 TxnID。
• 主节点必须等到保证以下所有适用条件都成立时,才能向 SN-F 发送 DMT 请求:
--- 不需要发送监听请求。
--- 如果发送了监听请求,则接收到的监听响应不返回缓存行的脏副本。
--- 如果监听响应返回了缓存行的部分脏副本,则只有当部分数据被写入 SN-F 并收到该写操作的完成通知后,才能发送 DMT。
--- 如果监听是转发类型的监听,则它不会导致缓存行被转发给请求者。
注意
主节点可以结合 DCT 启用 DMT,但必须在向 SN-F 发送 DMT 请求之前等待接收到 DCT 响应。
带有 DCT 的事务结构
当数据要直接从被监听的 RN-F 发送到原始请求者时,使用带有 DCT 的可监听读事务。带有 DCT 的可监听读事务的进展如下:
-
请求者在 REQ 通道上发送一个可监听的读请求:
• ReadClean。
• ReadNotSharedDirty。
• ReadShared。
• ReadUnique。
-
ICN 在 SNP 通道上向 RN-F 发送一个 Snp[*]Fwd 请求。
-
RN-F 作为完成者,使用 DAT 通道上的 CompData 操作码将读数据和任何相关的事务响应转发给 RN。
数据可以使用多次传输发送。参见第 2-118 页的数据传输。
-
RN-F 还在 SRSP 通道上向 ICN 转发一个 SnpRespFwded 响应,以指示读数据已被转发给请求者。
-
由于事务请求的 ExpCompAck 位被设置,请求者必须使用 SRSP 通道上的 CompAck 操作码返回一个确认,以指示事务已完成。
图 2-2 显示了事务结构。

请求/响应规则为:
• CompData 只能在完成者接收到相关请求后发送。
• CompAck 可以在接收到读数据的第一个数据包后立即发送。
注意
在 CHI Issue C 之前,CompAck 必须在接收到读数据的所有数据包之后才能发送。
图 2-2 可监听读 DCT 结构
无直接数据传输的事务结构
本节展示了没有 DMT 或 DCT 的读事务结构。
从请求者的角度来看,无直接数据传输的可监听读事务的进展与有直接数据传输的可监听读事务相同,如下所示:
-
请求者在 REQ 通道上发送一个可监听的读请求:
• ReadClean。
• ReadNotSharedDirty。
• ReadShared。
• ReadUnique。
-
完成者使用 RDAT 通道上的 CompData 操作码返回读数据和任何相关的事务响应。
读数据可以使用多次传输发送。参见第 2-118 页的数据传输。
-
由于 ExpCompAck 位被设置,请求者必须使用 SRSP 通道上的 CompAck 操作码返回一个确认,以指示事务已完成。CompAck 可以在接收到读数据的第一个数据包后立即发送。
可能存在单独的 Comp 和 Data 响应。参见第 2-50 页的带有分离的非数据响应和纯数据响应的读操作。
注意
在 CHI issue C 之前:
• CompAck 必须在接收到读数据的所有数据包之后才能发送。
• 不允许单独的 Comp 和 Data 响应。
图 2-3 显示了事务结构。

图 2-3 无直接数据传输的可监听读结构
请求/响应规则为:
• CompData 只能在完成者接收到相关请求后发送。
• 如果正在发送的数据是从从属设备或被监听的代理接收的,则允许 ICN 在收到来自从属设备或被监听代理的第一个数据包后立即转发 CompData 数据包。
• CompAck 可以在接收到读数据的第一个数据包后立即发送。
注意
在 CHI Issue C 之前,CompAck 必须在接收到读数据的所有数据包之后才能发送。
ReadNoSnp、ReadOnce、ReadOnceCleanInvalid、ReadOnceMakeInvalid
ReadNoSnp 事务用于在执行读操作时不需要监听其他主设备。ReadNoSnp 获得的数据要么直接来自从属节点,要么通过互联。
ReadOnce、ReadOnceCleanInvalid 和 ReadOnceMakeInvalid 事务用于在执行读操作时需要监听其他主设备,但请求者不打算在其自己的缓存中分配缓存行的情况。
注意
ReadOnce、ReadOnceCleanInvalid 和 ReadOnceMakeInvalid 获取一致性数据值的快照。如果请求者在本地缓冲区或缓存中持有此值,则该数据值将不再一致。
在本节剩余部分,ReadOnce* 代表 ReadOnce、ReadOnceCleanInvalid 和 ReadOnceMakeInvalid 这三种事务类型。
ReadOnce* 获得的数据要么直接来自从属节点或对等请求节点,要么通过互联。
ReadNoSnp 和 ReadOnce* 事务可以选择具有排序要求。对于需要排序的事务,主节点必须确保一个事务在被观察之前,不会采取任何可能导致后续排序事务被观察的操作。这样的事务可以包括从主节点到请求者的 ReadReceipt 响应。
ReadNoSnp 和 ReadOnce* 事务可以选择设置 ExpCompAck 字段,指示事务将包含一个 CompAck 响应。对于 ReadNoSnp 和 ReadOnce* 事务,使用 CompAck 响应在功能上不是必需的,因为发出事务的 RN 不会持有缓存行的副本。但是,在某些情况下,使用 CompAck 允许使用 DMT 以及分离的 Comp 和 Data 响应。
2-44
版权所有 © 2014, 2017, 2018, 2019 Arm Limited 或其附属公司。保留所有权利。 ARM IHI 0050D 非机密 ID082919
ReadNoSnp 和 ReadOnce 带有 DMT 的结构 *
带有 DMT 的 ReadNoSnp 和 ReadOnce* 事务的进展如下:
-
请求者在 REQ 通道上发送带有 ReadNoSnp 或 ReadOnce* 操作码的请求。
-
如果请求的 Order 字段指示需要排序,则当顺序建立后,必须在 CRSP 通道上返回一个 ReadReceipt 响应。
-
ICN 在 REQ 通道上向 SN 发送一个 ReadNoSnp 请求。
-
如果 ReadNoSnp 请求的 Order[1:0] 设置为 0b01,SN 在 CRSP 通道上向 ICN 返回一个 ReadReceipt 响应。
-
SN 作为完成者,使用 RDAT 通道上的 CompData 操作码将读数据和任何相关的事务响应直接返回给请求者。
读数据可以使用多次传输发送。参见第 2-118 页的数据传输。
-
如果事务请求的 ExpCompAck 位被设置,请求者必须使用 SRSP 通道上的 CompAck 操作码返回一个确认,以指示事务已完成。
CompAck 可以在接收到读数据的第一个数据包后立即发送。
注意
在 CHI Issue C 之前,CompAck 必须在接收到读数据的所有数据包之后才能发送。
图 2-4 显示了事务结构。

图 2-4 ReadNoSnp 和 ReadOnce* DMT 结构
使用 DMT 的 ReadNoSnp 和 ReadOnce* 事务在主节点的生命周期可以通过使用来自从属设备的 ReadReceipt 响应作为读接收确认来减少,从而在主节点处取消分配事务。图 2-4 中标记为可选的来自 SN 的 ReadReceipt,当用于在主节点处提前取消分配请求(代替通常较晚来自请求者的 CompAck)时,就变为必需。关于此类流的示例,请参见第 5-212 页的带有早期主节点取消分配的 ReadOnce* 和 ReadNoSnp。关于 DMT 与使用读接收确认(以 ReadReceipt 形式)、CompAck 以及在 ReadOnce* 和 ReadNoSnp 事务中的排序要求之间的关系,请参见第 2-49 页的表 2-6。
以下要求适用于这种生命周期减少的事务类型:
• 主节点必须在发送给从属节点的读请求中将 Order[1:0] 设置为值 0b01。
• 对于 Order[1:0] 设置为值 0b01 的请求,当从属节点可以保证请求已被接受并且不会发送 RetryAck 响应时,它必须发送一个 ReadReceipt 以确认读请求。
• 如果来自 RN 的请求没有排序要求,则主节点允许在收到 ReadReceipt 后取消分配该请求,而无需等待 CompAck。
• 即使在请求被取消分配后,也允许主节点接收 CompAck。
ReadOnce 带有 DCT 的结构 *
带有 DCT 的 ReadOnce* 事务的进展如下:
-
请求者在 REQ 通道上发送带有 ReadOnce* 操作码的请求。
-
ICN 在 SNP 通道上向 RN-F 发送一个 Snp[*]Fwd 请求。
-
RN-F 作为完成者,使用 DAT 通道上的 CompData 操作码将读数据和任何相关的事务响应转发给 RN。
读数据可以使用多次传输发送。参见第 2-118 页的数据传输。
-
RN-F 还在 SRSP 通道上向 ICN 转发一个 SnpRespFwded 响应,以指示读数据已被转发给请求者。或者,对 ICN 的响应可以包含数据,并将是 SnpRespDataFwded 响应。
-
如果事务请求的 ExpCompAck 位被设置,请求者必须使用 SRSP 通道上的 CompAck 操作码返回一个确认,以指示事务已完成。
CompAck 可以在接收到读数据的第一个数据包后立即发送。
注意
在 CHI Issue C 之前,CompAck 必须在接收到读数据的所有数据包之后才能发送。
图 2-5 显示了事务结构。

图 2-5 ReadOnce* DCT 结构
无直接数据传输的 ReadNoSnp 和 ReadOnce 结构 *
本节展示了没有 DMT 或 DCT 的读事务结构。
从请求者的角度来看,无直接数据传输的 ReadNoSnp 和 ReadOnce* 事务的进展与有直接数据传输的 ReadNoSnp 和 ReadOnce* 事务相同,如下所示:
-
请求者在 REQ 通道上发送带有 ReadNoSnp 或 ReadOnce* 操作码的请求。
-
如果请求的 Order 字段指示需要排序,则当顺序建立后,必须在 CRSP 通道上返回一个 ReadReceipt 响应。
-
完成者使用 RDAT 通道上的 CompData 操作码返回读数据和任何相关的事务响应。
读数据可以使用多次传输发送。参见第 2-118 页的数据传输。
-
如果事务请求的 ExpCompAck 位被设置,请求者必须使用 SRSP 通道上的 CompAck 操作码返回一个确认,以指示事务已完成。CompAck 可以在接收到读数据的第一个数据包后立即发送。
注意
在 CHI Issue C 之前,CompAck 必须在接收到读数据的所有数据包之后才能发送。
图 2-6 显示了事务结构。

图 2-6 无直接数据传输的 ReadNoSnp 和 ReadOnce* 结构
请求/响应规则为:
• 如果 ReadReceipt 是事务的一部分:
--- 必须仅在完成者接收到相关请求后发送。
--- 通常由完成者在 CompData 之前发送。但也允许在 CompData 之后发送。
--- 通常由请求者在 CompData 之前接收。但也允许在 CompData 之后接收。
• CompData 必须仅在完成者接收到相关请求后发送。
• 如果正在发送的数据是从从属设备或被监听的代理接收的,则允许 ICN 在收到来自从属设备或被监听代理的第一个数据包后立即转发 CompData 数据包。
• 如果 CompAck 是事务的一部分:
--- 请求者必须仅在接收到至少一个 CompData 数据包后才能发送 CompAck。
--- 允许(但不要求)请求者在发送 CompAck 之前等待 ReadReceipt。
--- 不允许完成者在发送 ReadReceipt 之前等待 CompAck。
排序和 CompAck 规则的影响总结
表 2-6 显示了对于来自 RN 的 ReadNoSnp 和 ReadOnce*,在不同排序和 CompAck 组合下 DMT 和 DCT 的使用情况。
表 2-6 来自 RN 的 ReadNoSnp 和 ReadOnce* 允许的 DMT 和 DCT

| Order[1:0] | ExpCompAck | DMT | DCT | 说明 |
|---|---|---|---|---|
| 00 | 0 | Y | Y | 主节点不需要获知事务完成。 对于 DMT,主节点必须从 SN 获取请求接受响应,以确保发送给 SN 的请求不会收到 RetryAck 响应。 |
| 00 | 1 | Y | Y | 主节点不需要获知事务完成。 对于 DMT,主节点可以通过从 SN 获取请求接受响应或等待 CompAck 响应来确保发送给 SN 的请求不会收到 RetryAck 响应。 |
| 01 | - | N | Y | 不允许。 |
| 10 | 0 | - | Y | 对于 DCT,主节点使用 SnpRespFwded 或 SnpRespDataFwded 监听响应来确定事务完成。 |
| 11 | 1 | Y | Y | 对于 DMT,主节点使用 CompAck 响应来确定事务完成。 对于 DCT,主节点使用 SnpRespFwd 或 SnpRespDataFwd 监听响应来确定事务完成。 |
带有分离的非数据响应和纯数据响应的读操作
本规范支持所有 Read* 事务从主节点返回分离的非数据响应以及从主节点或从属设备返回纯数据响应。
注意
在 CHI Issue C 之前不支持分离的非数据响应和纯数据响应。
此特性不适用于:
• 原子事务。
• 独占事务。
• 没有 CompAck 的有序 ReadNoSnp 和 ReadOnce* 事务。
带有分离的 Comp 和 Data 响应的 Read* 事务的进展如下:
来自主节点的 Comp 和来自从属设备的数据:
-
请求者在 REQ 通道上发送带有 Read* 操作码的请求。
-
主节点在 CRSP 通道上向请求者发送 RespSepData 响应。
• 这告诉请求者,事务已在主节点处相对于对同一地址的请求进行了排序,并且事务的数据将在单独的数据响应中提供。
-
请求者在 SRSP 通道上向 ICN 发送 CompAck 确认。
对于有序事务,CompAck 必须在接收到第一个数据响应数据包后发送。
-
ICN 在 REQ 通道上向 SN 发送 ReadNoSnpSep 请求。
• 这告诉作为完成者的从属设备发送 DataSepResp 响应。
-
SN 在 CSRP 通道上向主节点发送 ReadReceipt。
• 这告诉主节点,发送给从属设备的请求将被完成,并确保 SN 不会对该请求响应 RetryAck。
-
SN 作为完成者,向请求者发送 DataSepResp,返回读数据。
对于具有 Order 要求的 ReadOnce 和 ReadNoSnp 请求,主节点通过接收 CompAck 响应来确定请求已完成。
来自主节点的 Comp 和数据:
-
请求者在 REQ 通道上发送带有 Read* 操作码的请求。
-
主节点在 CRSP 通道上向请求者发送 RespSepData 响应。
• 这告诉请求者,事务已在主节点处相对于同一地址进行了排序,并且事务的数据将在单独的数据响应中提供。
-
主节点作为完成者,向请求者发送 DataSepResp,返回读数据。
-
请求者在 SRSP 通道上向主节点发送 CompAck 确认。
图 2-7 在第 2-51 页显示了事务结构。
来自主节点的 Comp 和来自从属设备的数据

图 2-7 带有分离的非数据响应和纯数据响应的 Read* DMT 结构
注意
如图 2-7 所示,请求者向 ICN 发送的 CompAck 确认允许(但不要求)等待 DataSepResp,除非在带有 CompAck 的有序 ReadOnce 和 ReadNoSnp 请求的情况下,它需要等待 RespSepData。
请求和响应规则为:
• DataSepResp 和 RespSepData 必须仅在完成者接收到相关请求后发送。仅允许主节点发送 RespSepData。允许从属设备或主节点发送 DataSepResp。
• CompAck 确认必须仅在接收到 RespSepData 响应后由请求者发送:
--- 对于非有序请求,允许(但不要求)请求者在发送 CompAck 确认之前等待接收任何或所有数据。
--- 对于具有 Order 要求的 ReadOnce 和 ReadNoSnp 请求,要求请求者在发送 CompAck 确认之前至少等待接收一个数据响应。
• 要求完成者在发送所有数据包之前不得等待 CompAck。
• ReadNoSnpSep 必须仅在主节点接收到相关请求并且所有需要发送的监听都接收到监听响应之后,才能由主节点发送给从属设备。
• 从属设备必须在接收到 ReadNoSnpSep 并确保不会对该请求响应 RetryAck 后,才向主节点发送 ReadReceipt 响应。
• 来自从属设备的 ReadReceipt 足以向主节点指示对从属设备的请求将被完成。
不需要从从属设备向主节点发送单独的 Comp 响应,且不得发送。对于具有 Order 要求的 ReadOnce 和 ReadNoSnp 请求,主节点通过接收 CompAck 响应来确定请求已完成。
• 对于具有 Order 要求的 ReadOnce 和 ReadNoSnp 事务,如果包含分离的 Comp 和 Data 响应,则主节点不得发送 ReadReceipt 响应。来自主节点的 RespSepData 响应包含一个隐含的 ReadReceipt。
在所有情况下,在可以使用分离的数据响应和主节点响应的地方,也允许使用组合的 CompData 响应。
第 2-53 页的表 2-7 显示了对于 ReadNoSnp 和 ReadOnce*,在不同 Order 和 ExpCompAck 值组合下,预期和允许使用分离的非数据响应和纯数据响应,或组合的 CompData 响应。
表 2-7 对于 ReadNoSnp 和 ReadOnce*,在不同 Order 和 ExpCompAck 组合下使用分离的 Comp 和 Data 响应


| 事务 | Order[1:0] | ExpCompAck | 说明 |
|---|---|---|---|
| ReadNoSnp ReadOnce* | 00 | 0 | 为事务提供响应的选项有: • 单个 CompData 响应。可以来自: --- 主节点。 --- 被监听的 RN-F(当使用 DCT 时)。 --- 从属设备(当使用 DMT 时)。主节点必须向从属设备请求 ReadReceipt。 • 分离的 RespSepData 和 DataSepResp 响应。 RespSepData 来自主节点。DataSepResp 可以来自: --- 主节点。 --- 从属设备。主节点必须向从属设备请求 ReadReceipt。 不使用从主节点到请求者的 ReadReceipt。不使用从请求者到主节点的 CompAck。 |
| ReadNoSnp ReadOnce* | 01 | 1 | 为事务提供响应的选项有: • 单个 CompData 响应。可以来自: --- 主节点。 --- 被监听的 RN-F(当使用 DCT 时)。 --- 从属设备(当使用 DMT 时)。主节点可以选择向从属设备请求 ReadReceipt。 • 分离的 RespSepData 和 DataSepResp 响应。 RespSepData 总是来自主节点。DataSepResp 可以来自: --- 主节点。 --- 从属设备。主节点可以选择向从属设备请求 ReadReceipt。 不使用从主节点到请求者的 ReadReceipt。 仅当以下情况发生后,才从请求者向主节点发送 CompAck: • 接收到 CompData。 • 接收到 RespSepData。也允许在发送 CompAck 之前等待相应的 DataSepResp 响应。 - 这不适用于从请求者到主节点的事务。 |
表 2-7 对于 ReadNoSnp 和 ReadOnce*,在不同 Order 和 ExpCompAck 组合下使用分离的 Comp 和 Data 响应 (续)
| 事务 | Order[1:0] | ExpCompAck | 说明 |
|---|---|---|---|
| ReadNoSnp ReadOnce* | 10 11 | 0 | 为事务提供响应的选项有: • 提供单个 CompData 响应。可以来自: --- 主节点。 --- 被监听的 RN-F(当使用 DCT 时)。 --- DMT 不允许。 • 不允许分离的 RespSepData 和 DataSepResp 响应。 使用从主节点到请求者的 ReadReceipt。 不使用从请求者到主节点的 CompAck。 |
| 1 | 为事务提供响应的选项有: • 单个 CompData 响应。可以来自: --- 主节点。 --- 被监听的 RN-F(当使用 DCT 时)。 --- 从属设备(当使用 DMT 时)。在这种情况下,主节点可以选择向从属设备请求 ReadReceipt。 • 分离的 RespSepData 和 DataSepResp 响应。RespSepData 总是来自主节点。DataSepResp 可以来自: --- 主节点。 --- 从属设备。主节点可以选择向从属设备请求 ReadReceipt。 从主节点到请求者的 ReadReceipt 取决于: • 如果使用单个 CompData 响应,则发送 ReadReceipt。 • 如果使用分离的 RespSepData 和 DataSepResp 响应,则不发送 ReadReceipt。RespSepData 用于指示与 ReadReceipt 相同的含义。 仅当以下情况发生后,才从请求者向主节点发送 CompAck: • 接收到 CompData。 • 同时接收到 RespSepData 响应和 DataSepResp 响应。 |
无数据操作
无数据事务可分为非缓存维护(Non-CMO)和缓存维护(CMO)事务。
非 CMO 事务有:
• CleanUnique。
• MakeUnique。
• Evict。
• StashOnceUnique。
• StashOnceShared。
这些事务具有多种功能,例如:
• 获取存储到缓存的权限。
• 更新监听过滤器的状态。
• 将数据移近预期未来使用点。
非 CMO 无数据事务只给出单个响应。
从请求者的角度来看,非 CMO 无数据事务的进展如下:
-
请求者在 REQ 通道上发送请求。
-
完成者在 CRSP 通道上返回一个 Comp 响应。
-
如果事务请求的 ExpCompAck 字段被设置,请求者必须使用 SRSP 通道上的 CompAck 操作码返回一个确认,表示事务已完成:
• ExpCompAck 必须为以下事务断言:
--- CleanUnique。
--- MakeUnique。
• ExCompAck 不得为以下事务断言:
--- Evict。
--- StashOnceUnique。
--- StashOnceShared。
图 2-8 显示了事务结构。

图 2-8 非 CMO 无数据事务结构
请求/响应规则为:
• Comp 必须仅在完成者接收到相关请求后发送。
• CompAck 必须仅在请求者接收到相关的 Comp 后发送。
CMO 事务有:
• CleanShared。
• CleanSharedPersist。
• CleanSharedPersistSep。
• CleanInvalid。
• MakeInvalid。
这些事务用于对系统中不同级别的缓存执行缓存维护。除了 CleanSharedPersistSep 之外,CMO 事务只给出单个响应。CleanSharedPersistSep 事务可以包含一个或两个响应。
从请求者的角度来看,CMO 无数据事务的进展如下:
-
请求者在 REQ 通道上发送请求。
-
完成者在 CRSP 通道上返回一个 Comp 响应。
-
对于 CleanSharedPersistSep 事务,完成者还向请求者返回一个 Persist 响应。允许完成者将 Comp 和 Persist 响应合并为一个 CompPersist 响应。
第 2-57 页的图 2-9 显示了事务结构,包括当请求传播到 ICN 下游时的事务结构。
请求/响应规则为:
• Comp 必须仅在完成者接收到相关请求后发送。
如果主节点下游有观察者,则主节点在向请求者发送 Comp 响应之前,必须等待来自下游的 Comp。
具体对于 CleanSharedPersistSep 请求:
• 主节点在向从属节点发送 CleanSharedPersistSep 时,允许(但不预期)在请求中设置 ReturnNID 为其自身。如果主节点将 ReturnNID 设置为其自身,则它必须除了 Comp 之外还向请求者发送一个 Persist 响应。主节点必须等待来自从属设备的 Persist 响应,然后才能向请求者发送 Persist 响应。在这种情况下,允许(但不预期)主节点等待来自从属设备的 Persist 响应,然后向请求者发送组合的 CompPersist 响应,而不是先发送单独的 Comp 响应。

图 2-9 CMO 事务结构
• 如果主节点是持久性点:
--- 主节点允许不将 CleanSharedPersistSep 请求转发给从属设备。当主节点决定不转发 CleanSharedPersistSep 请求时,它必须向请求者返回一个 Persist 响应。
--- 当主节点发送 Persist 响应时,允许(但不要求)将其与 Comp 合并,并向请求者发送单个 CompPersist 响应。
• 如果请求发送给从属节点,则:
--- 从属节点必须仅在保证其已接受请求且不会发送 RetryAck 响应后,才发回 Comp 响应。如果主节点下游有观察者,则仅当从属节点能保证所有较早对同一地址的写操作可以被系统中所有观察者观察到后,才能发送 Comp 响应。
--- 从属节点还必须在其能保证所有先前对同一地址到非易失性内存的写操作已持久化,并且即使在断电后地址位置也将包含更新值时,才向请求者发送 Persist 响应。
--- 如果目标为易失性内存,则可以立即给出 Persist 响应。这种情况不得返回错误。
写操作
写事务包括以下类型:
• WriteNoSnp。
• WriteUnique。
• WriteBack。
• WriteCleanFull。
• WriteEvictFull。
WriteNoSnp 和 WriteUnique
WriteNoSnp 事务有:
• WriteNoSnpPtl, WriteNoSnpFull。
WriteNoSnp 事务用于在执行存储时不需要监听其他主设备。
WriteUnique 事务有:
• WriteUniquePtl, WriteUniqueFull。
• WriteUniquePtlStash, WriteUniqueFullStash。
WriteUnique 事务用于在可能需要监听其他可监听请求者(RN-F)以获取存储权限的位置执行存储。
在本节剩余部分,非回写写操作将同时指代 WriteNoSnp 和 WriteUnique。
与非回写事务相关的一个可选行为。该行为由事务请求中的 Order 字段决定。关于使用 CompAck 强制请求被观察顺序的详细信息,请参见第 2-106 页的流式有序写事务。
非回写事务的进展如下:
-
请求者在 REQ 通道上发送带有非回写操作码的请求。
-
完成者有以下选项之一:
• 返回单独的响应:
--- 返回一个 DBIDResp 响应,提供一个数据缓冲区标识符,指示它可以接受该事务的写数据。
--- 返回一个 Comp 响应,指示该事务可被其他请求者观察。两个响应都在 CRSP 通道上返回。
• 返回单个组合的 CompDBIDResp 响应,以指示:
--- 它可以接受该事务的写数据。
--- 该事务可被其他请求者观察。组合响应在 CRSP 通道上返回。
-
请求者使用 NonCopyBackWrData 操作码在 WDAT 通道上发送写数据和任何相关的字节使能。写数据可以使用多次传输发送。参见第 2-118 页的数据传输。
-
如果在事务请求中设置了 ExpCompAck 字段,则事务以 CompAck 事务确认完成。作为机会,CompAck 可以与 Data 响应合并,并作为 NCBWrDataCompAck 发送。
第 2-60 页的图 2-10 显示了事务结构选项。

图 2-10 非回写写事务结构选项
• 单独的 DBIDResp 和 Comp,或组合的 CompDBIDResp,必须仅在互联接收到相关请求后发送。
• WriteData 必须仅在请求者接收到 DBIDResp 或 CompDBIDResp 后发送。
• 如果 DBIDResp 和 Comp 响应是分开发送的:
--- 通常,DBIDResp 由完成者在 Comp 之前发送。但是,允许 DBIDResp 和 Comp 以任何顺序发送。
--- 通常,DBIDResp 由请求者在 Comp 之前接收。但是,允许 DBIDResp 和 Comp 以任何顺序到达。
--- 请求者必须在收到 DBIDResp 响应后发送写数据。请求者不得在发送写数据之前等待接收 Comp 响应。
--- 允许请求者在发送组合的 NCBWrDataCompAck 响应或单独的 CompAck 和 NCBWrData 响应之前等待 DBIDResp 响应。
--- 允许完成者在发送 Comp 响应之前等待 WriteData。
• 如果需要 CompAck,则:
--- CompAck 必须仅在请求者接收到 Comp 或 DBIDResp 或 CompDBIDResp 响应后发送。
--- 首先收到 DBIDResp 响应的请求者允许发送组合的 NCBWrDataCompAck 响应或单独的 NCBWrData 和 CompAck 响应。
--- 首先收到 Comp 响应的请求者允许在发送组合的 NCBWrDataCompAck 或单独的 CompAck 和 NCBWrData 响应之前等待 DBIDResp 响应。
--- 当发送单独响应时,请求者允许以任何顺序发送 WriteData 和 CompAck。
--- 当发送组合的 NCBWrDataCompAck 时,请求者必须在所有数据传输中发送组合响应。
注意
在 CHI Issue D 之前,不允许在 WriteNoSnp 中断言 ExpCompAck。
回写操作
回写事务有:
• WriteBackPtl, WriteBackFull。
• WriteCleanFull。
• WriteEvictFull。
除 WriteEvictFull 外,回写事务用于更新主内存或下游缓存的一致性位置。
WriteEvictFull 事务仅用于更新下游缓存的一致性位置。WriteEvictFull 不得传播到其监听域之外。
回写事务的进展如下:
-
请求者在 REQ 通道上发送回写请求。
-
完成者在 CRSP 通道上返回单个组合的 CompDBIDResp 响应,以指示:
• 它可以接受该事务的写数据。
• 此请求将在接收到对同一地址的任何监听之前完成。
-
请求者收到 CompDBIDResp 响应后,使用 CopyBackWrData 操作码在 WDAT 通道上发送写数据和任何相关的字节使能。写数据可以使用多次传输发送。参见第 2-118 页的数据传输。
图 2-11 显示了事务结构。

图 2-11 回写事务结构
请求/响应规则为:
• CompDBIDResp 必须仅在完成者接收到相关请求后发送。
• WriteData 必须仅在请求者接收到 CompDBIDResp 响应后发送。
原子操作
原子事务可以根据其事务结构分为两类:
• 以下事务仅返回完成响应:
--- AtomicStore。
• 以下事务随完成响应返回数据:
--- AtomicLoad。
--- AtomicSwap。
--- AtomicCompare。
第 2-63 页的图 2-12 显示了请求者接口处的原子事务结构。
-
请求者在 REQ 通道上发送带有原子事务操作码的请求。
-
根据原子事务的类型,完成者有不同的选项:
a. 如果请求是 AtomicStore,则完成者有以下选项之一:
• 返回单独的响应:
--- 返回一个 DBIDResp 响应,提供一个数据缓冲区标识符,指示它可以接受该事务的写数据。
--- 返回一个 Comp 响应,指示该事务可被其他请求者观察。
两个响应都在 CRSP 通道上返回。
• 返回单个组合的 CompDBIDResp 响应,以指示:
--- 它可以接受该事务的写数据。
--- 该事务可被其他请求者观察。组合响应在 CRSP 通道上返回。
b. 如果请求是 AtomicLoad、AtomicSwap 或 AtomicCompare,则完成者执行以下操作:
• 在 CRSP 通道上返回一个 DBIDResp 响应。DBIDResp 响应提供一个数据缓冲区标识符,指示它可以接受该事务的写数据。
• 使用 RDAT 通道上的 CompData 操作码返回读数据和任何相关的事务响应。
-
请求者使用 NonCopyBackWrData 操作码在 WDAT 通道上发送写数据和任何相关的字节使能。对于 AtomicCompare,写数据可以使用多次传输发送。参见第 2-118 页的数据传输。
请求/响应规则为:
• 单独的 DBIDResp 和 Comp,或组合的 CompDBIDResp,必须仅在完成者接收到相关请求后发送。
• CompData 必须仅在完成者接收到相关请求后发送。
• WriteData 必须仅在请求者接收到 DBIDResp 或 CompDBIDResp 后发送。
• 如果请求是 AtomicStore 并且 DBIDResp 和 Comp 响应是分开发送的:
--- 通常,DBIDResp 由完成者在 Comp 之前发送。但是,允许 DBIDResp 和 Comp 以任何顺序到达。
--- 请求者必须在收到 DBIDResp 响应后发送写数据。
--- 请求者不得在发送写数据之前等待接收 Comp 响应。
--- 允许完成者在发送 Comp 响应之前等待 WriteData。
• 如果请求是 AtomicLoad、AtomicSwap 或 AtomicCompare 事务:
--- 通常,DBIDResp 由完成者在 CompData 之前发送。但是,允许 DBIDResp 和 CompData 以任何顺序发送。
--- 通常,DBIDResp 由请求者在 CompData 之前接收。但是,允许 DBIDResp 和 CompData 以任何顺序到达。
--- 请求者必须在收到 DBIDResp 响应后发送写数据。
--- 请求者不得在发送写数据之前等待接收 CompData 响应。
--- 允许完成者在发送 CompData 响应之前等待 WriteData。

图 2-12 原子事务结构
原子事务中的自监听
本规范允许在原子事务中对请求者进行自监听。图中未显示可选的自我监听。自监听由原子请求中的 SnoopMe 位值控制。参见第 12-343 页的 SnoopMe。原子事务中自我监听的请求-响应规则为:
• 在发送原子请求之前未使其自身缓存的缓存行副本失效的 RN 必须依赖自监听来:
--- 使其自身缓存的缓存行副本失效。
--- 如果脏,则获取缓存行的副本。
• 主节点:
--- 如果设置了 SnoopMe 位且主节点确定缓存行存在于请求者处,则必须向请求者发送监听。
--- 如果设置了 SnoopMe 位,且主节点确定缓存行不存在于请求者处,则允许(但不要求)向请求者发送监听。
--- 当原子请求中未设置 SnoopMe 位时,允许(但不要求)监听请求者。
--- 预期响应原子请求发送 SnpUnique,但允许发送 SnpCleanInvalid。
注意
允许 RN:
• 在对同一地址且 SnoopMe 被断言的原子请求进行中时,发送回写请求。
• 在对同一地址的回写请求进行中时,发出 SnoopMe 被断言的原子请求。
杂项请求类型
杂项事务包括以下类型:
• DVM。
• PrefetchTgt。
DVM
DVM 事务是 DVMOp。
DVM 事务用于发送分布式虚拟内存(DVM)操作。
DVM 事务的进展如下:
-
请求者在 REQ 通道上发送带有 DVMOp 操作码的请求。
-
完成者返回一个 DBIDResp 响应,提供一个数据缓冲区标识符,指示它可以接受该事务的写数据。
-
请求者使用 NonCopyBackWrData 操作码在 WDAT 通道上发送 DVM 事务的写数据。DVM 事务仅发生一次数据传输。
-
完成者在 CRSP 通道上返回一个 Comp 响应。
第 2-65 页的图 2-13 显示了事务结构。
请求/响应规则为:
• DBIDResp 必须仅在完成者接收到相关请求后发送。
• Comp 必须仅在完成者接收到相关请求后发送。
• 如果 DVMOp 是非同步 DVMOp,则允许(但不要求)互联在发送 Comp 之前等待 WriteData。
• 允许完成者机会性地将 Comp 和 DBIDResp 组合成 CompDBIDResp 响应。
• WriteData 必须仅在请求者接收到 DBIDResp 响应后发送。
PrefetchTgt
从请求节点直接发送到从属节点的可共享内存地址的请求。从属节点可以使用该请求从主内存预取和缓冲数据,以预期后续对同一位置的读请求。
PrefetchTgt 事务的进展如下:
• 请求者在 REQ 通道上发送一个 PrefetchTgt 请求。PrefetchTgt 事务不包含响应。
图 2-14 显示了事务结构。

图 2-14 PrefetchTgt 事务结构
请求/响应规则为:
• 请求者可以在请求发送后立即取消分配该请求。
• SN 必须无任何依赖地接受该请求,并且不允许重试。
• SN 可以丢弃该请求而不采取任何行动。

图 2-13 DVM 事务结构
2.3.2 事务重试序列
除了 PrefetchTgt,所有如第 2-39 页的请求事务结构中描述的请求事务都可以以重试序列开始。
重试序列
请求事务首先在无协议信用(P-Credit)的情况下发送。如果事务无法在其完成者处被接受,则必须给出一个 RetryAck 响应,指示该事务尚未被接受,并且可以在提供适当信用时再次发送。当事务第二次发送时,带有信用,则保证被接受。
关于重试过程和信用使用的更多详细信息,请参见第 2-129 页的请求重试。事务重试序列如下:
-
请求者在 REQ 通道上发送一个不带 P-Credit 的请求。
-
完成者在 CRSP 通道上提供一个 RetryAck 响应。
-
完成者在适当的时候在 CRSP 通道上提供一个 PCrdGrant 响应,以指示有信用可用于重新发送该事务。
-
请求者在 REQ 通道上再次发送该事务,并带有信用。
图 2-15 显示了 RetryAck 序列。
RN ICN
REQ 事务 无信用
CRSP RetryAck PCrdGrant
REQ 事务 带信用
事务重试序列规则为:
• RetryAck 必须仅在完成者接收到相关请求后发送。
• PCrdGrant 必须仅在完成者接收到相关请求后发送。
• RetryAck 通常由完成者在 PCrdGrant 之前发送。但是,允许在 PCrdGrant 之后发送 RetryAck。
• RetryAck 通常由请求者在 PCrdGrant 之前接收。但是,允许在 PCrdGrant 之后接收 RetryAck。
• 带信用的事务必须仅在请求者同时接收到 RetryAck 响应和适当的 PCrdGrant 响应后发送。

图 2-15 事务重试序列
不重试事务
协议支持在收到 RetryAck 到使用信用重新发送之间的某个时刻决定不重新发送事务。该序列与图 2-15 在第 2-66 页显示的事务重试序列相同,只是最后带信用的事务作为 PCrdReturn 事务发送。这充当一个空事务,并将信用返回给完成者。
序列和规则与重试序列相同。图 2-16 显示了取消的事务序列。
监听事务从互联发送到请求节点:
• RN-F 是完全一致的,并且需要接受所有监听事务。
• RN-D 仅支持接收 SnpDVMOp 事务。
• RN-F 和 RN-D 必须及时响应接收到的监听请求(DVMOp(Sync) 除外),不对未完成请求的完成产生任何依赖。
监听的事务结构有几种选项:
• 向主节点返回响应的监听。
• 向主节点返回数据的监听。
• 向请求者返回数据并向主节点返回响应的监听。
• 向请求者返回数据并向主节点返回数据的监听。
• 向杂项节点返回响应的 DVM 操作监听。
监听事务也可用于在被监听者处暂存数据。暂存类型监听的事务结构选项有:
• 带有来自主节点的数据的暂存监听。
• 使用 DMT 的带有数据的暂存监听。
注意
与监听事务相关的图显示被监听的请求节点(RN)在右侧,互联(ICN)在左侧。这与请求/监听过程的顺序一致。
2.3.3 监听事务

图 2-16 取消的事务序列
向主节点返回无数据的响应的监听
向主节点返回响应的监听事务的进展如下:
-
互联在 SNP 通道上提供一个监听请求,可以是 RN 支持的任何监听事务。
-
RN 在 SRSP 通道上返回 SnpResp 监听响应。
图 2-17 显示了事务结构。

图 2-17 向主节点返回响应的监听事务结构
向主节点返回响应的监听规则为:
• SnpResp 必须仅在 RN 接收到相关的监听请求后发送。
向主节点返回带数据的响应的监听
向主节点返回带数据的响应的监听事务的进展如下:
-
互联在 SNP 通道上提供一个监听请求。可以是以下监听事务之一:
• SnpOnceFwd, SnpOnce。
• SnpCleanFwd, SnpClean。
• SnpNotSharedDirtyFwd, SnpNotSharedDirty。
• SnpSharedFwd, SnpShared。
• SnpUniqueFwd, SnpUnique。
• SnpCleanShared。
• SnpCleanInvalid。
-
RN 使用 DAT 通道上的 SnpRespData 或 SnpRespDataPtl 操作码返回数据和相关的响应。

图 2-18 显示了事务结构。
向主节点返回带数据的监听规则为:
• SnpRespData 或 SnpRespDataPtl(根据需要)必须仅在 RN-F 接收到相关的监听请求后发送。
图 2-18 向主节点返回带数据的监听事务结构
将数据转发给请求者但不向主节点返回数据或向主节点返回数据的监听
将数据转发给请求者的监听事务的进展如下:
-
互联在 SNP 通道上提供一个监听请求。可以是以下监听事务之一:
• SnpOnceFwd。
• SnpCleanFwd。
• SnpNotSharedDirtyFwd。
• SnpSharedFwd。
• SnpUniqueFwd。
-
被监听的 RN 使用 WDAT 通道上的 CompData 操作码将数据转发给请求者,并且:
• 使用 SRSP 通道上的 SnpRespFwded 操作码向主节点发送响应。
• 使用 WDAT 通道上的 SnpRespDataFwded 操作码向主节点发送数据。
图 2-19 显示了向主节点返回响应但不返回数据的事务结构。

图 2-19 将数据转发给请求者并向主节点返回响应的监听
图 2-20 显示了向主节点返回带数据的响应的事务结构。

图 2-20 将数据转发给请求者并向主节点返回数据的监听
转发监听的监听请求/响应规则为:
• SnpRespFwded 或 SnpRespDataFwded 必须仅在监听到达者接收到相关的监听请求后发送。
• CompData 必须仅在监听到达者接收到相关的监听请求后发送。
• 监听到达者的 SnpRespFwded 或 SnpRespDataFwded 和 CompData 响应可以按任何顺序发送。
• CompAck 必须在接收到第一个数据响应数据包后发送。
暂存监听
图 2-21 显示了带有数据拉取、来自监听到达者的数据响应以及来自主节点的数据的暂存类型监听的示例。RN-F 响应监听提供数据。然后,RN-F 响应由 SnpRespData_Read 响应发起的读事务,被返回 CompData。

图 2-21 带有数据拉取、来自监听到达者的数据响应以及来自主节点数据的暂存类型监听
图 2-22 显示了带有数据拉取、无来自监听到达者的数据响应以及 DMT 的暂存类型监听的示例。数据由来自内存的 DMT 读操作提供。

图 2-22 带有数据拉取、无来自监听到达者的数据响应以及 DMT 的暂存类型监听
监听 DVMOp
SnpDVMOp 事务的进展如下:
-
互联在 SNP 通道上提供两个带有 SnpDVMOp 操作码的监听请求。
-
RN 在 SRSP 通道上返回一个单独的 SnpResp 监听响应。
图 2-23 显示了事务结构。

图 2-23 SnpDVMOp 事务结构
SnpDVMOp 规则为:
• SnpResp 响应必须仅在 RN 接收到两个监听请求后发送。
2.4 事务标识符字段
每个事务由许多不同的数据包组成,这些数据包在互联上传输。数据包内的一组标识符字段用于提供有关数据包的附加信息。不同的标识符字段有:
目标标识符 (TgtID)、源标识符 (SrcID)
这些标识符在互联上路由数据包。参见第 2-74 页的事务标识符字段详情和第 3 章 网络层。
事务标识符 (TxnID)、数据缓冲区标识符 (DBID)、返回事务标识符 (ReturnTxnID)、转发事务标识符 (FwdTxnID)
这些字段关联与单个事务相关的所有数据包。参见第 2-74 页的事务标识符字段详情。
数据标识符 (DataID)、关键块标识符 (CCID)
这些字段标识事务中的单个数据包。参见第 2-120 页的数据打包。
逻辑处理器标识符 (LPID)、暂存逻辑处理器标识符 (StashLPID)
这些字段标识单个请求者内的各个处理代理。参见第 2-98 页的逻辑处理器标识符。
持久性组标识符 (PGroupID)
该字段用于标识不同的 CleanSharedPersistSep 事务集。参见第 4-151 页的持久性组 ID 的使用。
暂存节点标识符 (StashNID)
该字段标识作为暂存目标的节点。参见第 7-256 页的支持 REQ 数据包字段。
返回节点标识符 (ReturnNID)、转发节点标识符 (FwdNID)
这些字段标识带数据的响应将发送到的节点。参见第 2-74 页的事务标识符字段详情。
主节点标识符 (HomeNID)
该字段用于标识 CompAck 响应将发送到的节点。参见第 2-74 页的事务标识符字段详情。
2.5 事务标识符字段详情
事务请求包含标识目标节点的 TgtID 和标识源节点的 SrcID。这些 ID 用于在互联上路由数据包。
事务请求包含一个 TxnID,用于标识来自给定请求者的事务。要求 TxnID(除了 PrefetchTgt)对于给定的请求者必须是唯一的。请求者由 SrcID 标识。这确保任何返回的读数据或响应信息可以与正确的事务相关联。
为 TxnID 定义了一个 10 位字段,以适应最多 1024 个未完成的事务。允许请求者在收到以下任一情况后重用 TxnID 值:
• 与先前使用相同值的旧事务相关的所有响应。
• 针对使用相同值的先前事务的 RetryAck 响应。
第 2-77 页的事务标识符字段流为不同的事务类型提供了更详细的规则。TxnID 字段不适用于 PrefetchTgt 请求,可以采用任何值。
注意
• 在 CHI Issue B 中,TxnID 不适用于 PrefetchTgt 请求,必须设置为零。
• 在 CHI issue D 之前,TxnID 字段宽度为 8 位,可容纳最多 256 个未完成的事务。
主节点在向从属设备发送的请求的 TxnID 字段中使用的值,可以在收到取消分配该请求所需的所有响应或收到 RetryAck 响应后,由主节点重用。
被重试的事务不要求使用相同的 TxnID。参见第 2-129 页的请求重试。
主节点向从属设备发送的事务请求包含一个 ReturnNID,用于确定来自从属设备的数据响应或 Persist 的 TgtID。其值必须为主节点的节点 ID 或原始请求者的节点 ID。
ReturnNID 仅适用于从主节点到从属设备的 ReadNoSnp、ReadNoSnpSep、CleanSharedPersistSep 和非存储原子请求。该字段不适用,并且必须在所有其他从主节点到从属设备的请求中设置为零。
ReturnNID 不适用,并且必须在所有从请求者到主节点和请求者到从属设备的请求中设置为零。
主节点向从属设备发送的事务请求还包含一个 ReturnTxnID 字段,用于在来自从属设备的数据响应中传达 TxnID 的值。其值在适用时必须为:
• 主节点生成的 TxnID(当 ReturnNID 是主节点的节点 ID 时)。
• 原始请求者的 TxnID(当 ReturnNID 是原始请求者的节点 ID 时)。
ReturnTxnID 仅适用于从主节点到从属设备的 ReadNoSnp、ReadNoSnpSep 和非存储原子请求。该字段不适用,并且必须在所有其他从主节点到从属设备的请求中设置为零。
ReturnTxnID 不适用,并且必须在所有从请求者到主节点和请求者到从属设备的请求中设置为零。
来自主节点和从属节点的 CompData 包含 HomeNID 字段,请求者使用该字段来识别它可能需要为响应 CompData 而发送的 CompAck 的目标。HomeNID 适用于 CompData 和 DataSepResp,对于所有其他数据消息不适用,必须设置为零。
CleanSharedPersistSep 请求包含一个 PGroupID,用于标识该请求所属的持久性组。这个 5 位字段仅适用于:
• 从请求者到主节点的 CleanSharedPersistSep。
• 从主节点到从属设备的 CleanSharedPersistSep。
• 来自主节点的 Persist 响应。
• 来自从属设备的 Persist 响应。
• 从从属设备到主节点的 CompPersist 响应。
它在所有其他请求和响应中不适用,并且必须设置为零。
DataSepResp 响应中的 HomeNID 和 DBID 字段没有功能上的要求,因为 RespSepData 响应中提供的值是相同的,并且始终可以使用。但是,本规范要求包含这些值以帮助调试和协议检查。
从主节点到 RN-F 的监听请求包含一个 FwdNID,用于确定来自 RN-F 的数据响应的 TgtID。其值必须是原始请求者的 NodeID。
FwdNID 字段仅适用于:
• SnpSharedFwd。
• SnpCleanFwd。
• SnpOnceFwd。
• SnpNotSharedDirtyFwd。
• SnpUniqueFwd。
它在所有其他监听中不适用,并且必须设置为零。
从主节点到 RN-F 的监听请求还包含一个 FwdTxnID 字段,用于在来自 RN-F 的数据响应中传达 TxnID 的值。其值必须是原始请求的 TxnID。
FwdTxnID 字段仅适用于:
• SnpSharedFwd。
• SnpCleanFwd。
• SnpOnceFwd。
• SnpNotSharedDirtyFwd。
• SnpUniqueFwd。
它在所有其他监听中不适用,并且必须设置为零。
DBID 字段允许事务的完成者提供其自身的事务标识符。完成者发送一个包含 DBID 的响应。DBID 值用作以下响应中的 TxnID 字段值:
• 写操作、原子操作和 DVMOp 事务的 WriteData 响应。
• 用于数据拉取目的的暂存事务的 CompData 响应。
• 包含 CompAck 响应的读操作、无数据操作和 WriteUnique 事务的 CompAck 响应。
在以下情况下,给定事务的响应中完成者使用的 DBID 值对于给定的请求者必须是唯一的:
• 所有写事务的 DBIDResp 或 CompDBIDResp。
• 原子事务的 DBIDResp 或 CompDBIDResp。
• DVMOp 事务的 DBIDResp。
• 包含 CompAck 的读事务的 CompData 或 RespSepData,除非 ReadOnce* 和 ReadNoSnp 不使用由此产生的 CompAck 在主节点处取消分配请求。
• 包含 CompAck 的无数据事务的 Comp。
DBID 值适用于对包含 CompAck 的读请求的 DataSepResp 响应,并且必须与相关 RespSepData 响应中的 DBID 值相同。
对于写事务,与 DBIDResp 消息分开发送的 Comp 响应消息必须在 Comp 和 DBIDResp 消息中包含相同的 DBID 字段值。
对于原子事务,与 DBIDResp 消息分开发送的 Comp 响应消息允许(但不要求)在 Comp 和 DBIDResp 消息中包含相同的 DBID 字段值。
允许(但不要求)完成者对两个具有不同请求者的事务使用相同的 DBID 值。允许完成者在收到取消分配使用相同值的先前事务所需的所有数据包后重用 DBID 值。第 2-77 页的事务标识符字段流为不同的事务类型提供了更详细的规则。
在响应包含数据拉取的暂存类型监听时,监听完成者使用的 DBID 值必须相对于以下内容是唯一的:
• 对其他使用数据拉取的暂存类型监听的监听响应中的 DBID 值。
• 来自该监听完成者的任何未完成请求的 TxnID。
完成者不需要为以下事务使用 DBID 字段:
• 不带 CompAck 的读事务。
• 不带 CompAck 的无数据事务。
• 对不包含数据拉取的暂存类型监听的监听响应。
• 对非暂存类型监听的监听响应。
注意
使用由完成者分配的 DBID 而不是由请求者分配的 TxnID 的好处是,完成者可以使用 DBID 索引到其请求结构中,而不是使用 TxnID 和 SrcID 执行查找,以确定哪个事务的写数据或完成确认与哪个请求相关联。
如果完成者对不同请求者使用相同的 DBID 值(如果其操作需要同时有超过 1024 个 DBID 响应处于活动状态,则必须这样做),那么它必须结合使用 SrcID 和 DBID 来确定哪个请求应与写数据或响应消息相关联。
DBIDResp 响应还用于提供与事务相关的某些排序保证。参见第 2-102 页的事务排序。
2.6 事务标识符字段流
本节展示了不同事务类型的事务标识符字段流:
• 第 2-78 页的读事务。
• 第 2-86 页的无数据事务。
• 第 2-88 页的写事务。
• 第 2-96 页的 DVMOp 事务。
• 第 2-96 页的带重试的事务请求。
• 第 2-97 页的协议信用返回事务。
在相关图中:
• 每个数据包中包含的字段有:
--- 对于请求数据包:TgtID、SrcID、TxnID、StashNID、StashLPID、ReturnNID 和 ReturnTxnID。
--- 对于响应数据包:TgtID、SrcID、TxnID 和 DBID。
--- 对于数据数据包:TgtID、SrcID、TxnID、HomeNID 和 DBID。
--- 对于监听数据包:SrcNID、TxnID、FwdNID、FwdTxnID 和 StashLPID。
• 所有颜色相同的字段都具有相同的值。
• 弯曲的环回箭头显示了请求者和完成者如何使用来自先前数据包的字段来生成后续数据包的字段。
• 包含星号 [*] 的框表示字段首次生成的时间,即它指示确定字段原始值的代理。
• 括在括号中的字段表示该值实际上是固定值。通常,当数据包发送时 SrcID 字段是这样,当数据包到达其目的地时 TgtID 字段是这样。
• 被划掉的字段表示该字段无效。
• 允许互联将原始事务的 TgtID 重新映射到一个新值。这由包含字母 R 的框表示。这在第 3 章 网络层中有更详细的解释。
注意
在每个发送的数据包中,标识符字段属于以下类别之一:
• 新值。星号表示生成了新值。
• 从较早的数据包生成。环回箭头表示源。
• 固定值。该值括在方括号中。
• 无效。该字段被划掉。
在以下示例中,为清晰起见,有时会省略与示例无关的任何事务 ID。
2.6.1 读事务
本节展示了在有和没有直接数据传输的读事务中的标识符字段流:
• 带有 DMT 的 ID 值传递。
• 第 2-80 页的带有 DMT 和分离的 Comp 和 Data 的 ID 值传递。
• 第 2-82 页的带有 DCT 的 ID 值传递。
• 第 2-84 页的无直接数据传输的 ID 值传递。
带有 DMT 的 ID 值传递
图 2-24 显示了 DMT 事务消息中的目标和事务 ID 值是如何推导的。例如,ICN 在 ReadNoSnp 请求中的 SrcID 值由 ICN 分配,而用作数据响应中 TgtID 的 ReturnNID 被设置为接收到的读请求的 SrcID 值。

图 2-24 所示的流程中所需的步骤是:
-
请求者通过发送请求数据包开始事务。
请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个对该请求者唯一的 TxnID 字段。
-
ICN 中的接收主节点向从属节点生成一个请求。请求的标识符字段生成如下:
• TgtID 设置为从属设备所需的值。
• SrcID 是主节点的固定值。
• TxnID 是由主节点生成的唯一值。
• ReturnNID 设置为与原始请求的 SrcID 相同的值。
• ReturnTxnID 设置为与原始请求的 TxnID 相同的值。
-
如果对从属设备的请求需要 ReadReceipt,则从属设备提供该读接收确认。
ReadReceipt 响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是从属设备的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 TxnID 相同的值。
• DBID 字段无效。
-
从属设备提供读数据。
读数据响应的标识符字段生成如下:
• TgtID 设置为与请求的 ReturnNID 相同的值。
• SrcID 是从属设备的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 ReturnTxnID 相同的值。
• HomeNID 设置为与请求的 SrcID 相同的值。
• DBID 设置为与请求的 TxnID 相同的值。
-
请求者接收读数据并发送 CompAck 确认。
CompAck 的标识符字段生成如下:
• TgtID 设置为与读数据的 HomeNID 相同的值。
• SrcID 是请求者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与读数据的 DBID 相同的值。
• DBID 字段无效。
并非所有请求都需要从请求者到主节点的 CompAck 响应。
如果原始请求需要 ReadReceipt,则包括以下附加步骤:
• 主节点接收请求数据包并提供读接收确认。
ReadReceipt 响应的标识符字段生成如下:
--- TgtID 设置为与请求的 SrcID 相同的值。
--- SrcID 是完成者的固定值。这也匹配接收到的 TgtID。
--- TxnID 设置为与请求的 TxnID 相同的值。
--- DBID 字段无效。
何时可以重用 TxnID 值和 DBID 值的详细信息见第 2-74 页的事务标识符字段详情。
带有 DMT 和分离的 Comp 和 Data 的 ID 值传递
图 2-25 显示了在使用分离的 Comp 和 Data 的 DMT 事务消息中标识符字段值是如何推导的。

图 2-25 带有 DMT 和分离的 Comp 和 Data 的事务中的 ID 值传递
图 2-25 所示的流程中所需的步骤是:
-
请求者通过发送请求数据包开始事务。请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个对该请求者唯一的 TxnID 字段。
- ICN 中的接收主节点向从属节点生成一个请求。
请求的标识符字段生成如下:
• TgtID 设置为从属设备所需的值。
• SrcID 是主节点的固定值。
• TxnID 是由主节点生成的唯一值。
• ReturnNID 设置为与原始请求的 SrcID 相同的值。
• ReturnTxnID 设置为与原始请求的 TxnID 相同的值。
-
ICN 中的接收主节点提供单独的读响应。读响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是主节点的固定值。
• TxnID 设置为与原始请求的 TxnID 相同的值。
• DBID 值是由主节点生成的唯一值,并且与发送给从属设备的请求中的 TxnID 值相同。
-
请求者接收读响应并发送 CompAck 确认。
CompAck 的标识符字段生成如下:
• TgtID 设置为与读响应的 SrcID 相同的值。
• SrcID 是请求者的固定值。
• TxID 设置为主节点生成的唯一 DBID 值。
• DBID 值无效。
-
对从属设备的请求需要 ReadReceipt,从属设备提供该读接收确认。
ReadReceipt 响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是从属设备的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 TxnID 相同的值。
-
从属设备提供单独的读数据。
读数据的标识符字段生成如下:
• TgtID 设置为与请求的 ReturnNID 相同的值。
• SrcID 是从属设备的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 ReturnTxnID 相同的值。
• HomeNID 设置为与请求的 SrcID 相同的值。
• DBID 设置为与请求的 TxnID 相同的值。
带有 DCT 的 ID 值传递
图 2-26 显示了 DCT 事务消息中标识符字段值是如何推导的。在此示例中,数据被转发给 RN,并且带或不带数据的监听响应被发送给 HN-F。

图 2-26 DCT 事务中的 ID 值传递
图 2-26 所示的流程中所需的步骤是:
-
请求者通过发送请求数据包开始事务。请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个对该请求者唯一的 TxnID 字段。
- ICN 中的接收主节点向 RN-F 节点生成一个转发监听。
监听的标识符字段生成如下:
• SrcID 是主节点的固定值。
• TxnID 是由主节点生成的唯一值。
• FwdNID 设置为与原始请求的 SrcID 相同的值。
• FwdTxnID 设置为与原始请求的 TxnID 相同的值。
- RN-F 提供读数据。
读数据响应的标识符字段生成如下:
• TgtID 设置为与监听的 FwdNID 相同的值。
• SrcID 是 RN-F 的固定值。
• TxnID 设置为与监听的 FwdTxnID 相同的值。
• HomeNID 设置为与监听的 SrcID 相同的值。
• DBID 设置为与监听的 TxnID 相同的值。
-
RN-F 还向主节点提供一个响应,可以带或不带读数据。响应的标识符字段生成如下:
• TgtID 设置为与监听的 SrcID 相同的值。
• SrcID 是 RN-F 的固定值。
• TxnID 设置为与监听的 TxnID 相同的值。
• DBID 字段无效。
-
请求者接收读数据并发送 CompAck 确认。CompAck 的标识符字段生成如下:
• TgtID 设置为与读数据的 HomeNID 相同的值。
• SrcID 是请求者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与读数据的 DBID 相同的值。
• DBID 字段无效。
注意
也可以包括从 ICN 到请求者的可选 ReadReceipt。
无直接数据传输的 ID 值传递
本节给出了一个没有 DMT 或 DCT 的读标识符字段流示例,并描述了读事务中 TxnID 和 DBID 字段的使用。
此示例中的请求者和完成者分别是 RN 和 HN-F。
标识符字段流包括来自完成者的可选 ReadReceipt 响应,以及来自请求者的可选 CompAck 响应。
对于包含 CompAck 响应的读事务,完成者使用 DBID 将 CompAck 与原始事务关联。
不包含 CompAck 响应的读事务在数据响应中不需要有效的 DBID 字段。
图 2-27 显示了 ID 值传递。

图 2-27 带有 ReadReceipt 和 CompAck 的读请求中的 ID 值传递
图 2-27 所示的流程中所需的步骤是:
-
请求者通过发送请求数据包开始事务。
请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个对该请求者唯一的 TxnID 字段。
-
如果事务包含 ReadReceipt,完成者接收请求数据包并提供读接收确认。
ReadReceipt 响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是完成者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 TxnID 相同的值。
• DBID 字段无效。
-
完成者接收请求数据包并提供读数据。
读数据响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是完成者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 TxnID 相同的值。
• HomeNID 是完成者的固定值。这也匹配接收到的 TgtID。
• 如果请求中的 ExpCompAck 被断言,完成者生成一个唯一的 DBID 值。
-
请求者接收读数据并发送 CompAck 确认。
CompAck 的标识符字段生成如下:
• TgtID 设置为与读数据的 HomeNID 相同的值。
• SrcID 是请求者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与读数据的 DBID 相同的值。
• DBID 字段无效。
2.6.2 无数据事务
对于无数据事务,除了 CleanSharedPersistSep 之外,标识符字段的使用类似于第 2-84 页的无直接数据传输的 ID 值传递。唯一的区别是,从完成者到请求者的响应是在 CRSP 通道上作为单个数据包发送,而不是在 RDAT 通道上作为多个数据包发送。
CleanSharedPersistSep 事务中的 ID 值传递
图 2-28 显示了在使用分离的 Comp 和 Persist 的 CleanSharedPersistSep 事务消息中标识符字段值是如何推导的。

图 2-28 CleanSharedPersistSep 事务中的 ID 值传递
图 2-28 所示的流程中所需的步骤是:
-
请求者通过发送请求数据包开始事务。请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个对该请求者唯一的 TxnID 值。
在收到 Comp 响应后,请求者可以重用该 TxnID 值。
• 请求者生成一个新的 PGroupID 值,或重用当前正在使用的 PGroupID 值。
-
ICN 中的接收主节点向从属设备生成一个请求。
发送给从属节点的请求的标识符字段生成如下:
• TgtID 设置为从属设备所需的值。
• SrcID 是主节点的固定值。
• TxnID 是由主节点生成的唯一值。
在收到 Comp 响应后,主节点可以重用该 TxnID 值。
• ReturnNID 设置为与原始请求的 SrcID 相同的值。
• ReturnTxnID 不适用,必须设置为零。
• PGroupID 设置为与原始请求的 PGroupID 相同的值。
-
ICN 中的接收主节点向请求者发送一个 Comp 响应。
发送给请求者的 Comp 响应的标识符字段生成如下:
• TgtID 设置为与原始请求的 SrcID 相同的值。
• SrcID 是主节点的固定值。
• TxnID 设置为与原始请求的 TxnID 相同的值。
-
ICN 中的接收主节点可以选择向请求者发送一个 Persist 响应。
从主节点到请求者的可选 Persist 响应(未在图 2-28 第 2-86 页中显示)的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是主节点的固定值。
• TxnID 不适用,必须设置为零。
• PGroupID 设置为与请求的 PGroupID 相同的值。
接收主节点可以选择向请求者发送一个组合的 CompPersist 响应,而不是单独的 Comp 和 Persist 响应。
CompPersist 响应中的标识符字段生成如下:
• TgtID 设置为与原始请求的 SrcID 相同的值。
• SrcID 是主节点的固定值。
• TxnID 设置为与原始请求的 TxnID 相同的值。
• PGroupID 设置为与原始请求的 PGroupID 相同的值。
-
从属节点向主节点生成一个 Comp。
来自从属节点的 Comp 响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是从属设备的固定值。
• TxnID 设置为与请求的 TxnID 相同的值。
-
从属节点还向请求者或主节点生成一个 Persist 响应。
来自从属节点的 Persist 响应的标识符字段生成如下:
• TgtID 设置为与请求的 ReturnNID 相同的值。
• SrcID 是从属设备的固定值。
• TxnID 不适用,必须设置为零。
• PGroupID 设置为与请求的 PGroupID 相同的值。
-
如果请求的 ReturnNID 和 SrcID 是相同的值,则从属节点可以选择向主节点发送一个组合的 CompPersist 响应,而不是单独的 Comp 和 Persist 响应。
来自从属设备的 CompPersist 响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是从属设备的固定值。
• TxnID 设置为与请求的 TxnID 相同的值。
• PGroupID 设置为与请求的 PGroupID 相同的值。
2.6.3 写事务
本节描述了写事务中 TxnID 和 DBID 字段的使用:
• 回写事务。
• 第 2-90 页的 WriteNoSnp 事务。
• 第 2-92 页的 WriteUnique 事务。
• 第 2-94 页的 StashOnce 事务。
回写事务
本节描述了回写事务中标识符字段的使用。图 2-29 显示了 ID 值传递。

图 2-29 回写事务中的 ID 值传递
图 2-29 所示的流程中所需的步骤是:
-
请求者通过发送请求数据包开始事务。请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个唯一的 TxnID 字段。
- 完成者接收请求数据包并生成一个 CompDBIDResp 响应。响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是完成者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 TxnID 相同的值。
• 完成者生成一个唯一的 DBID 值。
-
请求者接收 CompDBIDResp 响应并发送写数据。写数据的标识符字段生成如下:
• TgtID 设置为与 CompDBIDResp 响应的 SrcID 相同的值。如果该值被互联重新映射,这可能与请求的原始 TgtID 不同。
• SrcID 是请求者的固定值。
• TxnID 设置为与 CompDBIDResp 响应中提供的 DBID 值相同的值。
• 写数据中的 DBID 字段未使用。
• 所有写数据数据包的 TgtID、SrcID 和 TxnID 字段必须相同。
在收到 CompDBIDResp 响应后,请求者可以为另一个事务重用请求数据包中使用的相同 TxnID 值。
-
完成者接收写数据,并使用 TxnID 字段(现在包含完成者生成的 DBID 值)来确定写数据与哪个事务相关联。
在收到所有写数据数据包后,完成者可以为另一个事务重用相同的 DBID 值。
WriteNoSnp 事务
本节描述了 WriteNoSnp 事务中标识符字段的使用。
图 2-30 显示了分离的 Comp 和 DBIDResp 的 ID 值传递。完成者可以将 Comp 和 DBIDResp 机会性地组合成单个 CompDBIDResp 响应。请求者可以将 NCBWrData 与 CompAck 机会性地组合。

图 2-30 WriteNoSnp 中的 ID 值传递
标识符字段的使用与具有组合响应的事务相同,但附加要求是:
• 用于分离的 DBIDResp 和 Comp 响应的标识符字段必须相同。
• 请求者只有在同时收到 DBIDResp 和 Comp 响应后,才能重用 TxnID 值。
2-90
图 2-30 在第 2-90 页所示的流程中所需的步骤是:
-
请求者通过发送请求数据包开始事务。请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个唯一的 TxnID 字段。
- 完成者接收请求数据包并生成一个 DBIDResp 响应。响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是完成者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 TxnID 相同的值。
• 完成者生成一个唯一的 DBID 值。
- 请求者接收 DBIDResp 响应并发送写数据。写数据的标识符字段生成如下:
• TgtID 设置为与 DBIDResp 响应的 SrcID 相同的值。如果该值被互联重新映射,这可能与请求的原始 TgtID 不同。
• SrcID 是请求者的固定值。
• TxnID 设置为与 DBIDResp 响应中提供的 DBID 值相同的值。
• 写数据中的 DBID 字段未使用。
• 所有写数据数据包的 TgtID、SrcID 和 TxnID 字段必须相同。
-
完成者接收写数据,并使用 TxnID 字段(现在包含完成者生成的 DBID 值)来确定写数据与哪个事务相关联。
-
当事务完成时,完成者生成一个 Comp 响应。
Comp 响应的标识符字段必须与 DBIDResp 响应相同,生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是完成者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 TxnID 相同的值。
• 完成者使用与 DBIDResp 响应中使用的相同的 DBID 值。
- 如果事务需要,请求者在收到 DBIDResp 或 Comp 后发送 CompAck 消息。CompAck 的标识符字段生成如下:
• TgtID 设置为与 DBIDResp 或 Comp 响应的 SrcID 相同的值。
• SrcID 是请求者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与 DBIDResp 或 Comp 响应的 DBID 相同的值。
• DBID 字段无效。
在同时收到 Comp 和 DBIDResp 响应后,请求者可以为另一个事务重用相同的 TxnID 值。
在收到所有写数据数据包后,完成者可以为另一个事务重用相同的 DBID 值。
注意
分离的 DBIDResp 和 Comp 响应之间没有排序要求。规范要求是使用的值相同。
WriteUnique 事务
本节描述了 WriteUnique 事务中标识符字段的使用。WriteUnique 事务在某些情况下还可以包括从请求者到完成者的 CompAck 响应。在这种情况下,标识符字段使用的附加规则是:
• 从请求者到完成者的 CompAck 响应的 TgtID、SrcID 和 TxnID 标识符字段必须与用于写数据的字段相同,即:
--- TgtID 设置为与 CompDBIDResp 响应的 SrcID 相同的值。如果给出单独的 Comp 和 DBIDResp 响应,则 TgtID 设置为与 Comp 或 DBIDResp 响应的 SrcID 相同的值,因为两者中的 SrcID 值必须相同。但是,如果该值已被互联重新映射,这可能与请求的原始 TgtID 不同。
--- SrcID 是请求者的固定值。
--- TxnID 设置为与 CompDBIDResp 响应中提供的 DBID 值相同的值。如果给出单独的 Comp 和 DBIDResp 响应,则 TxnID 设置为与 Comp 或 DBIDResp 响应的 DBID 相同的值,因为两者中的 DBID 值必须相同。
--- WriteData 和 CompAck 中的 DBID 字段未使用。
--- 如果发送组合的 WriteData 和 CompAck 响应,则 TgtID 设置为与 Comp、DBIDResp 或 CompDBIDResp 中的 SrcID 相同的值,组合响应中的 TxnID 设置为与 Comp、DBIDResp 或 CompDBIDResp 中的 DBID 相同的值。
• 完成者必须在为另一个事务重用相同的 DBID 值之前接收所有写数据项和 CompAck 响应。
图 2-31 显示了带有组合的 CompDBIDResp 响应的 ID 值传递。

图 2-31 带有组合的 CompDBIDResp 响应的 ID 值传递
图 2-32 显示了带有组合的 WriteData 和 CompAck 响应的 ID 值传递。

图 2-32 带有组合的 WriteData 和 CompAck 响应的 ID 值传递
注意
在 CHI.C 之前,不允许组合 NCBWrData 和 CompAck。
StashOnce 事务
本节描述了带有 DataPull 的 StashOnce 事务中标识符字段的使用。图 2-33 显示了 ID 值传递。

图 2-33 暂存事务中的 ID 值传递
图 2-33 所示的流程中所需的步骤是:
-
请求者通过发送暂存请求数据包开始事务。请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个对该请求者唯一的 TxnID 字段。
• 请求者包含 StashNID 字段以指示要将暂存发送到的 RN-F。
• 请求者包含 StashLPID 字段以指示 RN-F 内的逻辑处理器。
2-94
-
ICN 中的主节点接收暂存请求数据包,并向适当的 RN-F 生成一个带有暂存的监听。
请求的标识符字段生成如下:
• SrcID 是主节点的固定值。
• TxnID 是由主节点生成的唯一值。
• StashLPID 设置为与原始请求的 StashLPID 相同的值。
注意
监听请求不包含 TgtID 字段。
- 被监听的 RN-F 生成一个监听响应。在此示例中,它包含一个数据拉取指示。监听响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是 RN-F 的固定值。
• TxnID 设置为与请求的 TxnID 相同的值。
• DBID 字段是由 RN-F 生成的唯一值。
- 主节点提供读数据。
读数据响应的标识符字段生成如下:
• TgtID 设置为与监听响应的 SrcID 相同的值。
• SrcID 是主节点的固定值。
注意
在此示例中,读数据由主节点提供。
• TxnID 设置为与监听响应的 DBID 相同的值。
• DBID 字段是由主节点生成的唯一值。
• HomeNID 是主节点的固定值。
- RN-F 接收读数据并发送 CompAck 确认。CompAck 的标识符字段生成如下:
• TgtID 设置为与读数据的 HomeNID 相同的值。
• SrcID 是 RN-F 的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与读数据的 DBID 相同的值。
• DBID 字段无效。
2.6.4 DVMOp 事务
DVMOp 事务的 TgtID、SrcID、TxnID 和 DBID 标识符字段的使用与第 2-90 页的 WriteNoSnp 事务完全相同。
2.6.5 带重试的事务请求
对于收到 RetryAck 响应的事务,关于如何使用标识符字段有特定规则。有关重试机制的更多详细信息,请参见第 2-129 页的请求重试,有关返回未使用信用的规则,请参见第 2-97 页的协议信用返回事务。
图 2-34 显示了 ID 值传递。

图 2-34 带重试的事务请求中的 ID 值传递
图 2-34 所示的流程中所需的步骤是:
-
请求者通过发送请求数据包开始事务。请求的标识符字段生成如下:
• TgtID 由请求的目的地决定。
2-96
注意
TgtID 字段可以被互联重新映射为不同的值。
• SrcID 是请求者的固定值。
• 请求者生成一个唯一的 TxnID 字段。
-
完成者接收请求数据包并确定它将发送 RetryAck 响应。RetryAck 响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是完成者的固定值。这也匹配接收到的 TgtID。
• TxnID 设置为与请求的 TxnID 相同的值。
• DBID 字段无效。
• 完成者使用一个 PCrdType 值,该值指示重试事务所需要的信用类型。
-
当完成者能够接受给定 PCrdType 的重试事务时,它使用 PCrdGrant 响应向请求者发送一个信用。PCrdGrant 响应的标识符字段生成如下:
• TgtID 设置为与请求的 SrcID 相同的值。
• SrcID 是完成者的固定值。这也匹配请求的 TgtID。
• TxnID 字段未使用,必须设置为零。
• DBID 字段未使用,必须设置为零。
• PCrdType 值设置为再次发出原始事务所需要的类型。
-
请求者接收信用授予并通过发送请求数据包重新发出原始事务。请求的标识符字段生成如下:
• TgtID 设置为与 RetryAck 响应的 SrcID 相同的值(也是 PCrdGrant 响应的 SrcID),或设置为原始请求中使用的值。
• SrcID 是请求者的固定值。
• 请求者生成一个唯一的 TxnID 字段。允许与收到 RetryAck 响应的原始请求不同。
• PCrdType 值设置为原始请求的 RetryAck 响应中的 PCrdType 值,该值也与 PCrdGrant 响应的 PCrdType 相同。
2.6.6 协议信用返回事务
协议信用返回事务使用 PCrdReturn 请求来返回已授予但不再需要的信用。TgtID、SrcID 和 TxnID 的要求是:
• 请求者通过发送 PCrdReturn 请求数据包来发送协议信用返回事务。请求的标识符字段生成如下:
--- TgtID 必须与所获信用的 SrcID 匹配。
--- SrcID 是请求者的固定值。
--- TxnID 字段未使用,必须设置为零。
PCrdType 必须与最初再次发出事务所需的原始 PCrdGrant 中的 PCrdType 值匹配。
与协议信用返回事务关联的 DBID 字段没有响应或使用。
2.7 逻辑处理器标识符
本规范在事务请求中定义了一个逻辑处理器标识符(LPID)字段。当单个请求者包含多个逻辑上分离的处理代理时,使用此字段。
LPID 必须为以下事务设置为正确的值:
• 对于任何不可监听的、不可缓存的或设备访问:
--- ReadNoSnp。
--- WriteNoSnp。
• 对于独占访问,可以是以下事务类型之一:
--- ReadClean。
--- ReadShared。
--- ReadNotSharedDirty。
--- CleanUnique。
--- ReadNoSnp。
--- WriteNoSnp。
更多详细信息,请参见第 6 章 独占访问。
注意
对于其他事务,LPID 值可用于指示导致事务发出的原始逻辑处理器。但是,本规范不需要此信息,并且是可选的。
2.8 排序
本节描述了协议中包含的支持系统排序要求的机制。它包含以下子部分:
• 多副本原子性。
• 完成响应和排序。
• 第 2-100 页的完成确认。
• 第 2-102 页的事务排序。
关于术语 EWA、设备和可缓存的含义,请参见第 2-110 页的内存属性。
2.8.1 多副本原子性
本规范要求多副本原子架构。所有符合要求的组件必须确保所有写类型请求都是多副本原子的。如果满足以下两个条件,则写操作被定义为多副本原子的:
• 所有对同一位置的写操作都被串行化,即它们被所有请求者以相同的顺序观察到,尽管某些请求者可能未观察到所有写操作。
• 对一个位置的读操作不会返回一个写操作的值,直到所有请求者都观察到该写操作。
在本规范中,如果两个地址的缓存行地址和 NS 属性相同,则认为它们在一致性、可观察性和冒险方面是相同的。
2.8.2 完成响应和排序
为了保证事务相对于后续事务(无论是来自同一代理还是来自另一代理)的排序,使用 Comp、RespSepData、CompData 或 Persist 响应,如下所示:
• 对于对不可缓存或设备位置的读事务,RespSepData 或 CompData 响应保证该事务对于稍后来自任何代理到同一端点地址范围的事务是可观察的。端点地址范围的大小由具体实现定义。
• 对于对可缓存位置的读事务,CompData 或 DataSepResp 响应保证该事务对于稍后来自任何代理到同一位置的事务是可观察的。
• 对于对可缓存位置的读事务,RespSepData 响应保证不会有较早的事务向此请求者发送监听,并且所有较晚的事务只有在主节点收到此事务的 CompAck 响应后才需要发送监听。
• 对于无数据事务,Comp 响应保证该事务对于稍后来自任何代理到同一内存位置的事务是可观察的。
• 此外,对于 CleanSharedPersist 事务,Comp 响应保证任何较早写入同一内存位置的数据已持久化。
• 对于 CleanSharedPersistSep 事务,Persist 响应保证任何较早写入同一内存位置的数据已持久化。
• 对于对不可缓存或 Device nRnE 或 Device nRE 的写或原子事务,Comp 或 CompData 响应保证该事务对于稍后来自任何代理到同一端点地址范围的事务是可观察的。
• 对于对可缓存或 Device RE 位置的写或原子事务,Comp 或 CompData 响应保证该事务对于稍后来自任何代理到同一位置的事务是可观察的。
注意
• 端点地址范围的大小由具体实现定义。通常,这是:
--- 对于用于外设的区域,是外设的大小。
--- 对于用于内存的区域,是缓存行的大小。
• 可缓存位置可以通过请求中 MemAttr[2] 可缓存位的断言来确定。不可缓存或设备位置可以通过请求中 MemAttr[2] 可缓存位的取消断言来确定。
如果对于到不可缓存或设备位置的写事务(EWA 被断言),Comp 响应不能保证该事务对于稍后来自任何代理到同一端点地址范围的事务是可观察的,那么可以使用以下技术之一来确保到同一端点地址范围的排序:
• 如果写事务具有端点顺序要求,则稍后来自同一代理的也具有端点顺序要求并且指向同一端点地址范围的事务将被排序。参见第 2-102 页的事务排序。
• 稍后对同一位置的读事务的 CompData 响应确保了该写事务相对于稍后来自任何代理到同一端点地址范围内任何位置的事务的排序。
组件必须仅在保证所有观察者都将看到原子操作的结果时,才给出 Comp 或 CompDBIDResp 响应。
2.8.3 完成确认
由请求者发出的事务与由不同请求者的事务引起的监听事务的相对顺序,通过使用完成确认响应来控制。这确保了在事务响应之后排序的监听事务被保证在事务响应之后被接收。
读事务的完成和 CompAck 发送的排序如下:
-
RN-F 在收到 Comp、RespSepData 或 CompData,或同时收到 RespSepData 和 DataSepResp 后发送 CompAck。
-
HN-F(ReadOnce* 情况除外)在向同一地址发送后续监听之前等待 CompAck。对于回写事务,WriteData 充当隐式 CompAck,HN-F 必须在向同一地址发送监听之前等待 WriteData。
此序列保证 RN-F 接收到事务的完成和到同一缓存行的监听,其顺序与从 HN-F 发送的顺序相同。这确保了对同一缓存行的事务以正确的顺序被观察到。
当 RN-F 有一个正在进行的、使用 CompAck 的事务(ReadNoSnp 和 ReadOnce* 除外)时,保证它在收到 Comp 和发送 CompAck 之间不会收到对同一地址的监听请求。
对于需要 CompAck 消息的 WriteNoSnp 和 WriteUnique 事务,RN 在收到 Comp、DBIDResp 或 CompDBIDResp 响应后发送 CompAck。
事务是否使用 CompAck 由请求者在原始请求中设置 ExpCompAck 字段决定。RN 设置 ExpCompAck 字段和生成 CompAck 响应的规则如下:
• RN-F 必须在所有读事务中包含 CompAck 响应,但 ReadNoSnp 和 ReadOnce* 除外。
• 虽然不要求,但允许 RN-F 在 ReadNoSnp 和 ReadOnce* 事务中包含 CompAck 响应。
• RN-F 不得在 StashOnce、CMO、原子或 Evict 事务中包含 CompAck 响应。
• RN-I 或 RN-D 允许(但不要求)在读事务中包含 CompAck 响应。
• RN-I 或 RN-D 不得在无数据或原子事务中包含 CompAck 响应。
• 想要使用 DMT 的 RN 必须在有序的 ReadNoSnp 和 ReadOnce* 事务中包含 CompAck 响应。
• 对于写事务,仅当 WriteUnique 和 WriteNoSnp 事务需要有序写观察保证时,才可以使用 CompAck。参见第 2-106 页的流式有序写事务。
对于 RN 和 HN 之间的事务,其中 HN 是完成者,HN 必须支持对所有需要或允许使用 CompAck 的事务使用 CompAck。
SN 不需要支持 CompAck 的使用。
与 SN-F 或 SN-I 通信的请求者(例如 HN-F 或 HN-I)不得发送 CompAck 响应。
表 2-8 显示了需要 CompAck 响应的请求类型,以及需要提供该响应的相应请求者类型。
表 2-8 请求者 CompAck 要求
| 请求类型 | CompAck 必需 |
|----------------------|------------|------------|
| | RN-F | RN-D, RN-I |
| ReadNoSnp | 可选 | 可选 |
| ReadOnce* | 可选 | 可选 |
| ReadClean | 是 | - |
| ReadNotSharedDirty | 是 | - |
| ReadShared | 是 | - |
| ReadUnique | 是 | - |
| CleanUnique | 是 | - |
| MakeUnique | 是 | - |
| CleanShared | 否 | 否 |
| CleanSharedPersist* | 否 | 否 |
| CleanInvalid | 否 | 否 |
| MakeInvalid | 否 | 否 |
| WriteBack | 否 | - |
| WriteClean | 否 | - |
| WriteUnique | 可选 | 可选 |
| Evict | 否 | - |
| WriteEvictFull | 否 | - |
| WriteNoSnp | 可选 | 可选 |
| Atomics | 否 | 否 |
| StashOnce | 否 | 否 |
2.8.4 RespSepData 和 DataSepResp 的排序语义
当请求者收到第一个 DataSepResp 时,它可以认为读事务已被全局观察到,因为没有可以修改接收到的读数据的操作。
主节点必须确保在发起可能导致 DataSepResp 响应发送给请求者的事务(例如 ReadNoSnpSep)之前,所有必需的监听事务都已完成。
当请求者收到来自主节点的 RespSepData 响应时,其所应用的请求已在主节点处排序,并且请求者将不会收到任何针对在其之前调度的事务的监听。主节点在向请求者发送 RespSepData 响应之前,必须确保没有针对该请求者到同一地址的未完成监听事务。接收 RespSepData 并不保证主节点已完成对系统中其他代理的监听。
当请求者发出 CompAck 确认时,该请求者表示它将承担为在其之后调度的任何事务冒险处理监听的职责。以下规则适用:
• 对于所有事务,除非下文立即描述的情况,必须在收到 RespSepData 响应后发送 CompAck 确认。允许(但不要求)在给出 CompAck 确认之前等待 DataSepResp 响应。
• 对于具有排序要求的 ReadOnce 和 ReadNoSnp 事务(即,Order 字段设置为 b10 或 b11 并且 ExpCompAck 字段被断言),要求仅在同时收到 DataSepResp 和 RespSepData 响应后才给出 CompAck 确认。
• 请求者必须等待同时收到 RespSepData 和 DataSepResp,然后才能向同一地址发出另一个请求。
注意
本规范要求仅在收到 DataSepResp 时不得给出 CompAck。
事务排序
除了使用 Comp 响应来排序来自请求者的请求序列之外,本规范还定义了在 RN、HN 对和 HN-I、SN-I 对之间对请求进行排序的机制。在 HN-F、SN-F 对之间,Order 字段用于获取请求被接受的确认。
请求者在 RN、HN 对和 HN-I、SN-I 对之间的顺序由请求中的 Order 字段支持。Order 字段指示事务需要以下形式的排序之一:
请求顺序 这保证了来自同一代理的多个事务到同一地址位置的顺序。
端点顺序 这保证了来自同一代理的多个事务到同一端点地址范围的顺序。此保证也包括请求顺序的保证。
有序写观察
请求被接受
这保证了系统中其他代理对来自单个代理的一系列写事务的观察顺序。
这保证完成者仅在接受请求时才发送肯定确认。
2.8.5

表 2-9 显示了 Order 字段的编码。
表 2-9 Order 字段编码 之间的一对
• 请求者需要 ReadReceipt 来确定何时可以发送下一个有序请求。
• 在完成者处,ReadReceipt 意味着请求已到达下一个排序点,该点将保持请求按接收顺序:
--- 对于需要请求顺序的请求,它将保持来自同一源的对同一地址的请求之间的顺序。
--- 对于需要端点顺序的请求,它将保持来自同一源的对同一端点地址范围的请求之间的顺序。
• 能够发送分离的非数据响应和纯数据响应的完成者可以发送 RespSepData 响应代替 ReadReceipt,并实现相同的功能行为。
当 WriteNoSnp 或不可监听的原子事务需要请求顺序或端点顺序时:
• 请求者需要 DBIDResp 来确定何时可以发送下一个有序请求。
• 完成者发送 DBIDResp 响应意味着数据缓冲区可用,并且写请求已到达一个将保持请求按接收顺序的 PoS:
--- 对于需要请求顺序的请求,它将保持来自同一源的对同一地址的请求之间的顺序。
--- 对于需要端点顺序的请求,它将保持来自同一源的对同一端点地址范围的请求之间的顺序。
当未断言 ExpCompAck 的 WriteUnique 事务或可监听的原子事务需要请求顺序时:
• 请求者需要 DBIDResp 来确定何时可以发送下一个有序请求。
• 完成者发送 DBIDResp 响应意味着它将保持来自同一源的对同一地址的请求之间的顺序。
Order 字段必须仅对以下事务设置为非零值:
• ReadNoSnp。
• ReadNoSnpSep。
• ReadOnce*。
• WriteNoSnp。
• WriteUnique。
• Atomic。
当 ReadNoSnp 或 ReadOnce* 事务需要请求顺序或端点顺序时:
当 WriteUnique 或 WriteNoSnp 事务需要有序写观察时:
• CompAck 是必需的。RN 必须断言 ExpCompAck。
• RN 需要 DBIDResp。
• 完成者是 PoS。PoS 发送 DBIDResp 意味着:
--- 数据缓冲区可用。
--- PoS 保证此写操作的一致性操作的完成不依赖于后续需要有序写观察的写操作的一致性操作的完成。
--- 在收到 CompAck 之前,写操作不会变得可见。
所有适用于提高流式效率的架构机制以及相应的约束在第 2-106 页的流式有序写事务中定义。
表 2-10 显示了对于需要排序的事务的不同组合,所获得的排序保证。
表 2-10 中显示为第一个事务和第二个事务的事务来自同一个请求者。
当来自同一个请求者的事务指定了不同的排序要求时,所提供的排序保证是两者中限制最少的那个。

| 第一个事务 | 第二个事务 | 排序保证 |
|---|---|---|
| 无排序 | 无排序 | 无排序 |
| 无排序 | 请求顺序 | 无排序 |
| 无排序 | 端点顺序 | 无排序 |
| 请求顺序 | 无排序 | 无排序 |
| 请求顺序 | 请求顺序 | 请求顺序 |
| 请求顺序 | 端点顺序 | 请求顺序 |
| 端点顺序 | 无排序 | 无排序 |
| 端点顺序 | 请求顺序 | 请求顺序 |
| 端点顺序 | 端点顺序 | 端点顺序 |
表 2-10 事务之间的顺序
当 ReadNoSnp 或 ReadNoSnpSep 的 Order 字段设置为 0b01 时,来自完成者的 ReadReceipt 响应保证完成者已接受该请求并且不会发送 RetryAck 响应。
读请求顺序示例
图 2-35 显示了三个读请求的请求排序。

图 2-35 一系列有序读请求
从 RN 发送到 HN 的三个有序请求如下:
-
RN 向 HN 发送 ReadNoSnp-1 请求。
-
HN 接受请求并向 RN 返回 ReadReceipt-1 响应。
-
收到 ReadReceipt-1 响应后,RN 向 HN 发送 ReadNoSnp-2 请求。
-
HN 不能立即接受 ReadNoSnp-2 请求,并向 RN 返回 RetryAck-2 响应。
-
RN 现在必须等待 HN 发送 PCrdGrant,然后才能重新发送 ReadNoSnp-2 请求。RN 此时不发送 ReadNoSnp-3,因为它希望在 ReadNoSnp-2 之后排序 ReadNoSnp-3。此排序要求 ReadNoSnp-2 必须在 ReadNoSnp-3 发送到 HN 之前被 HN 接受。
-
收到适当的 PCrdGrant 后,RN 重新发送 ReadNoSnp-2 请求。
-
HN 接受请求并向 RN 返回 ReadReceipt-2 响应。
-
收到 ReadReceipt-2 响应后,RN 向 HN 发送 ReadNoSnp-3 请求。
-
HN 接受请求并向 RN 返回 ReadReceipt-3 响应。
-
HN 通过向 RN 发送每个请求的组合完成和数据响应来完成请求事务。
注意
图 2-35 在第 2-105 页显示了一个来自 RN 的由三个读操作组成的有序流。但是,一个 RN 可以有多个读流,在这种情况下,请求必须在流内排序,但流之间不存在排序依赖关系。一个例子是当流来自 RN 内的不同线程时,在这种情况下,RN 仅等待来自同一线程的前一个请求的 ReadReceipt,然后再从该流发出下一个有序请求。
回写请求顺序
RN-F 必须在收到未完成的回写事务的 CompDBIDResp 响应后,才能向同一缓存行发出另一个请求。允许在收到对同一缓存行的未完成回写的 CompDBID 响应之前,发出 SnoopMe 被断言的原子事务。
流式有序写事务
适用于提高有序写观察(OWO)写流式效率的架构机制以及相应的约束仅适用于 WriteUnique 和 WriteNoSnp 事务。
如果请求者要求一系列写事务以与它们发出时相同的顺序被观察到,那么请求者可以在发出序列中的下一个写之前等待一个写操作的完成。这种观察排序通常被称为有序写观察。本规范提供了一种称为流式有序写的机制,以更有效地流式传输此类有序写事务。
流式有序写机制依赖于使用有序写观察排序要求和 CompAck。利用流式有序写解决方案时,请求者和 HN-F 的职责为:
• 请求者必须在写请求上设置 Order 字段以要求有序写观察,并设置 ExpCompAck。
• 写请求中的有序写观察要求向 HN-F 指示,此写操作的一致性操作的完成不得依赖于后续写操作的一致性操作的完成。
• 请求者必须等待写事务的 DBIDResp、CompDBIDResp 或 Comp,然后再发送下一个写请求。
• 请求者在收到相应写操作的 DBIDResp、CompDBIDResp 或 Comp,以及所有较早相关有序写操作的 Comp 响应后,必须发送 CompAck 响应。如果要发送写数据,则允许请求者将 CompAck 与 WriteData 响应组合成 NCBWrDataCompAck 响应。当请求者将 CompAck 与 WriteData 响应组合时,它必须为所有 WriteData 传输发送组合响应。请求者确定一组有序写操作是否相关的方法是具体实现定义的。
注意
等待发送 CompAck,直到所有先前有序写操作都收到其 Comp 响应,这可确保它们已在各自的 HN-F 处完成操作,并且观察到发送了 CompAck 的写操作的任何请求者也将观察到所有先前有序的写操作。
• 收到 DBIDResp 并准备好发送 CompAck 的请求者不得为了发送 CompAck 而等待 Comp。
• HN-F 必须等待来自 RN 的 CompAck 响应,然后才能取消分配写事务并使该写操作对其他观察者可见。
注意
在 CHI issue D 之前:
• 只允许在收到相应写操作的 Comp 响应以及所有较早相关有序写操作的 Comp 响应后,才能发送写操作的 CompAck。
• WriteNoSnp 不允许有序写观察。
优化的流式有序写事务
本节中的写操作仅指 WriteUnique 或 WriteNoSnp。流式有序写机制可以进一步优化。如果先前发送的写操作是针对不同目标的,则请求者不需要在发送下一个有序写之前等待该请求的 DBIDResp。但是,如果互联可以重新映射 TgtID,则请求者必须假定所有写事务都针对同一个 HN-F,并且不得使用优化版本的流式有序写流。
使用优化或非优化流式有序写解决方案的实现必须避免死锁和活锁情况。
注意
• 避免资源相关的死锁或活锁问题的一种技术是将流式有序写优化限制为系统中的单个请求者。系统中的所有其他请求者可以使用不带优化的流式有序写解决方案。
• 在典型系统中,优化的流式有序写解决方案对作为 PCIe 风格、非宽松顺序、可监听从属设备写操作的管道的 RN-I 最有利。在大多数系统中,一个承载此类 PCIe 流量的 RN-I 就足够了。
• 通过使用 WriteDataCancel 消息来避免资源相关的死锁和活锁,多个请求者可以使用优化的流式有序写。
图 2-36 显示了一个典型的 RN-I 使用流式有序 WriteUnique 事务的事务流。此流程防止读操作在 Write-A 完成之前获取 Write-B 的新值。
注意
为清晰起见,图 2-36 中省略了 Write-B DBIDResp 和 NCBWrData 流。

图 2-36 流式有序 WriteUnique 事务流程
2.9 地址、控制和数据
事务包含定义事务由互联处理方式的属性。这些包括地址、内存属性、监听属性和数据格式。每个属性都在本节中定义。
2.9.1 地址
本规范支持:
• 44 到 52 位的物理地址(PA),以 1 位为增量。
• 49 到 53 位的虚拟地址(VA)。
REQ 和 SNP 数据包地址字段指定如下:
• REQ 通道:Addr[(MPA-1):0]
• SNP 通道:Addr[(MPA-1):3]
MPA 是支持的最大 PA。
表 2-11 显示了物理地址字段宽度与支持的虚拟地址之间的关系。
表 2-11 Addr 字段宽度及支持的 PA 和 VA 大小

| REQ Addr 字段宽度(位) | 支持的最大地址(位) |
|------------------|------------|----|
| | PA | VA |
| 44 | 44 | 49 |
| 45 | 45 | 51 |
| 46 到 52 | 46 到 52 | 53 |
对于不同 ADDR 字段宽度的 DVM 有效载荷在 REQ 和 SNP 字段中的映射,请参见第 8-269 页的 DVMOp 和 SnpDVMOp 数据包。
Req_Addr_Width 参数用于指定组件支持的最大物理地址(以位为单位)。此参数的有效值为 44 到 52,未指定时,参数采用默认值 44。
REQ 和 SNP 通道消息地址字段在 REQ 通道中是一个 44 位到 52 位的字段,标记为 Addr[(43-51):0];在 SNP 通道中是一个 41 位到 49 位的字段,标记为 Addr[(43-51):3]。该字段被不同的消息类型使用如下:
• 对于读、PrefetchTgt、无数据、写和原子事务,Addr 字段包括被访问内存位置的地址。
• 对于监听请求(SnpDVMOp 除外),该字段包括被监听位置的地址:
--- Addr[(43-51):6] 是缓存行地址,足以唯一标识监听要访问的缓存行。
--- Addr[5:4] 标识事务正在访问的关键块。参见第 2-123 页的关键块标识符。本规范建议被监听的缓存以回绕顺序返回数据,并首先返回关键块。
注意
提供了 Addr[3],但未使用。
• 对于 DVMOp 和 SnpDVMOp 请求,Addr 字段用于携带与 DVM 操作相关的信息。参见第 8 章 DVM 操作。
• Addr 字段值不用于 PcrdReturn 事务,必须设置为零。
2.9.2 非安全位
定义了安全和非安全事务以支持安全和非安全操作状态。
定义该位是为了当其被断言时,事务被标识为非安全事务。
对于可监听事务,此字段可被视为一个附加地址位,定义了安全地址空间和非安全地址空间这两个地址空间。必须正确处理安全和非安全地址空间之间的任何别名。
注意
硬件一致性不管理非安全和安全地址空间之间的一致性。
NS 断言要求为:
• 可以在任何读、无数据、写和原子事务中断言。
• 可以在 PrefetchTgt 事务中断言。
• 不适用于 DVMOp 或 PCrdReturn 事务,并且必须设置为零。
2.9.3 内存属性
内存属性(MemAttr)包括早期写确认(EWA)、设备、可缓存和分配。
EWA
EWA 指示事务的写完成响应:
• 是否允许来自互联中的中间点,例如主节点。
• 是否必须来自事务的最终端点。
如果 EWA 被断言,事务的写完成响应可以来自中间点或端点。来自中间点的完成必须提供如第 2-99 页的完成响应和排序中描述的 Comp 所需的相同保证。
如果 EWA 被取消断言,事务的写完成响应必须来自端点。
注意
允许实现不使用 EWA 属性,在这种情况下,必须从端点给出完成。
EWA 断言要求为:
• 可以在 ReadNoSnp 和 ReadNoSnpSep 事务中取任何值。
• 可以在 WriteNoSnp 事务中取任何值。
• 可以在 CMO 事务中取任何值。
• 可以在原子事务中取任何值。
• 必须在任何不是 ReadNoSnp、ReadNoSnpSep 或 CMO 事务的读或无数据事务中断言。
• 必须在任何不是 WriteNoSnp 事务的写事务中断言。
• 不适用于 DVMOp 或 PCrdReturn 事务,并且必须设置为零。
• 不适用于 PrefetchTgt 事务,可以取任何值。
设备
设备属性指示内存类型是设备类型还是普通类型。
设备内存类型
设备内存类型必须用于表现出副作用的位置。对于没有表现出副作用的位置,允许使用设备内存类型。
对设备类型内存位置的事务的要求是:
• 读事务不得读取比请求更多的数据。
• 不允许从设备内存位置预取。
• 读操作必须从其端点获取数据。不得将从对同一地址位置的写操作(在中间点完成)转发的数据提供给读操作。
• 不允许将对不同位置的请求合并为一个请求,也不允许将对同一位置的不同请求合并为一个请求。
• 写操作不得合并。
• 对从中间点获得完成的设备内存的写操作,必须及时使写数据对端点可见。
对设备内存的访问必须使用以下类型,允许独占变体:
• 对设备内存位置的读访问必须使用 ReadNoSnp。
• 对设备内存位置的写访问必须使用 WriteNoSnpFull 或 WriteNoSnpPtl。
• CMO 事务允许访问设备内存位置。
• 原子事务允许访问设备内存位置。
• PrefetchTgt 事务不允许访问设备内存位置。该位值不适用,可以取任何值。
普通内存类型
普通内存类型适用于没有副作用的存储位置。
对普通内存的访问没有像设备类型内存那样的关于预取或转发的限制:
• 具有 EWA 断言的读事务可以从写事务中获取读数据,该写事务已从中间点发送其完成并且是针对同一地址位置的。
• 写操作可以合并。
任何读、无数据、写、PrefetchTgt 或原子事务类型都可用于访问普通内存位置。使用的事务类型取决于要完成的内存操作以及可监听属性。
可缓存
可缓存属性指示事务是否必须执行缓存查找:
• 当可缓存被断言时,事务必须执行缓存查找。
• 当可缓存被取消断言时,事务必须访问最终目的地。
可缓存属性值的要求是:
• 不得为任何设备内存事务断言。
• 必须为任何读事务断言,但 ReadNoSnp 和 ReadNoSnpSep 除外。
• 必须为任何无数据事务断言,但 CleanShared、CleanSharedPersist*、CleanInvalid、MakeInvalid 除外。
• 必须为任何写事务断言,但 WriteNoSnpFull 和 WriteNoSnpPtl 除外。
• 对于普通内存位置的 ReadNoSnp、ReadNoSnpSep、WriteNoSnpFull 和 WriteNoSnpPtl 可以取任何值。
• 对于 CleanShared、CleanSharedPersist* 、CleanInvalid 和 MakeInvalid 可以取任何值。
• 对于原子事务可以取任何值。
• 不适用于 DVMOp 和 PCrdReturn 事务,并且必须设置为零。
• 不适用于 PrefetchTgt 事务,可以取任何值。
注意
在可以取任何可缓存值的事务中,该值通常由页表属性确定。
分配
分配属性是一个分配提示。它指示事务的建议分配策略:
• 如果分配被断言,出于性能原因,建议将事务分配到缓存中。但是,允许不分配该事务。
• 如果分配被取消断言,出于性能原因,建议不要将事务分配到缓存中。但是,允许分配该事务。
分配属性值的要求是:
• 可以为具有可缓存属性断言的事务断言。
• 必须为 WriteEvictFull 事务断言。
注意
请求者可以将分配位未断言的 WriteEvictFull 转换为 Evict 事务。
• 不得为设备内存事务断言。
• 不得为普通非可缓存内存事务断言。
• 不适用于 DVMOp、PCrdReturn 和 Evict 事务,并且必须设置为零。
• 不适用于 PrefetchTgt 事务,可以取任何值。
Attr 的传播
必须保留从 HN 到 SN 的请求中的 MemAttr 位 EWA、设备、可缓存和分配,该请求是响应发送到 HN 的请求而发送的。此规则的唯一例外是当已知下游内存为普通内存时,Device 字段值可以设置为 0b0 以指示普通内存。
从 HN 到 SN 的请求中的 SnpAttr 属性位值必须始终设置为 0b0。
对于由于来自主节点的预取或来自系统缓存的逐出而在互联内生成的 ReadNoSnp 或 WriteNoSnp:
• MemAttr 位 EWA、可缓存和分配都必须设置为 0b1。
• Device 字段值必须设置为 0b0 以指示普通内存。
• SnpAttr 字段值必须设置为 0b0 以指示不可监听。
表 2-12 列出了 MemAttr、SnpAttr 和 Order 字段值的合法组合以及等效的 ARM 内存类型。Order 字段在第 2-99 页的排序中描述。
2.9.4 事务属性组合

| MemAttr[3:0] | SnpAttr | LikelyShared | Order[1:0] | ARM 内存类型 |
|----------------|---------|--------------|--------------|----------|---|---------|-------|--------------|
| [1] | [3] | [2] | [0] | | | [1] | [0] | |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Device nRnE |
| 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | Device nRE |
| 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | Device RE |
| 所有其他值 ^b | | | | | | | | 无效 |
| 0 | 1 | 1 | 0 | 0 | 0 | 0/1 ^a | 0 | 非可缓存 非缓冲 ^c |
| 0 | 1 | 1 | 0 | 1 | 1 | 0/1 ^a | 0 | 非可缓存 可缓冲 |
| 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 不可监听 回写 不分配 |
| 0 | 1 | 1 | 1 | 0 | 1 | 0/1 ^d | 0 | 不可监听 回写 分配 |
| 0 | 1 | 1 | 0 | 1 | 1 | 0/1 ^d | 0 | 可监听 回写 不分配 |
| 0 | 1 | 1 | 1 | 1 | 1 | 0/1 ^d | 0 | 可监听 回写 分配 |
| 所有其他值 ^b | | | | | | | | 无效 |
a. Order = 0b10 仅允许在 ReadOnce*、WriteUnique、ReadNoSnp、WriteNoSnp 和原子事务中使用。
b. Order = 0b01 不用于事务排序。参见第 2-103 页的 Order 字段编码。
c. 非可缓存 非缓冲 是 AXI 内存类型,不是 ARM 内存类型。
d. LikelyShared = 1 仅允许用于 ReadShared、ReadNotSharedDirty、ReadClean、WriteBackFull、WriteCleanFull、WriteEvictFull、WriteUnique 和 StashOnce 事务。
内存类型
本节规定了表 2-12 第 2-113 页中显示的每种内存类型所需的行为。
Device nRnE
Device nRnE 内存类型所需的行为是:
• 写响应必须从最终目的地获得。
• 读数据必须从最终目的地获得。
• 读操作不得获取超出所需的数据。
• 不得预取读操作。
• 写操作不得合并。
• 写操作不得写入比原始事务更大的地址范围。
• 来自同一源到同一端点的所有读和写事务必须保持有序。
Device nRE
Device nRE 内存类型所需的行为与 Device nRnE 内存类型相同,但以下情况除外:
• 写响应可以从中间点获得。
Device RE
Device RE 内存类型所需的行为与 Device nRE 内存类型相同,但以下情况除外:
• 来自同一源到同一端点的读和写事务不必保持有序。
• 来自同一源到重叠地址的读和写事务必须保持有序。
普通非可缓存非缓冲
普通非可缓存非缓冲内存类型所需的行为是:
• 写响应必须从最终目的地获得。
• 读数据必须从最终目的地获得。
• 写操作可以合并。
• 来自同一源到重叠地址的读和写事务必须保持有序。
普通非可缓存可缓冲
普通非可缓存可缓冲内存类型所需的行为是:
• 写响应可以从中间点获得。
• 写事务必须及时在最终目的地可见。
注意
没有机制可以确定写事务何时在其最终目的地可见。
• 读数据必须从以下之一获得:
--- 最终目的地。
--- 正在进行到其最终目的地的写事务。如果读数据是从写事务获得的:
--- 它必须从该写操作的最新版本获得。
--- 数据不得被缓存以服务于后续读操作。
• 写操作可以合并。
• 来自同一源到重叠地址的读和写事务必须保持有序。
注意
对于普通非可缓存可缓冲读操作,数据可以从仍在进行到其最终目的地的写事务中获得。这与读和写事务传播以同时到达最终目的地是无法区分的。以这种方式返回的读数据并不表示写事务在最终目的地可见。
回写不分配
回写不分配内存类型所需的行为是:
• 写响应可以从中间点获得。
• 不要求写事务在最终目的地可见。
• 读数据可以从中间的缓存副本获得。
• 可以预取读操作。
• 写操作可以合并。
• 读和写事务需要缓存查找。
• 来自同一源到重叠地址的读和写事务必须保持有序。
• 不分配属性是一个分配提示,即建议内存系统出于性能原因不分配该事务。但是,并不禁止分配该事务。
回写分配
回写分配内存类型所需的行为与回写不分配内存相同。但是,在这种情况下,分配提示是建议内存系统出于性能原因分配该事务。
2.9.5 可能共享
LikelyShared 属性是一个缓存分配提示。当被断言时,此属性指示请求的数据可能被系统中的其他请求节点共享。这对于共享系统级缓存来说是一个提示,即出于性能原因,建议分配该缓存行。
与此事务属性没有关联的必需行为。LikelyShared 断言要求为:
• 可以在以下中断言:
--- ReadClean。
--- ReadNotSharedDirty。
--- ReadShared。
--- StashOnceUnique。
--- StashOnceShared。
--- WriteUniquePtl。
--- WriteUniqueFull。
--- WriteUniquePtlStash。
--- WriteUniqueFullStash。
--- WriteBackFull。
--- WriteCleanFull。
--- WriteEvictFull。
• 不得在任何其他读或写事务中断言。
• 不得在任何无数据或原子事务中断言。
• 不适用于 DVMOp 或 PCrdReturn 事务,并且必须设置为零。
• 不适用于 PrefetchTgt 事务,可以取任何值。
2.9.6 监听属性
监听属性(SnpAttr)指示事务是否需要监听。表 2-13 显示了 SnpAttr 字段编码。
表 2-13 SnpAttr 字段编码
| SnpAttr | 监听属性 |
|---|---|
| 0 | 不可监听 |
| 1 | 可监听 |
表 2-14 显示了不同事务类型的监听属性。
表 2-14 不同事务类型的监听属性
| 事务 | 不可监听 | 可监听 |
|---|---|---|
| ReadNoSnp, ReadNoSnpSep | Y | - |
| ReadOnce*, ReadClean, ReadShared, ReadNotSharedDirty, ReadUnique | - | Y |
| CleanUnique, MakeUnique, StashOnce | - | Y |
| CleanShared, CleanSharedPersist*, CleanInvalid, MakeInvalid | Y | - |
| Evict | Y | - |
| WriteNoSnp | Y | - |
| WriteBack, WriteClean, WriteEvictFull | Y | - |
| WriteUnique | - | Y |
| 原子事务 | Y | Y |
| DVMOp | n/a ^a | n/a ^a |
| PrefetchTgt | n/a ^b | n/a ^b |
从主节点到从属设备的 CMO、ReadNoSnp 和 ReadNoSnpSep 中的 SnpAttr 字段值必须设置为零,无论从原始请求者到主节点的请求中该字段的值如何。
注意
对于可以取多个 SnpAttr 值的事务,该值通常由页表属性确定。
a. 不适用,必须设置为零。
b. 不适用,可以取任何值。
允许两个不同的代理在同一时间点使用不匹配的 MemAttr 或 SnpAttr 值访问同一位置。
使用不匹配的可监听性或可缓存性属性来自不同代理的内存访问被视为软件协议错误。软件协议错误可能导致一致性丢失并导致数据值损坏。要求系统在软件协议错误时不会死锁,并且事务始终向前推进。
对一个 4KB 内存区域的访问的软件协议错误不得导致对另一个不同的 4KB 内存区域的数据损坏。
对于保存在普通内存中的位置,使用适当的软件缓存维护可用于将内存位置返回到已定义状态。
使用不匹配的内存属性可能导致 RN-F 观察到对同一地址的监听事务,而它正在对该地址执行 ReadNoSnp 或 WriteNoSnp 事务。在这种情况下,监听事务与 RN-F 发出的事务之间没有定义的关系。
2.9.7 不匹配的内存属性
2.10 数据传输
读事务、写事务、原子事务和带数据的监听响应包括数据有效载荷。本节定义了数据对齐规则,以及针对地址、事务大小和内存类型的不同组合所访问的数据字节。
2.10.1 数据大小
数据包中的 Size 字段与其他字段结合使用,以确定传输的字节数。表 2-15 显示了 Size 字段值的编码。监听事务不包含 Size 字段。所有监听数据传输都是 64 字节。
表 2-15 Size 字段值编码
| Size[2:0] | 字节数 |
|---|---|
| 0b000 | 1 |
| 0b001 | 2 |
| 0b010 | 4 |
| 0b011 | 8 |
| 0b100 | 16 |
| 0b101 | 32 |
| 0b110 | 64 |
| 0b111 | 保留 |
2.10.2 内存中的字节访问
MemAttr[1] 位字段确定内存类型是设备类型还是普通类型。参见第 2-110 页的内存属性。访问的字节由内存类型决定,如下所示:
普通内存
具有普通内存类型的事务访问由 Size 字段定义的字节数。数据访问从 Aligned_Address 开始,即事务地址向下舍入到最接近的 Size 边界,并在下一个 Size 边界之前的字节结束。
计算如下:
Start_Address = Addr 字段值。
Number_Bytes = 2^Size 字段值。
INT(x) = x 向下取整的整数值。
Aligned_Address = (INT(Start_Address / Number_Bytes)) x Number_Bytes。
访问的字节从 (Aligned_Address) 到 (Aligned_Address + Number_Bytes) - 1。
设备
具有设备内存类型的事务访问从事务地址开始到下一个 Size 边界之前的字节数。
访问的字节从 (Start_Address) 到 (Aligned_Address + Number_Bytes) - 1。
对于对设备位置的写事务,必须仅为访问的字节断言字节使能。参见第 2-119 页的字节使能。
2.10.3 字节使能
字节使能,也称为 BE,与写事务和带数据的监听响应一起使用。
对于写事务,断言的字节使能表示关联的数据字节有效,并且必须在内存或缓存中更新。取消断言的字节使能表示关联的数据字节无效,并且不得在内存或缓存中更新。
在写数据和监听响应数据中,字节使能值为零必须将关联的数据字节值设置为零。
如果在发送请求和发送数据之间发生监听,并且来自回写的脏数据副本被传递给相应的监听响应,则发送 CopyBackWrData_I 数据包作为回写请求的数据响应,向主节点指示回写被取消。请求者必须在 CopyBackWrData_I 数据包中取消所有 BE 值。请求者还必须在 WriteDataCancel 数据包中取消所有 BE 值,这些数据包是取消 WriteUniquePtl、WriteUniquePtlStash 或 WriteNoSnpPtl 事务的结果。
以下写事务必须在数据传输期间断言所有字节使能,除非写数据是 CopyBackWrData_I 数据包:
• WriteNoSnpFull。
• WriteBackFull。
• WriteCleanFull。
• WriteEvictFull。
• WriteUniqueFull。
• WriteUniqueFullStash。
以下写事务允许在数据传输期间断言任何字节使能组合。这包括全部断言和全部不断言:
• WriteBackPtl。
• WriteUniquePtl。
• WriteUniquePtlStash。
对于 WriteNoSnpPtl 事务,以下规则适用:
• 对于普通内存的事务,可以在数据传输期间断言任何字节使能组合。这包括全部断言和全部不断言。
• 对于设备内存的事务,字节使能必须仅为事务中指定地址处或高于该地址的字节断言。可以断言满足此要求的任何字节使能组合。这包括全部断言和全部不断言。
对于所有写事务,不在由 Addr 和 Size 指定的数据窗口内的字节使能必须被取消断言。
对于原子事务,不在由 Addr 和 Size 指定的数据窗口内的字节使能必须被取消断言,如下所示:
• 如果 Addr 与 Size 对齐,则数据窗口为 [Addr:(Addr+Size-1)]。
• 如果 Addr 不与 Size 对齐,则数据窗口为 [(Addr-Size/2):(Addr+Size/2-1)]。
• 对于原子事务,数据窗口内的所有字节使能必须被断言。
对于使用 SnpRespData 操作码的带数据的监听响应,必须断言所有字节使能。
对于使用 SnpRespDataPtl 操作码的带数据的监听响应,可以在数据传输期间断言任何字节使能组合。这包括全部断言和全部不断言。
2.10.4 数据打包
对于涉及数据的每个事务,数据字节可以在多个数据包中传输。
所需的数据包数量由以下因素决定:
• 字节数。
• 数据总线宽度。
每个数据包中传输的字节数由以下因素决定:
• 数据总线宽度。
本规范支持以下数据总线宽度:
• 128 位。
• 256 位。
• 512 位。
数据标识符和关键块标识符字段用于标识事务中的数据包。
最大为 16 字节的事务大小始终包含在一个数据包中。DataID 字段值必须设置为 Addr[5:4],因为 DataID 字段表示数据包中最低寻址字节的 Addr[5:4]。
表 2-16 显示了对于不同的数据总线宽度,DataID 字段与数据包中包含的字节之间的关系。
表 2-16 不同数据宽度的 DataID 和数据包内的字节
| DataID | 数据宽度 |
|--------|-----------------|-----------------|---------------|
| | 128 位 | 256 位 | 512 位 |
| 0b00 | Data[127:0] | Data[255:0] | Data[511:0] |
| 0b01 | Data[255:128] | 保留 | 保留 |
| 0b10 | Data[383:256] | Data[511:256] | 保留 |
| 0b11 | Data[511:384] | 保留 | 保留 |
在一个数据包内,所有字节都位于其自然字节位置。即使传输的数据字节少于数据总线的宽度,也是如此。
用于设备内存事务的数据包数量与事务地址无关。所需的数据包数量仅由 Size 字段和数据总线宽度决定。
注意
对于某些设备内存事务,可以从事务开始时的地址确定某些数据包不包含有效数据并且是多余的。但是,本规范要求传输这些数据包。
2.10.5 原子事务中的大小、地址和数据对齐
本节描述了原子事务的数据大小和对齐要求。它包含以下子部分:
• 大小。
• 地址和数据对齐。
• 第 2-122 页的字节序。
大小
数据包的大小字段指定原子事务的总数据大小。
对于 AtomicCompare 事务,数据大小是比较和交换数据值的总和。
表 2-17 显示了允许的数据大小,以及每种原子事务类型的出站和入站有效数据大小之间的关系。响应 AtomicCompare 事务返回的数据值大小是相关请求数据包中 Size 字段指定的字节数的一半。
表 2-17 原子事务出站和入站数据大小
| 原子事务 | 出站 | 入站 |
|---|---|---|
| AtomicStore | 1、2、4 或 8 字节 | - |
| AtomicLoad | 1、2、4 或 8 字节 | 与出站相同 |
| AtomicSwap | 1、2、4 或 8 字节 | 与出站相同 |
| AtomicCompare | 2、4、8、16 或 32 字节 | 出站大小的一半 |
地址和数据对齐
在 AtomicStore、AtomicLoad 和 AtomicSwap 事务中:
• 字节地址与出站数据大小对齐。
• 数据包中数据字节的位置与操作的字节序匹配,如请求的 Endian 字段所指定。
• 大端数据是字节不变的。
与 AtomicCompare 事务关联的写数据被提供为仿佛它是与出站数据大小对齐的事务。
在 AtomicCompare 事务中:
• 字节地址必须在数据包中与入站数据大小对齐,入站数据大小相当于出站数据大小的一半。
AtomicCompare 事务中的两个数据值按以下方式放置在数据字段中:
• 比较和交换数据值被连接起来,生成的数据有效载荷在数据包中与出站数据大小对齐。
• 比较数据始终位于寻址的字节位置。
• 交换数据始终位于有效数据的剩余一半中。
对于任何给定的比较数据地址,可以通过反转比较数据地址中的位 [n] 来确定交换数据地址,其中:
•
n = log2(以字节为单位的比较数据大小)
对齐示例
图 2-37 显示了不同地址和不同数据大小的数据放置示例。

图 2-37 AtomicCompare 事务的数据值打包
在图 2-37 显示的第一个示例中,寻址的字节位置是 0x2,数据总大小为 2 字节。在这种情况下,比较和交换数据必须放置在与包含寻址位置的 2 字节边界对齐的地址位置,即地址 0x2 到 0x3。比较数据放在位置 0x2,交换数据放在位置 0x3。
注意
交换数据的地址可以通过反转比较数据地址的位 [0] 来确定。位 [0] 被反转是因为比较数据和交换数据的大小都是 1 字节。
在图 2-37 显示的第三个示例中,寻址位置是 0x2,数据总大小为 4 字节。在这种情况下,比较和交换数据必须放置在与包含寻址位置的 4 字节边界对齐的地址位置,即地址 0x0 到 0x3。比较数据放在位置 0x2,交换数据放在位置 0x0。
注意
交换数据的地址可以通过反转比较数据地址的位 [1] 来确定。位 [1] 被反转是因为比较数据和交换数据的大小都是 2 字节。
字节序
执行原子操作的数据可以是小端或大端格式。对于算术运算,例如 ADD、MAX 和 MIN,执行操作的组件需要知道数据的格式。
数据的字节序格式由原子事务请求数据包中的 Endian 位定义。参见第 12-342 页的 Endian。
2.10.6 关键块标识符
CCID 字段用于标识事务请求中最关键的数据字节。
CCID 字段必须与原始请求的 Addr[5:4] 值匹配。包含多个数据包的事务必须对所有数据包使用相同的 CCID 值。
当读数据或写数据被互联重新排序时,CCID 字段允许通过比较 CCID 值与 DataID 值来快速识别事务中的最关键字节。当两个值匹配时,正在传输的数据字节是关键字节。
要匹配的位取决于数据总线宽度:
• 对于 128 位的数据总线宽度,CCID 和 DataID 位必须匹配以识别关键块。
• 对于 256 位的数据总线宽度,只有最高有效的 CCID 和 DataID 位必须匹配以识别关键块。
2.10.7 关键块优先回绕顺序
数据的发送者允许(但不要求)以关键块优先回绕顺序发送事务的单个数据包。
接口属性 CCF_Wrap_Order 定义了发送者的能力,以及接收者提供的保证:
• 发送者的 CCF_Wrap_Order:
True 发送者表明其能够以关键块优先回绕顺序发送数据包。
False 发送者表明其不能够以关键块优先回绕顺序发送数据包。
• ICN 的 CCF_Wrap_Order:
True ICN 保证将保持事务的数据包按接收到的顺序。
False ICN 表明不保证能保持事务的数据包按接收到的顺序。
• 非 ICN 的接收者的 CCF_Wrap_Order:
True 接收者要求数据包按关键块优先回绕顺序接收。
False 接收者不要求数据包按关键块优先回绕顺序接收。
如果系统中的某些组件不支持以关键块优先回绕顺序发送数据包,则数据接收者不得依赖数据按关键块优先回绕顺序接收。
注意
在设计时,CCF_Wrap_Order 参数可以帮助组件识别是否需要以关键块优先回绕顺序发送数据包。例如,如果组件知道它连接到一个乱序互联,那么它可能能够通过不按关键块优先回绕顺序返回数据包来简化其数据包路径。
如果互联的 CCF_Wrap_Order 属性设置为 True,那么连接到该互联的组件(如果能够的话)可以按关键块优先回绕顺序发送数据包,并且接收者可以利用由于首先接收到关键块而可能实现的延迟优化。
2.10.8 数据节拍排序
本规范允许在跨越互联时重新排序事务内的数据包。但是,允许(但不要求)数据包的原始来源以关键块优先、回绕顺序提供数据包。参见第 2-123 页的关键块优先回绕顺序。
注意
关键块优先回绕顺序确保当使用有序互联时,与不支持数据重排序的协议(如 AXI)的接口能够以最高效的方式进行。
回绕顺序定义如下:
Start_Address = Addr
Number_Bytes = 2^Size
INT(x) = x 向下取整的整数值
Aligned_Address = (INT(Start_Address / Number_Bytes)) x Number_Bytes
Lower_Wrap_Boundary = Aligned_Address
Upper_Wrap_Boundary = Aligned_Address + Number_Bytes - 1
为保持回绕顺序,顺序必须为:
-
第一个数据包必须对应于由事务的 Start_Address 指定的数据字节。
-
后续数据包必须对应于递增的字节地址,直到 Upper_Wrap_Boundary。
-
后续数据包必须对应于 Lower_Wrap_Boundary。
-
后续数据包必须对应于递增的字节地址,直到 Start_Address。
注意
如果所需字节已包含在先前的步骤中,则保持回绕顺序的一些步骤可能重叠且不是必需的。
2.10.9 数据传输示例
本节给出了本规范中定义的数据传输要求的一些示例。
在大多数示例中,事务的大小为 64 字节,数据总线宽度为 128 位。每个事务需要 4 个数据包。
在以下示例中,随附的文本突出了一些有趣的方面。其目的不是描述示例的所有方面。

示例 2-1 从对齐地址进行的普通内存 64 字节读事务
示例 2-2 从非对齐地址进行的普通内存 64 字节读事务

示例 2-3 从非对齐地址进行的普通内存 32 字节读事务

示例 2-4 从非对齐地址进行的普通内存 14 字节连续写事务

示例 2-5 从非对齐地址进行的设备读事务

示例 2-6 到非对齐地址的设备写事务

2.11 请求重试
本规范提供了一种请求重试机制,确保当请求到达完成者时,要么被接受,要么被给予 RetryAck 响应,以防止 REQ 通道阻塞。
请求重试不适用于 PrefetchTgt 事务。PrefetchTgt 事务不能重试,因为与此请求没有关联的响应。
要求请求者保留请求的所有详细信息,直到它收到指示请求已被接受或必须在稍后时间点再次发送的响应。为满足此要求,除 PrefetchTgt 外,AllowRetry 字段必须在事务首次发送时被断言。
接收请求的完成者能够对无法接受的请求给出 RetryAck 响应。通常,当其资源有限且没有足够的存储空间来保存当前请求直到某些较早的事务完成时,它将无法接受请求。
当完成者给出 RetryAck 响应时,它负责记录请求来自何处,由请求的 SrcID 确定。完成者还负责确定并记录处理该请求所需的协议信用类型。RetryAck 中的 PCrdType 字段编码了将由完成者授予的协议信用类型。当所需资源在稍后的时间点可用时,完成者必须使用 PCrdGrant 响应向请求者发送 P-Credit。PCrdGrant 响应向请求者指示可以重试该事务。
注意
没有显式的请求信用的机制。收到 RetryAck 响应的事务隐含地请求了一个信用。
有可能一个重新排序的互联可以对响应进行重新排序,使得请求者在收到事务的 RetryAck 响应之前就收到了 PCrdGrant。在这种情况下,请求者必须记录它收到的信用,包括信用类型,以便在确实收到 RetryAck 响应时适当地分配该信用。
注意
期望 PCrdGrant 相对于 RetryAck 响应被重新排序的情况很少见,因为 RetryAck 和 PCrdGrant 响应之间的延迟通常比互联重排序引起的任何延迟要长得多。
当请求者收到信用时,它可以重新发送请求,并指示已分配了信用。这是通过取消断言 AllowRetry 字段来完成的。这第二次尝试执行事务被保证会被接受。
重新发送的事务必须具有与原始请求相同的字段值,但以下字段除外:
• TgtID。参见第 3-136 页的请求消息的目标 ID 确定。
• QoS。
• TxnID。
• 从 HN 到 SN 的 ReadNoSnp 和 ReadNoSnpSep 的 ReturnTxnID。
• RSVDC。
• AllowRetry,必须被取消断言。
• PCrdType,必须设置为原始事务的重试响应中的值。
• TraceTag。
信用与特定事务之间没有固定关系。如果请求者收到了针对不同事务的多个 RetryAck 响应,然后收到一个信用,则没有固定的信用分配,请求者可以自由地从收到具有该特定协议信用类型的 RetryAck 响应的事务列表中选择最合适的事务。
重试机制支持最多十六种不同的信用类型。这让完成者可以对不同资源使用不同的信用类型。例如,完成者可能将一种信用类型用于与读事务相关的资源,将另一种信用类型用于写事务。使用不同的信用类型使完成者能够通过控制哪些重试的请求可以再次发送来有效地管理其资源。
仅当收到具有正确 PCrdType 的 PCrdGrant 时,请求者才必须重试该事务。
注意
如果完成者仅使用一种信用类型,本规范建议使用 PCrdType 值 0b0000。参见第 2-131 页的 PCrdType。
给出 RetryAck 响应的完成者必须能够记录它已给出的所有 RetryAck 响应,以确保它可以正确地分发信用。如果完成者使用多于一种信用类型,则必须记录已为每种信用类型给出的 RetryAck 响应。
请求者必须限制其发出的事务,以使完成者永远不需要跟踪超过 1024 个需要 PCrdGrant 响应的事务。这是通过将每个请求者的最大未完成事务数限制为 1024 来实现的。
注意
在 Issue D 之前,每个请求者的最大未完成事务数限制为 256。
事务从请求首次发出的周期开始到以下任一情况发生为止,被视为未完成:
• 事务完全完成,由返回该事务预期的所有以下响应确定:
--- ReadReceipt、CompData、RespSepData、DataSepResp、DBIDResp、Comp 和 CompDBIDResp。
• 它收到 RetryAck 和 PCrdGrant,并且:
--- 使用适当 PCrdType 的信用重试,然后由所有响应的返回确定完全完成。
--- 被取消,并使用 PCrdReturn 消息返回收到的信用。
请求者可以在以下任一情况下重用请求使用的 TxnID 值:
• 一旦它收到该请求的 RetryAck 响应。
• 一旦它收到该请求的所有必需响应(如果收到的响应是非 RetryAck 响应)。
每个事务请求都包含一个 QoS 值,完成者可以使用该值在资源可用时影响信用的分配。更多详细信息,请参见第 10 章 服务质量。
2.11.1 信用返回
请求者有可能获得比所需更多的信用。
本规范未定义何时会发生这种情况,但两种典型情况是:
• 事务在首次尝试和可以使用 P-Credit 重新发送的时间点之间被取消。
• 请求被多次请求,且 QoS 值不断增加。但是,只需要事务的单个完成。
注意
如果请求者在第一个请求被给予 RetryAck 响应之前发出第二个请求,那么两个事务都必须是可以接受的。但是,作为一个例子,对于对外设的访问,这种行为通常是不可接受的。
请求者通过使用 PCrdReturn 事务返回信用。这实际上是一个空操作(NOP)事务,它使用了不需要的信用。此事务用于通知完成者,对于给定的 PCrdType,不再需要已分配的资源。
任何不需要的信用必须及时返回。
注意
任何未使用的预分配信用必须被返回,以避免组件持有信用期望稍后使用它们。这种行为很可能导致资源使用效率低下,并使系统性能分析变得困难。
2.11.2 事务重试机制
以下部分描述了重试机制使用的请求事务字段。事务重试机制不适用于 PrefetchTgt 事务。
AllowRetry
AllowRetry 字段指示是否可以给请求事务一个 RetryAck 响应。有关 AllowRetry 值编码,请参见第 12-342 页的表 12-27。AllowRetry 字段必须在事务首次发送时被断言。
在以下情况下,AllowRetry 字段必须被取消断言:
• 事务正在使用预分配的 P-Credit。
• 事务是 PrefetchTgt。
PCrdType
PCrdType 字段指示与请求关联的信用类型,并确定如下:
• 对于请求事务:
--- 如果 AllowRetry 字段被断言,PCrdType 字段必须设置为 0b0000。
--- 如果 AllowRetry 字段被取消断言,PCrdType 字段必须设置为事务首次尝试时从完成者的 RetryAck 响应中返回的值。
• PCrdReturn 事务必须将其信用类型设置为正在返回的信用类型的值。有关 PCrdType 值编码,请参见第 12-345 页的 PCrdType。
• 对于具有单一信用类别或不实现信用类型分类的目的地,本规范建议将 PCrdType 字段设置为 0b0000。
注意
完成者分配给 PCrdType 的值由具体实现定义。
完成者必须实现一种防止饥饿的机制,以确保所有事务,无论 QoS 值或所需的信用类型如何,最终都将取得进展,即使是在很长的时间段内。这是通过确保最终为每个收到 RetryAck 响应的事务给予信用来实现的。有关为 QoS 目的而分配信用的更多详细信息,请参见第 10 章 服务质量。
2.11.3 事务重试流程
图 2-38 显示了一个典型的事务重试流程。

图 2-38 显示的步骤是:
-
请求者发送一个 ReadOnce 请求。
• 这是在无信用的情况下完成的,因此 AllowRetry 被断言。
图 2-38 事务重试流程 -
完成者接收请求并发送 RetryAck 响应,因为它此时无法处理该事务。
• 请求被记录,并在完成者处确定 PCrdType。
-
当完成者为该事务分配了资源时,它使用 PCrdGrant 响应发送一个 P-信用。
• PCrdGrant 包括为原始请求分配的 PCrdType。
-
请求者重新发送事务,且 AllowRetry 被取消断言。
• 该请求使用 P-信用,并将 PCrdType 字段设置为为原始请求分配的值。
允许(但不期望)完成者在发送相关的 RetryAck 响应之前发送 PCrdGrant。
注意
请求者可能在 RetryAck 之前收到 PCrdGrant。
事务的第二次尝试必须仅在收到该事务的 RetryAck 响应和适当的 P-信用后才发送。