NVMe协议详解(一)

参考文档:NVME手册1.4a,下载网站。

NVMe相关定义

queue pair

一对用来承载NVMe命令的队列对,由一个Submission Queue和一个Completion queue组成,QP有两种类型,分别为Admin queue(承载admin命令)和I/O queue(承载I/O命令),host通过SQ提交命令给NVMe Controller,NVMe Controller提交完成状态到CQ。注意,一般来说,SQ和CQ都是在host的DDR内存中,所谓的host下发SQ命令,其实就是将命令填充到SQ队列中,然后通知NVMe Controller来DDR中取命令(少部分企业SSD盘支持CMB机制可以将SQ放在SSD的BAR空间中)。

admin queue

admin queue是用来向控制器提交admin命令的队列空间,包含submission queue(SQ)和completion queue(CQ),其只能提交admin命令,包含获取ssd能力、ssd属性、创建I/O queue等,具体支持的命令如下图所示(NVMe 1.4a)。admin queue的创建是通过三个寄存器确立的,分别为Admin Queue Attributes(AQA)、Admin Submission Queue Base Address(ASQ)、Admin Completion Queue Base Address(ACQ),当Host配置好这三个寄存器后使能NVMe盘即创建了admin queue。注意,一个controller只有一个admin queue,一个SSD可能有多个controller,比如SRIOV。

NVMe协议详解(一)_第1张图片

I/O queue

I/O queue是用来向控制器提交I/O命令的队列空间,包含submission queue(SQ)和completion queue(CQ),其只能提交I/O命令,包含读写数据、刷新数据、使数据无效话等,具体支持的命令如下图所示(NVMe 1.4a)。I/O queue是通过admin命令来创建的,意味着必须先建立admin queue并使能NVMe盘才能创建I/O queue。I/O queue创建的个数取决于host CPU个数及SSD能力,取它两最小值。

NVMe协议详解(一)_第2张图片

host

一个实体,它通过一个或多个控制器域NVM子系统连接,向SQ队列提交命令,并从CQ中检索完成状态。一般来说,host就是我们插NVMe盘的主机,它们通过pcie连接。

cache

NVMe ssd中用来暂存数据的缓存,它可能是SDRAM、DDR、甚至是falsh介质(比如TLC sdd的部分falsh block配置成SLC来缓存数据),大多数消费级ssd都是使用flash介质来缓存数据的,这样能节省成本,而企业级ssd一般使用DDR,使用SDRAM的极少极少(成本太高)。

controller

controller是host与NVM subsystem之间的接口,根据功能不同可分为三种:

​ 1)I/O controller;

​ 2)discovery controllers;

​ 3)administrative controllers.

I/O controller就是我们正常使用NVMe盘时交互的 controller ,包含一对admin queue和一个或多个I/O queue;discovery controllers只含有一对admin queue,一般用于NVMe over fabric发现远端设备的controllers信息及NVMe over fabric使用的信息;administrative controllers只含有一对admin queue,一般也在NVMe over fabric中使用,很少见。

controller就是一个处理命令的实体,和NVMe上的控制器芯片没有必然关系,目前市面上大多数ssd都只含有一个controller。

LB

Logical Block是host看到的逻辑块,也是host读写的最小单位,这个逻辑块的大小是由NVMe盘的物理介质决定的,目前市面上消费级盘大多是512 byte,而企业盘一般为4k byte。逻辑块的地址通常称为LBA(Logical Block Address缩写),host以LBA来索引NVMe中数据块位置。与LB对应的是physical block,它们之间通过FTL表映射索引。

需要注意的是,我们在操作系统上对512byte LB盘格式化成4k只是文件系统层面上的,而不会改变到NVMe底层逻辑块大小,如果我们在文件系统上写一个4k,则实际写下nvme中是写8个NLB。

arbitration mechanism

仲裁机制,用来决策SSD底层逻辑怎么选择SQ的机制,包含三种:

1)RR,轮询调度机制,每个队列优先级相同,包含admin queue和I/O queue,这个是NVMe协议要求必须实现的仲裁机制。

NVMe协议详解(一)_第3张图片

2)WRR,带优先级和加权的轮询调度机制,包含三个优先级和三个权重,如下图所示(可选机制)。

NVMe协议详解(一)_第4张图片

admin queue的优先级最高,这意味着只要admin queue中有命令,就不会去调度到其他I/O queue。接下来是urgent优先级,部分I/O queue可配置成该优先级,在没有admin queue命令时,优先执行urgent优先级对应I/O queue中命令。最后是带权重的优先级,可分别配置三种权重每次拿取多少个SQ(后续文章中详细讲解)。

3)厂商自定义的仲裁机制,可选机制。目前来看,几乎没有厂商会去自定义仲裁机制。

metadata

metadata元数据,每一个LB对应一个metadata(如果支持的话),一般而言只有企业SSD支持metadata,常说的4k+0、4k+8、4k+128等表示的就是LB大小+metadata大小,这个metadata一般用于LB块的数据校验。metadata一般放在flash的OOB区域,也受到ECC纠错算法的保护。举个例子,一个flash的physical page有16k+1.xk的大小,用作DATA+OOB,这个page分成4个ep,每个ep=4k+304字节(以304为例),这个304字节就是ep的OOB区域,假设NVMe盘LB的metadata有16字节,那留个做ECC算法(一般是LDPC)纠错的就只有288字节,这样1k数据能纠错40bit。所以flash的OOB区域越大,其支持的metadate格式越多,纠错能力也越强。

namespace

namespace是N块logical block逻辑块(LB)的集合,它的LBA从0到N-1,一块NVMe盘可以有多个namespace,个namespace的LBA都从0开始,所以每个namespace的LB对应到physical block需要一个转换表,这个表就是FTL表(Flash Translation Layer)。

namespace对Host呈现就是一块真实的物理盘,比如一块SSD盘有两个namespace(一般企业盘支持删除和创建namespace),那么host就能看到两块物理盘,并且可以分别对它们进行格式化和分区,目前消费级的sdd大都只支持一个namespace,并且不支持namespace的删除与创建。

NVM subsystem

NVM子系统包含一个或多个controller、零个或多个namespace、一个或多个port,也可以包含非易失性存储介质以及controller与存储介质之间的接口。

NVM子系统是一个广泛的概念,不仅仅适用于普通NVMe over PCIe的SSD,也适用于NVMe over Fabric,比如A主机上A_NIC网卡连接B主机上B_NIC网卡,在B主机上插有SSD,A主机通过NVMe over TCP协议访问B主机上的SSD,那么可以将上述除A主机外的所有称为一个NVM子系统(A主机视角)。

NVMe over PCIe

早期SSD绝大多数都是使用STAT接口跑的AHCI,但随着存储颗粒发展,底层介质读写速率越来越快,STAT接口已经不能满足需求,然后AHCI拉了另一个伙计PCIe合伙干活,但是它们合伙干了一段时间后发现AHCI无法发挥PCIe全部能力,因此几位存储巨头合伙制定了NVMe协议,从此基于NVMe协议的SSD开始爆发式增长。

分层

PCIe协议自身分为四层,分别为物理层、数据链路层、事务层以及应用层,如下图所示(参考《深入浅出ssd》)。

NVMe协议详解(一)_第5张图片

NVMe协议是PCIe应用层上的协议,所有的NVMe命令在PCIe协议来看都是Data Patload。

NVMe协议详解(一)_第6张图片

框架

NVMe协议详解(一)_第7张图片

NVMe SSD作为一个PCIe ep挂在host RC下。

PCIe寄存器

NVMe SSD拥有pci标准的配置空间头,但NVMe协议对部分bar寄存器有特殊的规定(bar0与bar1组成64bit bar),如下图红框所示。

NVMe协议详解(一)_第8张图片

PCI Power Management Capabilities用于SSD电源管理,该能力必须实现。

NVMe协议详解(一)_第9张图片

Message Signaled Interrupt Capability用于支持MSI中断,这是可选的能力,一般情况使用MSI-X居多。

NVMe协议详解(一)_第10张图片

MSI-X Capability用于支持MSI-X中断,虽然是可选能力,但大多数SSD都会采用MSI-X方式上报中断。

NVMe协议详解(一)_第11张图片

PCI Express Capability包含设备能力、设备控制、设备状态、Link能力、Link控制、Link状态等,是必须实现的能力。需要注意的是Device Control 2寄存器,可通过改变它来设置链路超时时间(SSD侧认为的),一般Host侧的超时时间是37~50ms。
NVMe协议详解(一)_第12张图片

Advanced Error Reporting Capability 可选能力,用于向host报告错误,注意,这个错误是PCIe协议上的错误,而不是NVMe命令执行错误。

此外还有一些其他PCIe Capability是NVMe规范未提及但会使用的,这取决于NVMe SSD的实现。

以下图是一块inter SSD实际配置空间。
NVMe协议详解(一)_第13张图片

NVMe cotroller寄存器

NVMe对SSD与host交互的寄存器有严格定义,这样避免了厂商实现不统一,导致驱动五花八门,就如现在网卡驱动一样。NVMe协议要求与host交互相关的寄存器放在PCIe bar0空间,以下是具体定义。
NVMe协议详解(一)_第14张图片

寄存器详解:

Controller Capabilities —— 00h

SSD控制器的能力寄存器,表明SSD有哪些能力,该寄存器64bit。

0-15:Maximum Queue Entries Supported (MQES),表示controller能支持多大深度的I/O,0 base也就是0表示深度为1,16bit意味着I/O深度最大为65536.

16:Contiguous Queues Required (CQR),表示I/O queue是否需要连续的物理内存,为1表示需要。目前大多数SSD均要求I/O queue内存连续,并且linux内核(5.10)驱动直接为I/O queue分配连续物理内存。

17-18:Arbitration Mechanism Supported (AMS),表示controller支持的queue调度机制(仲裁机制),17bit表示是否支持带优先级和加权的轮询调度机制(WRR),18bit表示SSD厂商自定义自定义调度机制。需要注意的,17:18对应的调度机制是可选的,但RR调度机制是必须支持的,所以没有RR调度机制对应的能力位。

19-23:Reserved

24-31:Timeout(TO)表示SSD使能或关闭使能的响应超时时间,单位为500ms,假设这个字段值为120,则表示超时时间为60s,即CC.EN从0写1或从1写0后,CSTS.RDY状态位必须在60s内对应变化,否则host认为SSD超时挂死。

32-35:Doorbell Stride (DSTRD),Doorbell的步进,计算公式为0x1000h + (x * (4 << CAP.DSTRD)),其中x是queue的排列顺序,正常情况前一个queue与后一个queue的Doorbell之间步进为0,也就是紧接排布,比如admin sq地址为0x1000,admin cq的地址是0x1004。

36:NVM Subsystem Reset Supported (NSSRS)表示NVM子系统是否支持复位。

37-44:37bit表示controller是否支持I/O命令,如果支持该bit为1,如果不支持,该bit为0且44bit要设为1.

45:Boot Partition Support (BPS)表示是否支持Boot Partition区域,该区域可以在controller未enable情况下读写数据,一般用于存放未起操作系统时要读写的数据,比如引导代码、数据、密钥等。

46-47:Reserved

48-51:Memory Page Size Minimum (MPSMIN)表示controller支持的最小内存页大小,计算公式为(2 ^ (12 + MPSMIN)),一般情况MPSMIN为0,即最小4k。

52-55:Memory Page Size Maximum (MPSMAX)表示controller支持的最大内存页大小,计算公式为(2 ^ (12 + MPSMAX)),大多数SSD的MPSMAX液位0,即最大4k。

56:Persistent Memory Region Supported (PMRS)表示是否支持持久性内存区域,这块区域存储的数据不会因掉电而丢失并提供了内存级别的速度和低延时,一般用于存储log、metadata等。

57:Controller Memory Buffer Supported (CMBS)表示controller是否支持memory buff区域,其实就是将SSD中部分DDR映射到bar空间中让host使用,linux内核(5.10)发现SSD支持该能力的话,会将SQ建立在这个区域,但CQ还是建立在host的DDR上,这是因为SSD是SQ的消费者,host是CQ的消费者。

58:-63:Reserved

Version —— 08h

该寄存器存放controller实现的NVMe版本,该寄存器会在linux内核(5.10)驱动中检查。该寄存器分为三段,如下所示。

31-16:Major Version Number (MJR)
15-08:Minor Version Number (MNR)
07-00:Tertiary Version Number (TER)

以NVMe1.4版本为例,寄存器值如下

31-16:1
15-08:4
07-00:0

Interrupt Mask Set(INTMS) —— 0Ch

中断掩码寄存器,32bit,对应位为1时禁用对应的pin-based interrupts或MSI verctor中断,该寄存器只能写1不能写0(写INTMC清对应位)。注意,该寄存器不适用MIS-X中断,因为MSI-X中断有自己对应的mask位,直接使用现有的就好了。

Interrupt Mask Clear (INTMC) —— 10h

中断掩码清除寄存器,32bit,往某个bit写1时,将清除INTMS寄存器对应bit,该寄存器只能写1,写0无效。该寄存器和INTMS寄存器结合使用,同样也无法适用MSI-X中断。

Controller Configuration —— 14h

控制器配置寄存器,简称为CC寄存器,用于配置和控制controller的行为,32bit具体含义如下。

0:Controller Enable(EN),当该位从0写为1时(0->1)表示Controller使能,host给admin queue分配好内存并配置好AQA、ASQ、ACQ三个寄存器后,将会对这个位写1,SSD的FW检测到这个行为就创建admin queue以及初始化硬件,然后SSD会将CSTS.RDY置为1表示已就绪,之后host就可以下发admin命令了。当该位从1写为0时(1->0)表示让Controller复位,SSD的FW检测到这个行为将下发命令告诉硬件不要再响应敲Doorbell,等处理完所有SQ命令并等CQE回完后删除所有I/O queue,然后复位状态和部分寄存器(不包含AQA、ASQ、ACQ),最后将CSTS.RDY置为0表示已复位。注意,在CC.EN位不为1时,将不会响应任何敲Doorbell的行为。

01-03:Reserved。

04-06:I/O Command Set Selected (CSS),该字段表示配置Controller支持哪些种类命令,值为0b000时表示支持admin和I/O命令,值为0b111表示只支持admin命令(需要CAP寄存器第44bit为1)。注意,该字段只能在CC.EN为0时配置。

07-10:Memory Page Size (MPS)表示配置Controller的内存页大小,计算公式为(2 ^ (12 + MPS)),host会根据CAP.MPSMIN字段和CAP.MPSMAX字段的值,选择一个和host内存页大小匹配的值写入该字段,一般情况下都是写0,也就是支持4k。注意,该字段只能在CC.EN为0时配置。

11-13:Arbitration Mechanism Selected (AMS),仲裁机制(queue调度机制)选择字段,值为0b000表示选择RR机制,值为0b001表示选择RR机制,值为0b111表示选择厂商自定义机制。默认情况都是使用RR机制,RR机制也是NVMe协议要求必须实现的机制。

14:15:Shutdown Notification (SHN)下电通知字段。值为0b00表示没有通知;值为0b01表示host通知SSD正常下电,此时host会给SSD留足够的时间保存数据,Controller会在这段时间内刷新掉所有在Buffer内的数据并删除Queue, 然后通过CSTS.SHST告诉Host已完成下电;值为0b10表示意外断掉,此时留给Controller的时间非常有限,Controller必须在非常短时间保存数据,注意,一般意外断电保存动作不会依赖这个字段,因为host也不清楚自己什么时候会被意外断电,SSD通常是通过检测PCIe引脚供电来发现意外掉电的。一般情况,消费级SSD没有足够的电容,也就无法实现意外断电保护数据,所以大家在使用SSD盘时候千万别意外断电,容易丢失数据。

16-19:I/O Submission Queue Entry Size (IOSQES)用于配置I/O SQ每个条目(SQE)的大小,计算公式为(2^n),其中n为该字段的值,默认是6,即SQE默认64byte。

20-23:I/O Completion Queue Entry Size (IOCQES)用于配置I/O CQ每个条目(CQE)的大小,计算公式为(2^n),其中n为该字段的值,默认是4,即CQE默认16byte。

24-31:Reserved

Controller Status(CSTS) —— 1Ch

控制器的状态寄存器,用来表征Controller状态,32bit具体含义如下。

00:Ready (RDY)该bit表示当前Controller使能状态,为1时表示SSD已使能,为0时表示SSD未使能。

01:Controller Fatal Status (CFS)表示Controller出现致命错误,当host读取到该位为1时,将下发get log page命令查询具体错误信息。当controller执行SQE命令出错且无法在CQE中表征时,HW会将该bit置1。

02-03:Shutdown Status (SHST)表示当前SSD下电动作执行情况,值为0b00表示没有下电动作,值为0b01表示下电动作执行中,值为0b10表示下电动作执行完毕。

04:NVM Subsystem Reset Occurred (NSSRO)表示NVM子系统是否发生复位,这个复位不包含上电时的复位。

05:Processing Paused (PP)表示当前controller是否在正常执行命令,为0时表示正常执行,为1时表示已经停止执行命令,比如在SSD的FW动态升级时,需要先将当前工作暂停,完成升级之后再接着执行(暂停与再次开始之间有时间间隔要求,一般不超过200ms)。

06-31:Reserved

NVM Subsystem Reset(NSSR) —— 20h

可选寄存器32bit,用于复位NVM子系统,对该寄存器写0x4E564D65值即可复位NVM子系统,写入其他值无效,读该寄存器为0。

Admin Queue Attributes(AQA) —— 24h

用于配置admin SQ/CQ的深度,32bit具体如下。

00-11:Admin Submission Queue Size (ASQS)用来配置admin SQ队列的深度,0 base最大4096深度,linux内核(5.10)驱动配置深度为32。
12-15:Reserved
16-27:Admin Completion Queue Size (ACQS)用来配置admin CQ队列的深度,0 base最大4096深度,一般与admin SQ深度一致,linux内核(5.10)驱动配置深度为32。
28-31:Reserved

Admin Submission Queue Base Address(ASQ) —— 28h

admin SQ基地址配置寄存器,64bit如下。

00-11:Reserved
12-63:Admin Submission Queue Base (ASQB)用于配置admin SQ基地址,注意这是地址的高52位,意味着host给admin SQ分配的内存最少是4k对齐的,事实上对齐需要根据CC.MPS值来确定。

Admin Completion Queue Base Address(ACQ) —— 30h

admin CQ基地址配置寄存器,64bit如下。

00-11:Reserved
12-63:Admin Completion Queue Base (ACQB)用于配置admin CQ基地址,注意这是地址的高52位,意味着host给admin CQ分配的内存最少是4k对齐的,事实上对齐需要根据CC.MPS值来确定。

Controller Memory Buffer Location(CMBLOC) —— 38h

controller内存缓存区能力支持寄存器,该寄存器为可选,32bit具体如下。

00-02:Base Indicator Register (BIR)表示CMB这个缓存buff在哪个bar上。

03:CMB Queue Mixed Memory Support (CQMMS)表示CMB是否支持队列内存混合,为1表示支持,为0表示不支持。混合内存的意思就是queue一部分放在host DDR上,一部分放在controller的缓存CMB buff上,也就是说queue是分离的。目前来看,没有SSD厂商会支持这个特性,完全是吃力不讨好,要么放DDR上,要么放缓存buff上。

04:CMB Queue Physically Discontiguous Support (CQPDS)表示queue在缓存CMB buff中是否支持不连续内存,为1表示支持不连续内存,为0表示不支持,也就是要求queue在buff中的物理内存连续。还是那句话,没有哪个厂商去支持离散queue这个特性。

05:CMB Data Pointer Mixed Locations Support (CDPMLS)表示表示是否支持数据指针与数据混合模式,为1表示支持混合,为0表示不支持。支持则表示数据和数据指针(PRP/SGL list)可以分别位于DDR或CMB缓存中。注意,该位需要和CDPCILS联合使用,如果CDPCILS为1,则数据指针在host DDR上或CMB上都可以,如果CDPCILS为0,则数据指针所在位置必须跟随queue所在位置。

06:CMB Data Pointer and Command Independent Locations Support (CDPCILS)表示是否支持数据指针(PRP/SGL list)和queue分开存放,为1表示支持,为0表示不支持。也就是说为1时queue可以和数据指针分离存放。

07:CMB Data Metadata Mixed Memory Support (CDMMMS)表示是否支持元数据与数据混合存放,为1表示支持,为0表示不支持,和上面一样。

08:CMB Queue Dword Alignment (CQDA)表示CMB是否支持queue地址DWord对齐,为1表示支持,为0表示不支持。不支持时按正常创建I/O的要求来处理,也就是最少4k对齐,事实上对齐需要根据CC.MPS值来确定。

09-11:Reserved

12-31:表示CMB缓存所在bar空间的偏移,单位由CMBSZ.SZU字段指定,单位分别有4k、64k、1M、16M、256M、4G、64G。

Controller Memory Buffer Size(CMBSZ) —— 3Ch

controller内存缓存区大小即属性寄存器,该寄存器为可选,32bit具体如下。

00:Submission Queue Support (SQS)表示是否支持将SQ建在CMB区域,1表示支持,0表示不支持。

01:Completion Queue Support (CQS)表示是否支持将CQ建在CMB区域,1表示支持,0表示不支持。需要注意的是,即使SSD支持将CQ建在CMB区域这个能力,linux内核(5.10)驱动也不会将CQ建在CMB区域中,猜猜为什么?提示一下,和时间有关。

02:PRP SGL List Support (LISTS)表示是否支持将PRP/SGL list数据指针表放在CMB区域中,为1表示支持,为0表示不支持。

03:Read Data Support (RDS)表示CMB是否支持读数据操作,1表示支持,0表示不支持。

04:Write Data Support (WDS)表示CMB是否支持写数据操作,1表示支持,0表示不支持。需要注意的是,往往RDS位与WDS位要一起使能,否则SQ和数据等都不会放在CMB区域。

05-07:Reserved

08-11:Size Units (SZU)表示CMB区域单位的大小,与之关联的有 CMBSZ.SZ字段和CMBLOC.OFST字段,值为0h表示4k,1h表示64k,2h表示1M,3h表示16M,4h表示256M,5h表示4G,6h表示64G。

12-31:Size (SZ)表示整个CMB区域的大小,单位由CMBSZ.SZU决定。需要注意的是,如果((Offset + Size)*Units) > bar size,则CMB的区域受限于bar大小。

Boot Partition Information(BPINFO) —— 40h

该寄存器定义了启动分区相关信息,可选寄存器,用于BIOS从NVMe盘启动系统,32bit具体含义如下。

00-14:Boot Partition Size (BPSZ)表示每个引导分区大小,2个引导分区大小是一样的,这个大小为128k的倍数。

15-23:Reserved

24-25:Boot Read Status (BRS)表示引导分区读取状态,值为0b00表示没有读操作,0b01表示读操作正常进行中,0b10表示读操作完成,0b11表示引导分区读取出错。

26-30:Reserved

31:Active Boot Partition ID (ABPID)表示当前选择的引导分区id,有0、1。

Boot Partition Read Select(BPRSEL) —— 44h

该寄存器用来配置引导分区的读操作,可选寄存器,32bit具体含义如下。

00-09:Boot Partition Read Size (BPRSZ)引导分区读大小,单位4k。

10-29:Boot Partition Read Offset (BPROF)引导分区读偏移位置,单位4k。

30:Reserved

31:Boot Partition Identifier (BPID)用来选择读哪个引导分区,有0、1。

Boot Partition Memory Buffer Location(BPMBL) —— 48h

用于指定读引导分区时,数据存放的位置。host发起对引导分区读时,只是配置了相关寄存器,真正读这个动作是由SSD的DMA将数据写到host DDR上的,所以需要配置数据放置DDR的地址。

00-11:Reserved

12-63:Boot Partition Memory Buffer Base Address (BMBBA)用来配置DDR上物理地址,只有高52位意味着地址至少4k对齐。

Controller Memory Buffer Memory Space Control(CMBMSC) —— 50h

用于配置CMB区域,64bit具体如下。

00:Capabilities Registers Enabled (CRE)表示是否启用CMA相关寄存器,比如CMBLOC、CMBSZ,当该bit为1时,CMBLOC、CMBSZ寄存器值才如上面描述那样,否则CMBLOC、CMBSZ都是0。

01:Controller Memory Space Enable (CMSE)表示是否使能CMB空间。

02-11:Reserved

12-63:Controller Base Address (CBA)用于配置CMB所在bar的pci域地址。有点奇怪,SSD完全可以从自己的配置空间中读取bar地址,完全不需要host再去配置。

Controller Memory Buffer Status(CMBSTS) —— 58h

用来显示CMB状态,目前仅有1bit有效。

00:Controller Base Address Invalid (CBAI)表示host写到CMBMSC.CBA中的地址是否合法有效。该bit只有在CMBMSC.CRE为1时有意义。

Persistent Memory Region Capabilities(PMRCAP) —— e00h

该寄存器用来描述持久性内存相关能力。

00-02:Reserved

03:Read Data Support (RDS)持久性内存是否支持读数据。

04:Write Data Support (WDS)持久性内存是否支持写数据。

05-07:Base Indicator Register (BIR)持久性内存所在bar id。注意,持久性内存单独使用一个bar。

08-09:Persistent Memory Region Time Units (PMRTU)持久性内存时间单位,0b00表示500ms,0b01表示分钟。与这个字段相关的字段有PMRCAP.PMRTO。

10-13:Persistent Memory Region Write Barrier Mechanisms (PMRWBM)用于表示持久性内存的读写屏障机制。10bit为1表示在对持久性内存地址空间读操作时,之前的写操作已完成并是持久的。11bit为1表示对PMRSTS寄存器读状态时,之前对持久性内存的写操作都已完成并且是持久的。

14-15:Reserved

16-23:Persistent Memory Region Capabilities (PMRTO)用于表示写PMRCTL.EN(使能持久性内存区域)之后多久使能后可以访问持久性内存区域,单位由PMRCAP.PMRTU字段决定。

24:Controller Memory Space Supported (CMSS)如果controller支持使用主机提供的地址引用持久内存区域,这个位应该置为1,否则为0。

25-31:Reserved

Persistent Memory Region Control(PMRCTL) —— e04h

用来控制使能持久性区域。

00:Enable (EN)使能持久性内存区域,必须等待PMRSTS.NRDY为0之后才可以真正去读写操作持久性内存区域。

1-31:Reserved

Persistent Memory Region Status(PMRSTS) —— e08h

用于显示持久性内存区域状态,32bit具体如下。

00-07:Error (ERR)表示对持久性内存读写是否存在错误,为0时读写正常,并且写是持久的,非0时表示出错,出错含义由厂商自定义。

08:Not Ready (NRDY)表示持久性内存其余未就绪,为1表示未就绪,为0表示就绪。

09-11:Health Status (HSTS)表示持久内存区域的健康状态。值为0b000表示正常操作。0b001表示之前出错了,但持久性内存区域已经恢复正常工作,这意味着之前最后移除写的数据不一定写入成功;0b010表示区域只读。0b011表示区域已经不可靠。

12:Controller Base Address Invalid (CBAI)表示持久性内存配置的地址(PMRMSC.CBA)是否为无效。

13-31:Reserved

Persistent Memory Region Elasticity Buffer Size(PMREBS) —— e0ch

持久性内存区大小,32bit具体如下。

00-03:PMR Elasticity Buffer Size Units (PMRSZU)表示缓存buff大小的单位,,值为0h表示单位为byte,1表示单位为1k,2表示单位为1M,3表示单位为1G。

04:Read Bypass Behavior,表示读操作是否能超越之前的写操作。为1表示,当读地址与上一次写地址不冲突时,可以让读超越写,提前返回读数据。为0表示,当读地址与上一次写地址不冲突时,可能会出现读超越写。

05-07:Reserved

08-31:PMR Elasticity Buffer Size Base (PMRWBZ)表示缓存区大小,该字段的单位由PMRSZU字段决定。

Persistent Memory Region Sustained Write Throughput(PMRSWTP ) —— e10h

用于向host表明持久性缓存区持续性写的速率大小。

00-03:PMR Sustained Write Throughput Units (PMRSWTU)表示持续性写速率的单位。0表示单位byte,1表示单位1k,2表示单位1M,3表示单位1G。

04-07:Reserved

08-31:PMR Sustained Write Throughput (PMRSWTV)表示在PCIe最大支持负载下吞吐量大小,单位由PMRSWTU指定。

Persistent Memory Region Memory Space Control(PMRMSC) —— e14h

用于配置持久性内存空间,64bit具体如下。

00:Reserved

01:Controller Memory Space Enable (CMSE)该位表示host是否可以提供地址引用持久性内存区域。

02-11:Reserved

12-63:Controller Base Address (CBA)持久性内存区域所在bar空间的pci域地址。

Submission Queue y Tail Doorbell(SQyTDBL) —— 1000h + ((2y) * (4 << CAP.DSTRD))

SQ doorbell寄存器,32bit如下。

00-15:Submission Queue Tail (SQT)SQ的tail。

16-31:Reserved

Completion Queue y Head Doorbell(CQyHDBL ) —— 1000h + ((2y + 1) * (4 << CAP.DSTRD))

CQ doorbell寄存器,32bit如下。

00-15:Completion Queue Head (CQH)CQ的head。

16-31:Reserved

在忙别的,下一篇博客不知道啥时候能更新,未完待续~~~

你可能感兴趣的:(NVMe,NVMe,SSD)