nvme1.3 学习笔记 3 controller register-3

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使用并忽视。

 

 

4.2 Submission Queue Entry-Command Format

每个命令都是64字节大小。

命令的DW0,Namespace Identify,Metadata Pointer,PRP Entry1,PRP Entry2,SGL Entry1和Metadata SGL Segment Pointer在所有的Admin命令和NVM命令中都有一个共同的定义,其中Metadata Pointer,PRP Entry1,PRP Entry2和Metadata SGL Segment Pointer不是所有命令都要使用的。DW0参见下图10。

图10 Command Dword 0

Bit

Description

31:16

Command Identifier(CID):这一部分和SQID组合起来的话能够代表Command的独一无二的ID

15:14

PRP or SGL for Data Transfer(PSDT): 这部分代表了是使用PRP还是SGL进行data传输。如果是基于NVMe over PCIe,则所有的Admin命令都应该使用PRP。如果是基于NVMe over Fabrics,则所有的Admin命令和IO命令都应该使用SGL。如果是基于NVMe over Fabrics 1.0版本,此位应该为01b。

Value

Definition

00b

使用PRP传输。

01b

使用SGLs传输,MPTR包含一个连续空间的物理地址。

10b

使用SGLs传输,MPTR包含一个SGL segment的地址。

11b

Reserved

如果Metadata和Logic Block Data不是交叉存储的,则MPTR被用来指向Metadata。Metadata指针的定义取决于本字段。

13:10

Reserved

09:08

Fuse Operation(FUSE):在混合操作中,一个混合的命令通过“融合”两个相似的命令被创建出来。参见4.10。本字段表明了本命令是否是一个混合命令,是在混合命令的那一部分(顺序)。

Value

Definition

00b

正常操作

01b

混合操作,这是第一个命令

10b

混合操作,这是第二个命令

11b

Reserved

 

07:00

Opcode(OPC):这一字段代表了被运行命令的opcode。

这个64字节的Admin和NVM命令格式被定义在图11中,将来定义的任何I/O 命令可能使用附加的命令大小和格式。

基于NVMe over PCIe的Admin 命令不能够使用SGLs。

图11 Command Format-Admin and NVM Command Set

Byte

Description

03:00

Command Dword 0(CDW0):这一部分是所有命令通用的,定义在图10中

07:04

Namespace Identifier(NSID):这一部分代表了此命令应用在哪一个Namespace上。如果这个命令不使用Namespace,则这一部分应该被清0,此位值为FFFFFFFFh代表这是一个广播值(参见6.1),范围(例如:NVM subsystem,all attached namespace,all namespace)取决于这个命令。参见图41和42,哪些命令支持值FFFFFFFFh。

如果此字段被使用但是给出了一个inactive的ID值(6.1.4),除非另有说明,否则Controller应该Abort掉此命令并回复Invalid 的status。

除非另有说明,如果此字段给出了一个invalid的NSID,那么Controller应该Abort掉此命令并回复Invalid NS 或者Format。

除非另有说明,如果此条命令中使用了NSID(见图41,42),而且这条命令不支持FFFFFFFFh,但是Host填充了FFFFFFFFh,Controller应该Abort掉这条命令并回复Invalid Field。

除非另有说明,如果此条命令不使用NSID但是Host填充了00000001h到FFFFFFFh之间的值,则Controller应该Abort掉此命令并回复Invalid Field。

15:08

Reserved

23:16

Metadata Pointer(MPTR):当在Format NVM命令中指定的Metadata和Logic Block Data不是交错存储时,这一字段有效。在NVMe over Fabrics中此字段被保留。

如果CDW0.PSDT被设置为00b,则这一字段应该包含一个有关于Metadata的连续的物理地址,而且这个地址是Dword对齐的(Bit1:0 Cleared to 00b)。Controller不是必须的检查Bits1:0是不是被设置为0。Controller可能会报告一个Invalid Field的错误当Bit1:0没有被清0时。如果Controller没有报告这个错误,那么Controller应该忽略Bit1:0的数值,就当做是00b。

如果CDW0.PSDT被设置为01b,则这个字段应该包含一个Medata的连续物理buffer地址,这个地址可以任意字节对齐。

如果CDW0.PSDT被设置为10b,则这个字段应该包含一个含有SGL Descriptor的SGL segment地址,这个包含SGL segment的地址应该是Qword对齐的。SGL segment包含第一个metadata的SGL Descriptor。如果该SGL segment中包含的SGL Descriptor是一个SGL Data Block Descriptor,那么该SGLDescriptor是唯一的描述Metadata数据传输的SGL Descripor。参见4.4

39:24

Data Pointer(DPTR):这一字段规定了命令中数据的使用。

如果CDW0.PSDT被设置为00b,则有如下定义:

39:32

PRP Entry2(PRP2):这一部分:

a) 如果数据传输没有跨过一个内存页边界则此部分被保留。

b) 如果数据传输恰好快过了一个内存页边界,则此部分描述了第二个内存页的页基地址。例如:

1.命令数据传输长度等于一个内存页的大小,并且PRP1的PBAO字段的偏移量为非0值。

2.PRP1的PBAO字段偏移量为0,但是命令数据传输长度大于1个内存页大小小于等于2个内存页大小。

c) 如果数据传输超过了一个内存页大小,则是一个PRP List指针。例如:

1.此命令的数据传输长度大于等于2个内存页大小,但是PRP1的PBAO字段非0。

2.此命令的数据传输长度大于2个内存页大小,而且PRP1的PBAO字段为0。

31:24

PRP Entry1(PRP1):这一部分包含了这个命令的第一个PRP Entry,或者是一个PRP List指针。

如果CDW0.PSDT被设置为01b或者10b,则有如下定义:

39:24

SGL Entry1(SGL1):这一字段包含了命令中的第一个SGL segment。

 

43:40

Command Dword 10(CDW10):这一字段是命令中的Dword10。

47:44

Command Dword 11(CDW11):这一字段是命令中的Dword11。

51:48

Command Dword 12(CDW12):这一字段是命令中的Dword12。

55:52

Command Dword 13(CDW13):这一字段是命令中的Dword13。

59:56

Command Dword 14(CDW14):这一字段是命令中的Dword14。

63:60

Command Dword 15(CDW15):这一字段是命令中的Dword15。

除了通用的Admin和NVM命令之外,Admin和NVM 厂商自定义命令也可能支持Data传输和Metadata算出的Dword数量。如果支持的话,厂商自定义命令如图12.更多细节参见8.7

图12:Command Format-Admin and NVM Vendor Specific Commands(Optional)

Bytes

Descriptor

03:00

Command Dword0(CDW0):这一部分所有定义都在图10中

07:04

Namespace Identify(NSID):这一部分代表了命令应用在哪一个Namespace中。如果这个命令不应用于任何Namespace,则这一部分被清0。如果这个命令应用于Attached到这个Controller的所有Namespace,则设置这个值到FFFFFFFFh。

如果Namespace ID是一个Invalid Namespace ID,则Controller应该Abort掉该命令。

15:08

Reserved

39:16

参见图11

43:40

Number of Dwords in Data Transfer(NDT):这一部分代表了Data传输的Dwords数量。

47:44

Number of Dwords in Metadata Transfer(NDM):这一部分代表了Metadata传输的Dwords数量。

51:48

Command Dword12(CDW12):这一字段是命令中的Dword12。

55:52

Command Dword13(CDW13):这一字段是命令中的Dword13。

59:56

Command Dword14(CDW14):这一字段是命令中的Dword14。

63:60

Command Dword15(CDW15):这一字段是命令中的Dword15。

4.3 Physical Region Page Entry and List

一个physical region page(PRP) Entry就是物理内存页的一个指针。PRPs作为一个在Controller和内存之间数据传输的Scatter/Gather 机制。为了在Controller和Host之间进行一个有效的数据传输,PRP Entries有一个确定的大小。

物理内存页大小由Host通过CC.MPS来配置。图13展示了包含有页基地址Page Base Address和偏移Offset的PRP Entry的设计。Offset的大小取决于CC.MPS值。

图13:PRP Entry Layout

63                                 n+1

n                                    0

Page Base Address

Offset

PRP Entry的定义描述见下图14。

图14:PRP Entry-Page Base Address and Offset

Bit

Descriptor

63:00

Page Base Address and Offset(PBAO):这一部分代表了64位的物理内存页地址。地位(n:0)代表了在内存页的偏移。如果这个内存页大小是4KB,那么第11:00位都是偏移;如果内存页大小是8KB,则第12:00位都是偏移。如果命令中的这个Entry并不是第一个PRP Entry或者是一个PRP List指针,那么偏移应该设置为0h。偏移应该是按照Dword对齐的,也就是说第1:0位总是设置为0。

PRP List是在一页连续内存中的PRP Entries的列表。PRP List中描述了不能够在命令中指出的另外的PRP Entries。如果有多个PRP List内存页数据要传输,那么List中的最后一个PRP Enries应该被当做指向下一个PRP List Entry的指针使用。代表了下一个PRP List的数据段的起始。图15展示了PRP List的设计。

图15 PRP List Layout

63                                 n+1

n                                    0

Page Base Address k

0h

Page Base Address k+1

0h

Page Base Address k+m

0h

Page Base Address k+m+1

0h

根据命令定义,命令中的第一个PRP Entry可能包含有一个包含在内存页内的Offset为非0的地址。第一个PRP List Entry(指向包含另外的PRP Entries的内存页的第一个指针)通常包含在命令中PRP Entry2的位置,应当是一个Qword对齐的而且有可能在内存页中的Offset非0。

 

包含在PRP List中的PRP Entries在内存页中的offset应该为0。

如果在命令中包含第二个PRP Entry,则这个Entry在内存中的Offset也为0。在这两种情况中。Entries都是以CC.MPS对齐的。如果控制器接收到了这两种Entries是一个非0的Offset,则应该返回一个PRP Offset Invalid的Error。

PRP List应该有一个Entries从entry0开始的最小的大小。如果请求了多个PRP List Page,那么PRP List中的最后一个Entries应该指向喜爱个PRP List Page的Page基础地址。下一个PRP List Page应该是基于内存页对齐的。请求的PRP Entries总个数应该通过命令中的参数和内存页大小决定。

4.4 Scatter Gather List

4.5 Metadata Region(MR)

Namespace中支持的Metadata可以是Logical Block中的一部分,也可以作为和data分离的另一个buffer进行传输。Metadata不能够被分离。对于写操作,Metadata和他所关联的Logical block是一个原子写。参见8.2。

Namespace被格式化为Metadata和Data分别存储的情况下,Metadata Region会被使用。Medata Region所在的Metadata指针被包含在Command中。Metadata指针应该是Dword对齐的。

Controller可能会支持几种Logical Block的物理格式和几种相关联的Metadata大小。在不同的格式下可能会有不同的性能。在Namespace数据结构中说明了使用哪种格式。

如果Namsepace被格式化成使用End-to-End 数据保护,则Metadata的前八个字节或者后八个字节被用来当做End-to-End数据保护信息。

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值