Host寻址NVMe寄存器的具体实现与计算

原创内容,转载请注明:  [http://www.ssdfans.com]  谢谢!

作者 谭荣

 

在上电的过程中,每个Endpoint的内部地址空间都会通过内存映射(memory map)的方式映射到Host的内存中,SSD 内部与协议相关的所有寄存器都会被映射到Host的内存中(如图1所示)。Host访问的address只需为该寄存器在Host内存中映射的地址,就能准确地访问ssd的寄存器。注意Host不是往自己内存的那个物理地址读取或写入东西,而是用那个物理地址作为寻址用,最后访问SSD controller的寄存器。


图1

图2是NVME Spec对Host端到device端内存映射(memory map)的英文说明,SSD内部所有相关寄存器的映射都是在这些模块的基地址上进行偏移的,如BAR0、BAR1、MTAB、MPBA等。

 


图2:

那么具体是如何实现的呢?如图3以一个read命令举例,看懂Host如何访问device的SQ Tail Doorbell寄存器。


图3:

从图1可以看出Host端到SSD端的内存映射框图,它是没有直接到SQ Tail Doorbell的映射指向的,结合图3(SQID 4)与图4我们可以知道,Host要访问的地址是submission queue 4 tail doorbell。


图4:

图1可以知道Doorbeel Reg模块在Host端内存的首地址是{BAR0,BAR1}+1000,图4可以得出在该模块内部寄存器的偏移是1000h+ (2y * (4 <<CAP.DSTRD),其中y=4,那CAP.DSTRD的值是多少呢?

图5为DSTRD的Spec解释,不同厂商的sdk在Initialize the NVMe Controller Capabilities (CAP) register时,会对CAP.DSTRD进行初始化。这个值也可以通过抓取device上电行为得到,如图6。


图5:


图6:

最后一个问题,bar0和bar1是多少?NVME device在上电的时候会做一堆操作。如图7,Host通过Configuration Write向寄存器0x10写了一个地址,即BAR0=0XD1100000。


图7:

如图8,Host通过Configuration Write向寄存器0x14写了一个地址,即BAR1=0X00000000。


图8:

从图9可以看出0x10与0x14实际上就是bar0与bar1的偏移。


图9:

最后结合上面的参数做一次验证:submission queue 4 tail doorbel=

{BAR0,BAR1}+1000+Doorbell(寄存器内部偏移)={0XD1100000}+1000h+(2y * (4 <<CAP.DSTRD)

=0XD1101000+(2*4* (4 <<0)= 0XD1101000+32=0XD1101000+20h=0XD1101020。与图10完全吻合!


图10:

 


 

分类目录 SSD, 技术文章.
扫一扫二维码或者微信搜索公众号ssdfans关注(添加朋友->点最下面的公众号->搜索ssdfans),可以经常看到SSD技术和产业的文章(SSD Fans只推送干货)。
ssdfans微信群介绍
技术讨论群 覆盖2000多位中国和世界华人圈SSD以及存储技术精英
固件、软件、测试群 固件、软件和测试技术讨论
异构计算群 讨论人工智能和GPU、FPGA、CPU异构计算
ASIC-FPGA群 芯片和FPGA硬件技术讨论群
闪存器件群 NAND、3D XPoint等固态存储介质技术讨论
企业级 企业级SSD、企业级存储
销售群 全国SSD供应商都在这里,砍砍价,会比某东便宜20%
工作求职群 存储行业换工作,发招聘,要关注各大公司招聘信息,赶快来
高管群 各大SSD相关存储公司高管和创始人、投资人

想加入这些群,请微信扫描下面二维码,或搜索nanoarchplus,加阿呆为微信好友,介绍你的昵称-单位-职务,注明群名,拉你进群。SSD业界需要什么帮助,也可以找阿呆聊。