概述
NVM Express 或非易失性內存主機控制器接口(其先前名稱為 NVMHCI,現在縮寫為 NVMe)是一種基于主機的軟件接口,旨在通過 PCIe 結構與固態存儲設備進行通信。目前的 Synopsys NVMe 驗證 IP (VIP) 是一個綜合測試工具,由兩個主要子系統組成——第一個是 SVC(系統驗證組件),第二個是 SVT(系統驗證技術)。SVC 層與實際的 NVMe(和 PCIe 等)協議層相關聯。SVT 為 UVM 和其他方法(如 VMM 和 OVM)提供了驗證方法接口。
盡管VIP支持多個版本的VIP,但我們最初將與版本無關,更多地談論協議的一般情況,以便提供協議及其在VIP中的支持的10,000'視圖。未來的討論將更深入地探討 NVMe 的特定細節和驗證 IP 的功能。
您可以在此處了解有關 Synopsys 針對 NVMe 的 VC 驗證 IP 的更多信息。
NVMe簡介
與根和端點基本相等的PCIe不同,NVMe的非對稱關系更接近其他存儲協議(例如SATA,光纖通道)。
NVMe 命令(例如識別、讀取、寫入)在主機上啟動并轉換為 NVMe 請求,然后將其附加到主機內存中的特定提交隊列。將命令插入隊列后,主機將寫入控制器上的每個隊列門鈴寄存器(控制器位于 PCIe 端點上)。此門鈴寫入喚醒控制器,然后控制器探測隊列中是否有新請求。它讀取隊列條目,執行命令(可能從主機內存讀取數據緩沖區),最后將完成追加到完成隊列中,然后通過中斷通知主機。主機喚醒,從隊列中彈出該完成操作,并將結果返回給用戶。
使用兩種主要類型的隊列:
管理隊列 – 這些隊列用于配置和管理控制器的各個方面。每個控制器只有一對管理隊列。
I/O 隊列 – 這些隊列用于移動 NVMe 協議特定的命令(例如讀取、寫入)。每個控制器最多可以有 64K 個 I/O 隊列。
隊列的每個隊列都有尾(生產者)和頭(使用者)指針。尾部指針指向要向其添加條目的下一個可用條目。在生產者將條目添加到隊列后,他會遞增尾指針(考慮到一旦它到達隊列的末尾,它將回繞到零 - 它們都是循環隊列。如果頭指針和尾指針相等,則隊列被視為空。
使用者使用她的頭指針來確定從隊列中開始讀取的位置;在檢查尾指針并確定隊列為非空后;她將在閱讀每個條目后遞增頭部指針。
提交隊列的尾指針由主機管理;將一個或多個條目推入隊列后,尾指針(遞增)通過提交隊列門鈴寄存器寫入控制器。控制器維護頭部指針,并在收到尾部指針更新的通知后開始讀取隊列。它可以繼續讀取隊列,直到為空。當它使用條目時,頭部指針會更新,并通過完成隊列條目發送回主機(見下文)。
同樣,完成隊列的尾部由控制器管理,但與主機不同,控制器僅維護尾部指針的私有副本。存在新完成隊列條目的唯一指示是可以輪詢的完成隊列條目中的位。一旦主機確定某個條目可用,它將讀取該條目并更新頭指針。控制器通過主機寫入完成隊列門鈴寄存器來通知頭指針更新。
請注意,NVMe 控制器完成的所有工作都由控制器本身拉入或推出該控制器。主持人只是將工作放入主機內存并按門鈴(“您有一個提交條目要處理”)。稍后,它從完成隊列中收集結果,再次按門鈴(“我已完成這些完成條目”)。因此,控制器可以自由地與主機并行工作;例如,不需要對完成進行排序 - 控制器可以對它的工作進行排序,無論如何它感覺就像。
那么,我們在主機和控制器之間來回移動的這些隊列條目是什么?
第一個是提交隊列條目,這是一種 64 字節的數據結構,主機使用它將命令請求傳輸到控制器:
字節 | 描述 |
63:40 | 命令字 15-10 (CDW15-10):6 個命令特定信息的字。 |
39:32 | PRP 條目 2 (PRP2): 指向 PRP 條目或緩沖區或(與 PRP1 一起)SGL 段的指針。 |
31:24 | PRP 條目 1 (PRP1): 指向 PRP 條目、緩沖區或(與 PRP2 結合使用)SGL 段的指針。 |
23:16 | 元數據指針 (MPTR): 此字段包含 SGL 段或包含元數據的連續緩沖區的地址。 |
15:08 | 保留 |
07:04 | 命名空間標識符 (NSID): 此字段指定此命令適用的命名空間 ID。 |
03:00 | 命令字 0 (CDW0): 此字段對所有命令都是通用的,包含命令操作碼 (OPC)、命令標識符 (CID) 和各種控制位。 |
每個命令一個提交隊列條目排隊到相應的管理員或 I/O 隊列。操作碼指定要執行的特定命令,命令標識符是命令的唯一標識符(與提交隊列 ID 結合使用時)。
除了使用隊列條目來回移動信息外,主機還可以在主機內存中分配數據緩沖區。這些緩沖區可以是連續的(由其基址和長度定義),也可以是分布在內存周圍的一組數據緩沖區。后者使用稱為PRP列表和分散-聚集列表(SGL)的數據結構來定義其位置。當主機需要將這些緩沖區移入/移出控制器時(例如,用于讀取或寫入命令),它將在主機內存中分配適當的數據結構,并在將隊列條目寫入該控制器之前,將這些緩沖區的這些數據結構的信息寫入上述 PRP1 和 PRP2 字段。
元數據(例如端到端數據保護)也可以通過兩種方式與 NVMe 命令一起傳遞。它可以與數據一起在帶內發送(即它與每個扇區的數據相鄰),也可以帶外發送(即它作為單獨的數據流發送)。在SCSI術語中,它們分別稱為數據完整性字段(DIF)和數據完整性擴展(DIX)。后者使用上述元數據指針。我們將在以后的劇集中詳細討論這一點。
當我們實際向控制器上的非易失性存儲寫入/讀取時,我們會寫入命名空間。 在其他存儲技術中,還有其他類似的容器 - 例如SCSI中的LUN。命名空間對于控制器是唯一的,也可以在多個控制器之間共享。無論如何,請求中的命名空間 ID 字段確定要訪問的命名空間。某些命令不使用命名空間字段(然后設置為 0),其他命令可能需要處理所有命名空間(然后將命名空間 ID 設置為 0xffff_ffff)。
在完成端,有一個類似的數據結構,即完成隊列條目:
字節 | 描述 |
15:12 | 命令特定信息:返回信息的一個字。(并不總是使用。 |
11:8 | 保留 |
7:6 | 提交隊列 ID: 發送關聯命令的提交隊列。(16 位) |
需要注意的幾點:
提交隊列 ID 需要顯式顯示在完成隊列條目中,因為多個提交隊列可以共享一個完成隊列。
如上所述,提交隊列頭指針由控制器維護。當控制器更新該頭指針時,它需要將這些更新發送回主機,允許主機重用這些隊列條目,直到并包括新頭)。
狀態字段實際上由幾個子字段組成,并且有大量的錯誤狀態代碼。
相位標記提供了一個可以輪詢的位(如果主機驅動程序軟件愿意,而不是純粹的中斷驅動)。如果在檢查隊列的尾條目時階段標記發生更改,則可以推斷有新條目要檢查。
為了介紹可用的命令,我們將在此處列出其中的一些命令:
創建管理隊列 – 實際上本身不是一個命令,這是對 NVMe 控制器的寄存器寫入,用于定義管理員提交和完成隊列。NVMe 寄存器集具有少量用于基本配置、控制和狀態的寄存器。
創建 I/O 隊列 – 用于創建提交和完成隊列的命令。
識別 – 幾個命令允許請求有關控制器和附加到控制器的命名空間的各種信息。
設置/獲取功能 – 設置 NVMe 特定“功能”(例如可配置設施)的方法。
讀/寫 – 這就是我們真正在這里的原因:從/向附加到控制器的命名空間讀取和寫入數據。
由于一個活躍的團隊正在推動開發,NVMe 一直在添加更多的命令和功能。
審核編輯:郭婷
-
控制器
+關注
關注
112文章
15879瀏覽量
175338 -
接口
+關注
關注
33文章
8254瀏覽量
149942 -
nvme
+關注
關注
0文章
207瀏覽量
22503
發布評論請先 登錄
相關推薦
評論