阿呆实战NVMe之七

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

 

 

提要

 

本系列文章,旨在带你开发一个NVMe SSD控制器的前端协议逻辑,只不过是在QEMU虚拟机环境中。前面我们介绍了QEMU中PCI设备的初始化代码,还有NVMe设备的主要描述类NVMEState的每个变量。本文来看看NVMe设备的初始化,不过从本文开始,阿呆将少贴一些代码,关于编程技巧方面的就不多写了,毕竟无关宏旨,我们重点还是关注NVMe协议的实现。

 

话说最近几十年来,很多聪明的科学家分析了许许多多的宇宙观测数据,最后得出一个惊人的结论:我们的宇宙是由一个致密炽热的奇点于137亿年前一次大爆炸后膨胀形成的。爆炸之初,物质只能以中子、质子、电子、光子和中微子等基本粒子形态存在。宇宙爆炸之后的不断膨胀,导致温度和密度很快下降。随着温度降低、冷却,逐步形成原子、原子核、分子,并复合成为通常的气体。气体逐渐凝聚成星云,星云进一步形成各种各样的恒星和星系,最终形成我们如今所看到的宇宙。

 

看得出来,宇宙一开始的时候定义了一些物理定律,同时赋予初始值,从此就有了丰富多彩的宇宙。我们的NVMe设备也是如此,在初始化的时候主要还是设定一些机制,同时为各种变量赋初值,这些基本的机制从此开始循环运转,满足用户实现各种各样的需求。

 

当然,宇宙并没有循环运转,《三体》的结尾告诉我们,大爆炸最终是要塌缩到奇点的,只不过被人为阻碍了,人类灭绝,只有程心和关一帆携手走到了新的宇宙。

 

 

NVMe控制器初始化

 

初始化函数pci_nvme_init一进来,还是老套路,获得NVMEState指针。

 

1 static int pci_nvme_init(PCIDevice *pci_dev)
2 {
3     NVMEState *n = DO_UPCAST(NVMEState, dev, pci_dev);

 

接着,创建我们虚拟的SSD磁盘。看得出来,为每个NVMe namespace创建了一个SSD,由此我们也可以理解namespace的用法,就是把1个NVMe出来的SSD划分成几个独立的SSD,使用namespace来管理,在上层看来就有很多个盘,大家各干各的,互不干扰。真所谓鸡犬之声相闻,老死不相往来。

 

n->disk = (DiskInfo *)qemu_malloc(sizeof(DiskInfo)*n->num_namespaces);

 

接下来就是初始化SQ,CQ和Admin Q。然后要从配置文件NVME_device_PCI_config把PCI相关寄存器的定义和参数加载进来。文件内容,举个例子:

 

 1 <REG>
 2     CFG_NAME = PCIHEADER
 3     NAME = "CMD"
 4     OFFSET = 0x04
 5     LENGTH = 0x02
 6     VALUE = 0x03
 7     RO_MASK = 0xFBF8
 8     RW_MASK = 0x0447
 9     RWC_MASK = 0x0
10     RWS_MASK = 0x0
11     DESC = "Command Register"
12 </REG>

 

看得出来,定义了偏移地址,长度,还有前文说过的各种MASK。

 

MSI中断初始化

 

接下来就是MSI中断初始化。哎,等等等等,MSI?什么东东?首先我们来看PCI设备的中断机制,是有一些物理的中断信号,与处理器的中断控制器相连,通过电平变化触发中断。

 

PCI总线V2.2规范还定义了一种新的中断机制,即MSI中断机制。MSI中断机制采用存储器写总线事务向处理器系统提交中断请求,其实现机制是向HOST处理器指定的一个存储器地址写指定的数据。这个存储器地址一般是中断控制器规定的某段存储器地址范围,而且数据也是事先安排好的数据,通常含有中断向量号。其实就是文明在进步,不玩硬的了,来软的。不用电平触发,而是往主机内存写段数据就能触发中断了。

 

HOST主桥会将MSI这个特殊的存储器写总线事务进一步翻译为中断请求,提交给处理器。目前PCIe和PCI-X设备必须支持MSI中断机制,但是PCI设备并不一定都支持MSI中断机制。

 

MSI中断机制虽然在PCIe总线上已经成为主流,但是在PCI设备中并不常用。即便是支持MSI中断机制的PCI设备,在设备驱动程序的实现中也很少使用这种机制。首先PCI设备具有INTx#信号可以传递中断,而且这种中断传送方式在PCI总线中根深蒂固。其次PCI总线是一个共享总线,传递MSI中断需要占用PCI总线的带宽,需要进行总线仲裁等一系列过程,远没有使用INTx#信号线直接。不过我们这里说的是NVMe,就不考虑PCI了,而是关注PCIe。

 

QEMU里面用的是MSI的升级版MSIX,MSI-X中断机制与MSI的中断机制类似。PCIe总线引出MSI-X机制的主要目的是为了扩展PCIe设备使用中断向量的个数,同时解决MSI中断机制要求使用中断向量号连续所带来的问题。

 

QEMU中NVMe的MSIX中断向量初始化代码如下,其实就是申请了中断向量,页和前文介绍的MMIO。

1     dev->msix_entry_used = qemu_mallocz(MSIX_MAX_ENTRIES *
2                                         sizeof *dev->msix_entry_used);
3 
4     dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE);
5     msix_mask_all(dev, nentries);
6 
7     dev->msix_mmio_index = cpu_register_io_memory(msix_mmio_read,
8                                                   msix_mmio_write, dev,
9                                                   DEVICE_NATIVE_ENDIAN);

 

引用

 

https://github.com/nvmeqemu

sailing, 《浅谈PCIe体系结构》, http://blog.sina.com.cn/s/blog_6472c4cc0100qfau.html

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

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