1. nvme init
pcie training 完成后,host会将bar0 base addr写入pcie config 寄存器中,如上写入0xa1100000
nvme init阶段,host会来写AQA,ASQ,ACQ,写CC ON,CC ready后,写MSIX 中断向量表,如图,在bar0偏移0x2000处写入中断向量0,的addr:0xFEE02004,intr data:22400000, 配置完成后,就可以发送SQ到device了
2. 写SQ entry
创建SQ,CQ时,传入SQ和CQ的base addr
向创建的io队列中发起第一个命令,将SQ写入对应的地址
3. 带prp list的完整io flow
如上,传输256个sector,即128K的数据,nvme init时,设置host page size 为4K,因为需要32 host page,2个prp无法传输完成,prp2为prplist,读取prp2中的prp entry,再拉数据
如上图,device先从prp1 fetch数据,再从prp2中fetch了两个prp entry1,prp entry2
prp1的数据取完后,继续fetchprp entry1和prp entry2的数据,这中间device会再去fetch prp entry3,这样知道fetch完整个32 page的数据
取完后,向cq entry buffer写入CQ,并向host地址为0xFEE00004的位置写入0x22400000触发中断,写cq doorbell,通知host 来fetch CQ
基本上device 和host的nvme协议层面的交互就是如此