NVMe系统内存结构 - 命令格式

本文详细介绍了NVMe协议中SubmissionQueue与CompletionQueue的定义,包括队列操作、状态指示、队列大小、队列标识符和优先级。此外,还阐述了命令格式,如CommandDword0的结构,以及AdminCommandSet和NVMCommandSet的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


本文属于《 NVMe协议基础系列教程》之一,欢迎查看其它文章。
本节介绍NVM Express使用的系统内存结构。

1 Submission Queue与Completion Queue定义

Head和Tail条目指针,对应于Completion Queue Head Doorbells和Submission Queue Tail Doorbells。doorbell寄存器由host软件更新。

  • Tail
    一个Queue条目的提交者,使用当前Tail条目指针,来标识下一个空闲Queue条目空间。
    提交者将新条目,提交到Tail指向的空闲Queue条目空间后,对Tail条目指针加1。
    如果Tail条目指针增量,超过Queue大小,则Tail条目指针将归零。
    只要Queue未满,提交者可以继续向Queue提交条目。
    注意: 提交者应考虑Queue封装条件。

  • Head
    Queue上条目的消费者,使用当前的Head条目指针,来标识下一个要从Queue中取出的条目。
    在从Queue中取出下一个条目后,消费者对Head条目指针加1。
    如果Head条目指针增量,超过Queue大小,则Head条目指针将归零。
    只要Queue不为空,消费者就可以继续从Queue中取出条目。
    注意: 消费者应考虑Queue封装条件。

Submission Queue和关联的Completion Queue的创建和删除,需要由主机软件正确排序。

  • 先创建Completion Queue,后创建Submission Queue
    主机软件应在,创建任何关联的Submission Queue之前,创建Completion Queue。Submission Queue可以在,关联的Completion Queue创建后的任何时间创建。
  • 先删除Submission Queue,后删除Completion Queue
    主机软件应在,删除Completion Queue之前,删除所有相关联的Submission Queue。主机软件应该,只在Submission Queue处于空闲状态,且没有未完成的命令时才删除它。

如果主机软件,将无效值写入Submission Queue Tail Doorbell或Completion Queue Head Doorbell寄存器,并且Asynchronous Event Request命令未完成,则异步事件将以状态码"Invalid Doorbell Write Value"投递到Admin Completion Queue;关联的Queue应该被主机软件删除并重新创建。对于遇到此错误的Submission Queue,控制器可能会完成先前获取的命令;但不会再获取额外的命令。这种情况可能是,由于主机软件试图将条目添加到满的Submission Queue,或从空的Completion Queue中删除条目引起的。

命令被覆盖时的行为是未定义的。

如果Completion Queue中,没有空闲的Completion Queue条目,则控制器不应将状态,投递到该Completion Queue,直到Completion Queue条目变得空闲为止。在这种情况下,控制器可以停止处理,与受影响的Completion Queue关联的其他Submission Queue条目,直到Completion Queue条目空闲可用为止,但控制器可以继续处理其他队列。

1.1 空队列

当Head条目指针等于Tail条目指针时(Head == Tail),队列为空。
在这里插入图片描述

1.2 满队列

当Head条目指针比Tail条目指针多1时(Head == Tail + 1),队列已满。满时队列中的条目数比队列Size少一个。
注意:在确定队列是否已满时,应考虑队列封装条件。
在这里插入图片描述

1.3 队列大小

Queue大小在一个16位的基于0的字段中表示,该字段表示队列中的条目数。

  • I/O Queue大小:2 ~ 64K
    包括l/O Submission Queue或I/O Completion Queue。Queue具体大小,受CAP.MQES字段中报告的,控制器支持的最大队列大小的限制。
  • Admin Queue大小:2 ~ 4K
    包括Admin Submission Queue或Admin Completion Queue。Queue具体大小,受AQA.ACQS和AQA.ASQS字段的限制。

由于Head和Tail条目指针定义,每个队列中的一个条目不可使用。

1.4 队列标识符

每个队列通过创建队列时,分配给队列的16位ID值来标识。

1.5 队列优先级

如果支持带有Urgent优先级仲裁机制的加权轮询,则host软件可以分配一个Urgent、High、Medium或Low的队列优先级服务分类。如果不支持带有紧急优先级仲裁机制的加权轮询,则不使用该优先级设置,并被控制器忽略。

2 Submission Queue - 命令格式

每条命令的大小为64字节

  • 命令Dword 0、Namespace Identifier、Metadata Pointer、PRP Entry 1和PRP Entry 2,对所有Admin命令和NVM命令有共同的定义。
  • SGL Entry 1和Metadata SGL Segment Pointer,对所有NVM命令有共同的定义(SGLs不用于Admin命令)。
  • Metadata Pointer、PRP Entry 1、PRP Entry 2和Metadata SGL Segment Pointer,不是所有命令都使用的。

2.1 Command Dword 0

命令Dword 0定义,如下表所示。

Command Dword 0
BitDescription
31:16Command Identifier (CID):当与Submission Queue identifier结合使用时,此字段指定命令的唯一标识符。
15PRP or SGL for Data Transfer (PSDT):此字段指定与命令相关的任何数据传输,是否使用PRPs或SGLs。
如果清除为’ 0 ‘,则该命令将使用PRPs,来传输任何相关的数据或元数据。
如果设置为’ 1 ',则该命令使用SGLs,来传输任何相关的数据或元数据。
所有Admin命令,应使用PRPs。
14:10保留
09:08Fused Operation (FUSE):在融合操作中,通过将两个简单命令“融合”在一起,来创建复杂命令。
此字段指定,此命令是否是融合操作的一部分,如果是,它是序列中的哪个命令。在这里插入图片描述
07:00Opcode (OPC):指定要执行的命令的操作码。

2.2 Command Format – Admin Command Set

Admin命令集(Admin Command Set)和NVM命令集(NVM Command Set)的64字节命令格式,定义如下表所示。
将来定义的任何其他I/O命令集(I/O Command Set),都可以使用另一种命令大小或格式。

Command Format – Admin Command Set
BytesDescription
63:60Command Dword 15 (CDW15):该字段是命令专用的Dword 15。
59:56Command Dword 14 (CDW14):该字段是命令专用的Dword 14。
55:52Command Dword 13 (CDW13):该字段是命令专用的Dword 13。
51:48Command Dword 12 (CDW12):该字段是命令专用的Dword 12。
47:44Command Dword 11 (CDW11):该字段是命令专用的Dword 11。
43:40Command Dword 10 (CDW10):该字段是命令专用的Dword 10。
39:32PRP Entry 2 (PRP2):该字段包含该命令的第二个PRP条目,或者如果数据传输跨越两个以上的内存页,则该字段是一个PRP列表指针。
31:24PRP Entry 1 (PRP1):该字段包含该命令的第一个PRP条目,或者一个PRP列表指针,具体取决于该命令。
23:16Metadata Pointer (MPTR):该字段包含元数据的连续物理缓冲区的地址。该字段仅用于元数据与逻辑块数据不交错的情况,如Format NVM命令中指定的。此字段应以Dword对齐。
15:08保留
07:04Namespace Identifier (NSID):这个字段指定了,这个命令应用到的命名空间ID。如果命令中没有使用命名空间ID,则该字段清空为0h。如果一个命令应用到设备上的所有命名空间,那么该字段应该设置为FFFFFFFFh。
除非另有说明,在使用命名空间ID的命令中,指定未激活的命名空间ID,将导致控制器在command中带有状态“Invalid Field”而中止命令。
在使用命名空间ID的命令中,指定无效的命名空间ID,将导致控制器以状态“Invalid Namespace”或“Format”中止命令。
03:00Command Dword 0 (CDW0):该字段对所有命令都是通用的,见上表Command Dword 0定义。

2.3 Command Format – NVM Command Set

Command Format – NVM Command Set
BytesDescription
63:60Command Dword 15 (CDW15):该字段是命令专用的Dword 15。
59:56Command Dword 14 (CDW14):该字段是命令专用的Dword 14。
55:52Command Dword 13 (CDW13):该字段是命令专用的Dword 13。
51:48Command Dword 12 (CDW12):该字段是命令专用的Dword 12。
47:44Command Dword 11 (CDW11):该字段是命令专用的Dword 11。
43:40Command Dword 10 (CDW10):该字段是命令专用的Dword 10。
39:24若将CDW0[15]清除为’0’,则该字段的定义为:
在这里插入图片描述
- PRP Entry 2 (PRP2):该字段包含该命令的第二个PRP条目,或者如果数据传输跨越两个以上的内存页,则该字段是一个PRP列表指针。
- PRP Entry 1 (PRP1):该字段包含该命令的第一个PRP条目,或者一个PRP列表指针,具体取决于该命令。

若将CDW0[15]设置为’1’,则该字段的定义为:
在这里插入图片描述
- SGL Entry 1 (SGL1):该字段包含该命令的第一个SGL段。如果SGL段是一个Data Block描述符,那么它描述了整个数据传输。如果需要多个SGL段来描述数据传输,那么第一个SGL段是一个Segment,或最后一个段描述符。
23:16若将CDW0[15]清除为’0’,则该字段的定义为:
在这里插入图片描述
- Metadata Pointer (MPTR):该字段包含元数据的连续物理缓冲区的地址。该字段仅用于元数据与逻辑块数据不交错的情况,如Format NVM命令中指定的。此字段应以Dword对齐。

若将CDW0[15]设置为’1’,则该字段的定义为:
在这里插入图片描述
- Metadata SGL Segment Pointer (MSGLP):该字段包含一个SGL段的地址,其中包含一个描述要传输的元数据的SGL描述符。该字段仅用于元数据与逻辑块数据不交错的情况,如Format NVM命令中指定的。该字段应Qword对齐。
15:08保留
07:04Namespace Identifier (NSID):这个字段指定了,这个命令应用的命名空间。如果该命名空间未用于该命令,则该字段将被清除为0h。如果命令应用于设备上的所有命名空间,则该值应设置为FFFFFFFFh。
03:00Command Dword 0 (CDW0):该字段对所有命令都是通用的,见上表Command Dword 0定义。

2.4 Command Format – Admin and NVM Vendor Specific Commands (可选)

除了为所有Admin和NVM命令,定义的通用字段外,Admin和NVM Vendor Specific命令可能支持Data Transfer字段中的Dwords数,和MPTR字段中的Dwords数。
如果支持,则Admin Vendor Specific Command和NVM Vendor Specific Command的命令格式,定义在下表中。

Command Format – Admin and NVM Vendor Specific Commands (可选)
BytesDescription
63:60Command Dword 15 (CDW15):该字段是命令专用的Dword 15。
59:56Command Dword 14 (CDW14):该字段是命令专用的Dword 14。
55:52Command Dword 13 (CDW13):该字段是命令专用的Dword 13。
51:48Command Dword 12 (CDW12):该字段是命令专用的Dword 12。
47:44Number of Dwords in MPTR (NDM):该字段表示,元数据传输中的Dwords数量。
43:40Number of Dwords in Data Transfer (NDT):这个字段表示,数据传输中的Dwords数量。
39:16不同类型命令,此部分含义有所不同,具体参考Admin命令与NVM命令具体定义。
15:08保留
07:04Namespace Identifier (NSID):该字段表示,该命令应用的命名空间ID。如果命令中,没有使用命名空间ID,则该字段清空为0h。如果一个命令,应用到设备上的所有命名空间,那么该字段,应该设置为FFFFFFFFh。
对于Vendor Specific Command,控制器对未激活的命名空间ID的响应行为是厂商指定的。在使用命名空间ID的命令中,指定无效的命名空间ID,将导致控制器以状态“Invalid Namespace”或“Format”中止命令。
03:00Command Dword 0 (CDW0):该字段对所有命令都是通用的。

3 小结

命令需要被提交到Submission Queue中,以便NVMe控制器执行,在执行结束后,会有对应的完成状态,放入到Completion Queue中。

NVMe命令长度均为64Byte,对应的completion消息长度均为16Byte。
因此,在Submission Queue中,每条命令都是64字节,无论是Admin命令,还是NVM命令(IO命令)。

NVMe命令,按如下方式,进行组织:
在这里插入图片描述

  • 如果是Admin或NVM命令(IO命令),则在Metadata Pointer与Data Pointer这两个部分(39:16),含义有所不同,其他均相同。

  • 如果是Vendor Specific Command,除了在Metadata Pointer与Data Pointer这两个部分(39:16)不同外,还有Dword 10和Dword11这两个部分(47:40),含义有所不同,其他均相同。

<think>好的,我现在需要处理用户关于PCIe VDM和NVMe-MI的技术问题。首先,我应该明确这两个技术的基本概念和作用。PCIe VDM(Vendor Defined Messages)是PCIe协议中允许厂商自定义的消息,用于特定功能的通信。而NVMe-MI(NVMe Management Interface)则是用于管理NVMe设备的接口,提供带外管理功能。用户可能是在实现或故障排除这两个技术时遇到了问题,需要指导。 接下来,我需要考虑这两个技术如何结合使用。例如,NVMe-MI可能通过PCIe VDM来传输管理命令,这样可以在不占用主机CPU资源的情况下进行设备管理。需要检查协议文档,确认它们之间的交互机制。 对于实现部分,可能需要指导用户如何配置PCIe设备以支持VDM,以及如何在固件或驱动程序中处理这些消息。同时,NVMe-MI的实现可能涉及命令格式、传输方式以及状态机的管理。需要确保用户了解相关的规范版本,比如NVMe-MI 1.1或1.2,以及PCIe的具体版本要求。 在故障排除方面,常见的可能问题包括消息传输失败、命令超时或解析错误。这时候需要建议用户使用工具如PCIe协议分析仪捕获数据包,检查VDM是否正确生成和传输。同时,查看设备的日志和状态寄存器,确认NVMe-MI命令是否被正确执行。还需要检查物理层连接是否稳定,比如信号完整性是否影响消息传输。 另外,用户可能需要了解如何验证实现是否符合规范。这涉及到测试用例的设计,比如发送标准的VDM并验证响应是否符合预期,或者模拟错误条件来测试设备的容错能力。引用相关的规范文档和行业最佳实践会增强回答的可信度。 最后,生成相关问题时,需要覆盖实现步骤、调试工具、常见错误及解决方法、规范差异等,帮助用户全面理解问题。例如,询问如何验证VDM的正确性,或者在不同PCIe版本中的兼容性问题。</think>### PCIe VDM与NVMe-MI技术解析 #### **1. PCIe VDM基础** PCIe VDM(Vendor Defined Messages)是PCIe协议中定义的厂商自定义消息类型,允许设备制造商通过TLP(事务层数据包)传输特定控制指令[^1]。其实现需遵循以下步骤: - **TLP包头配置**:设置Fmt/Type字段为`0110_1010b`(VDM标识) - **消息编码**:在数据载荷中定义厂商ID(16位)+ 消息内容(最大1024字节) - **路由机制**:采用基于ID的路由方式(BDF号定位目标设备) #### **2. NVMe-MI管理接口** NVMe-MI通过SMBus/I2C或PCIe VDM实现带外管理,核心功能包括: - 健康状态监控(温度、寿命预测) - 固件更新 - 命名空间管理 $$ \text{NVMe-MI命令结构} = \begin{cases} \text{Opcode(1B)} \\ \text{SubOpcode(1B)} \\ \text{参数(6B)} \\ \end{cases} $$ #### **3. VDM实现NVMe-MI** 通过PCIe VDM承载NVMe-MI命令的典型流程: ```c // 构造VDM数据包 struct vdm_packet { uint16_t vendor_id; // 0x144A(NVMe组织ID) uint8_t mi_opcode; // NVMe-MI操作码 uint8_t sub_opcode; uint32_t data[64]; // 最大256字节载荷 }; // 通过PCIe EP发送 pcie_send_vdm(dev->bdf, &vdm_packet, sizeof(vdm_packet)); ``` #### **4. 故障排查指南** | 现象 | 检测点 | 工具 | |-------|--------|------| | VDM未响应 | - LCRC校验<br>- 路由配置 | PCIe协议分析仪 | | 命令超时 | - 超时寄存器设置<br>- 中断配置 | `lspci -vvv` | | 数据错误 | - 内存对齐检查<br>- DMA配置 | Wireshark插件解析 | > **调试技巧**:通过读取`PCI_DEVICE_STATUS`寄存器的`VDM_Support`位(bit18)验证硬件支持性[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值