3.2 Index/Data Pair Registers(Optional) Index/Data 组寄存器提供了Host使用基于I/O 空间的寄存器方位NVMe内存映射寄存器的机制。如果支持的话,这个寄存器应该在BAR2中定义。在基于PC的平台上,如果PCIE地址空间被映射且被映射到1MB以上,则Host在Real Mode(8086 mode)下的写操作不能够访问PCIE功能的地址空间的寄存器。 Index/Data 组机制允许Hos使用间接I/O寻址代替直接内存映射去访问NVME寄存器的内存映射。 4 Data Struct 本部分描述了NVME接口使用的数据结构。 4.1 Submission Queue & Completion Queue Definition 4.1 4.1.1 4.1.2仅适用于NVMe over PCIe。对于NVMe over Fabrics实现,参照NVMe over Fabrics版本规范的第2.4 2.4.1和2.4.2节。 队列内容的提交者使用当前的Tail入口指针来表示下一个公开的队列位置。提交者增加Tail入口指针的值来表示已经将内容放置到队列新的位置。如果Tail指针的增加超过了Queue的大小,Tail指针应该归0.只要不满足Queue满的条件,提交者就可以继续在Queue队列中放置新的数据(参见4.1.2)。 注意;提交者应该考虑Queue Wrap条件。 队列内容的消费者使用Head指针表示下一个要被消费的入口。消费者在取走Queue队列的一个数据后增加Head指针的值。如果Head指针的增加超过了Queue的大小,Head指针应该归0。只要Queue队列不空,消费者就可以一直在Queue中取。 注意:消费者应该考虑Queue Wrap条件。 创建删除Submission Queue和Completion Queue需要Host按照次序进行。Host应该在创建任何Submission Queue之前创建Completion Queue。Submission Queue可能在相关的Completion Queue创建之后的任何时刻创建。Host应该在删除Completion Queue之前删除Submission Queue。要Abort掉本Submission Queue的所有命令,Host 应该发送一个Delete I/O Submission Queue命令(参见7.4.3)。 Host应该写Submission Queue Tail Doorbell(参见3.1.16)和Completion Queue Head Doorbell (参见3.1.17)去告知Controller一个新的Queue入口。如果Host向Submission Queue Tail Doorbell或者Completion Queue Head Doorbell寄存器中写入了一个非法的值,而且当前Controller 有个一个未回复的Asynchronous Event Request命令,Controller应该触发一个Asynchronous Event去报告给Admin Completion Queue一个Invalid Doorbell Write Value。相关联的Queue需要被host删除或者重新创建。对于遇到此错误的Queue,Controller需要提前完成在此队列中取出来的命令,其他的命令可以不被完成。这种情况可能是由于Host试图向满的Submission Queue中增添一个新的Tail或者向空的Completion Queue中移除一个Head。 Host应该检测存放在内存中的Completion Queue Entry的Phase Tag(P)字段来决定是否有一个新的Completion Queue Entries被发送过来。Completion Queue的Tail指针只有Controller使用,对于Host他是不可见的。Controller使用Completion Queue Entries中的SQ Head Pointer(SQHD)字段向Host传输一个新的Submission Queue 的Head Pointer值。这个新的Head Pointer值代表了取到了哪一个Submission Queue Entries,但是并不代表已经运行或者完成了这个命令。参见4.6。 Host向Submission Queue Doorbell中写入一个新的值,这个新的值Submission Queue Tail代表了指针移动到或者越过放置Submission Queue Entries的地方。写到Submission Queue Tail Doorbell的值代表了有一个或者多个Submission Queue Entries命令需要被取走。 当返回的Completion Queue Entry中的Submission Queue Head Pointer被移动或者是越过了Submission Queue Entry放置的地方,说明一个Submission Queue Entry被Controller取走了。 一个Completion Queue Entry被发送到Completion Queue,当Controller写Completion Queue Entry到下一个空闲的Completion Queue的位置时,翻转Phase Tag(Tag)位较他之前在内存中的值。Controller可能会产生一个中断告知Host有一个或者多个Completion Queue Entries被发送过去了。 写入到Completion Queue Head Doorbell的新的值是Host用一个已经跳过了放置Completion Queue Entry的位置的值,代表一个Completion Queue Entry已经被Host取走。Completion Queue Head Doorbell写入可能代表Completion Queue中有一个或者更多的Entries被取走。 一旦一个SQ或者CQ Entry被取走,则放置Entry的这个位置就空闲出来了并且能够被再次使用。 如果CQ中没有了空的位置,Controller在CQ中有空余之前不应当再发送Status向CQ。在这种情况下,Controller可能会停止处理相关联的SQ Entries直到CQ中有了空闲位置。 4.1.1 Empty Queue 当Head Entry 指针和Tail Entry指针相等时表示Queue空了。 4.1.2 Full Queue 当Head Entyr指针等于Tail Entry指针加1时表示Queue满了。Queue中存放的Entries的数量比Queue的深度小1。 注意:队列反转情况应该在满时被考虑进去。 4.1.3 Queue Size Queue Size代表了Queue的大小,是一个16位的值,基础值是0。最小的大小是2个entry 。IO SQ和CQ最大值有64K个Entry,Controller可以通过CAP.MQES来限制最大的Queue Size。Admin SQ和CQ的最大值有4K个Entry。由于Head和Tail指针的定义,每个Queue中都有一个Entry是不能用的。 4.1.4 Queue Identify 每个队列在创建时都会分配一个QID。 4.1.5 Queue Priority 如果支持Weighted Round Robin的仲裁机制,则Host可能会为Queue分配Urgent,High,Medium或者Low优先级。如果不支持WRR的仲裁机制的话,Queue Priority的优先级设置应该不被Controller使用并忽视。 |