附录参考 - 🧩 比较命令 CMD0 的参数详细说明(继续) (第452页)
NVME2.0协议解读 1 min read

附录参考 - 🧩 比较命令 CMD0 的参数详细说明(继续) (第452页)

Blog Author

我们继续深入分析 NVMe Base Spec 2.0b 第 B.3 节的 Fused Operation 示例,这段内容重点是构造完整的 Compare + Write 命令对 —— 两个连续命令形成原子操作。我们从上一节命令结构接着讲下去。


🧩 比较命令 CMD0 的参数详细说明(继续)

在第一个命令 CMD0 中,即 Compare 命令,需要设置如下字段:

字段名 设置值 说明
MPTR 可选 如果元数据(Metadata)单独存在,用于指向元数据缓冲区地址
PRP1 地址 第一个数据页(4 KiB)的物理地址
PRP2 地址或 PRP List 如果有多个数据页(如本例是 16 KiB,需要 4 个页),设置为 PRP List 地址
SGL1 可选 如果使用的是 SGL 模式,设置为 SGL Segment 描述符
CDW10–11.SLBA 起始 LBA 比较的逻辑块起点
CDW12.LR 0 关闭 Limited Retry,允许控制器使用所有错误恢复手段
CDW12.FUA 0 允许从缓存中读取
CDW12.PRINFO 0 未启用端到端保护
CDW12.NLB 3h 表示比较 4 个 LBA(NLB 是 0-based)
CDW14CDW15 0 未启用保护信息时清零

🖼️ 图解:PRP List 映射数据页结构(Figure 480)

CMD0.PRP1 → 物理地址 Page i (LBA 0)
CMD0.PRP2 → PRP List:
    PRP List[0] → Page j(LBA 1)
    PRP List[1] → Page k(LBA 2)
    PRP List[2] → Page m(LBA 3)

✍️ CMD1:Write 命令字段说明(第二条命令)

字段名 设置值 说明
CDW0.OPC 01h Write 命令
CDW0.FUSE 10b Fused 操作中的第二条命令
CDW0.CID 新的命令 ID 必须与 CMD0 不同,例如 0xB1
NSID 与 CMD0 相同 同一个命名空间
PRP1/PRP2 物理地址 要写入的 16 KiB 数据地址列表
CDW10–11.SLBA 起始 LBA 与 CMD0 相同
CDW12.FUA 0 写缓存可用
CDW12.PRINFO 0 未启用保护
CDW12.NLB 3h 写入 4 个逻辑块
CDW13–CDW15 0 未使用保护信息

🔁 执行流程图

graph TD
    A[构建 CMD0 - Compare] --> B[设置 FUSE = 01b]
    B --> C[构建 CMD1 - Write]
    C --> D[设置 FUSE = 10b]
    D --> E[Doorbell 提交命令队列]
    E --> F[控制器原子处理 Compare + Write]
    F --> G{Compare 成功?}
    G --  --> H[执行 Write]
    G --  --> I[取消 Write]
    H & I --> J[填充 CQE  Completion Queue]

🧠 小结:构建 Fused Compare + Write 的关键点

  1. 命令必须连续地放在 Submission Queue 中;
  2. FUSE 字段必须正确设置
  3. CMD0 设置为 01b(First Command)
  4. CMD1 设置为 10b(Second Command)
  5. 两个命令都需要正确设置 CID、NSID、PRP 指针等字段;
  6. Doorbell 提交时 必须一次提交两个命令
  7. Compare 失败,Write 被自动取消 —— 不需要主机判断。

需要我接着为你画一张 PRP List 内存映射图、或者给出这一过程的代码伪实现(如 C/C++)来帮助你更直观理解吗?还是我们继续分析下一节内容?