PCIe NVMe SSD 上电初始化全流程
1. 在FPGA中对PCIe IP核中的各种寄存器进行最原始的配置,比如Vendor ID, Device ID, Revision ID, Class Vaule等等
2. HOST首先将PCIe的Bar全写入1,来获取NVMe寄存器的大小,并在内核空间中开辟一块内存(不是真的通过kalloc去开辟,只是指定一块内存没有被使用的地址)来映射NVMe寄存器,并将此块内存的首地址填入PCIe 的Bar寄存器中
注:HOST访问这块映射的内存时,Root Complex会自动转发到对应的PCIe Endpoint
3. HOST首先通过PCIe TLP事务去配置位于PCIe Bar寄存器指向的NVMe寄存器,具体来说是配置NVMe寄存器中的Admin Queue
Attributes (AQA),Admin Submission Queue Base Address (ASQ),以及Admin Completion Queue Base Address (ACQ)。从而完成对Admin Queue的配置,使得SSD后续能够接收Admin Command。
4. HOST通过PCIe TLP事务设置 CC寄存器中各个参数,包括主机页面大小、IO完成队列条目大小、IO提交队列条目大小、关机通知、内存页面大小、命令仲裁方式等。
5. HOST通过PCIe TLP事务将CC寄存器中的EN设置为1
6. HOST等待NVMe 控制器将NVMe寄存器中的CSTS.RDY变为1,表示控制器准备好接收NVMe Command。
7. HOST开始通过ASQ和ACQ发起Admin Command,首先通过Set Features获取I/O队列的数量。
8. HOST发送Identify命令,将CNS设置为1,来获取SSD内部的Controller的数据结构,里面包含SSD的名称,厂商,IO SQ, CQ的Entry大小,一次命令的最大传输量(mdts),寻址方式(是否支持SGL),namespace数量等。
9. HOST发送Identify命令,将CNS设置为2,来获取此SSD中每一个Namespace
10. HOST发送Identify命令,将CNS设置为0,来获取SSD内部Namespace的数据结构,里面包含此Namespace中的起始逻辑地址,逻辑页的数量(也即整个SSD的容量)信息。
11. HOST通过Create I/O Completion Queue Command来创建适当数量的CQ。
12. HOST通过Create I/O Submission Queue Command来创建适当数量的SQ。
13. HOST可以正常发送NVMe I/O Command