韌體

韌體佈局

基於 CSS 的韌體結構用於所有平臺上的 GuC 版本以及 DG1 之前的 HuC 版本。 從 DG2/MTL 開始,HuC 使用 GSC 佈局代替。 CSS 韌體佈局如下所示

+======================================================================+
|  Firmware blob                                                       |
+===============+===============+============+============+============+
|  CSS header   |     uCode     |  RSA key   |  modulus   |  exponent  |
+===============+===============+============+============+============+
 <-header size->                 <---header size continued ----------->
 <--- size ----------------------------------------------------------->
                                 <-key size->
                                              <-mod size->
                                                           <-exp size->

韌體可能具有也可能不具有模數金鑰和指數資料。 標頭、uCode 和 RSA 簽名是驅動程式必須使用的元件。 每個元件的長度,均以 dword 為單位,可以在標頭中找到。 如果 fw 中不存在模數和指數(即截斷的影像),則長度值仍會出現在標頭中。

驅動程式將根據以下規則執行一些基本的 fw 大小驗證

  1. 標頭、uCode 和 RSA 是必備元件。

  2. 所有韌體元件(如果存在)都按照上面佈局表中所示的順序排列。

  3. 每個元件的長度資訊可以在標頭中找到,以 dword 為單位。

  4. 驅動程式不需要模數和指數金鑰。 它們可能不會出現在 fw 中。 因此,驅動程式在這種情況下會載入截斷的韌體。

基於 GSC 的韌體結構用於所有平臺上的 GSC 版本以及從 DG2/MTL 開始的 HuC 版本。 較早的 HuC 版本則使用基於 CSS 的佈局。 與 CSS 標頭不同,GSC 標頭使用目錄 + 條目結構(即,存在指向由名稱標識的特定標頭擴充套件的地址陣列)。 雖然標頭結構相同,但某些條目特定於 GSC,而其他條目特定於 HuC。 清單標頭條目(包括關於二進位制檔案的基本資訊,如版本)始終存在,但根據二進位制檔案型別,其命名方式有所不同。

HuC 二進位制檔案以程式碼分割槽目錄 (CPD) 標頭開頭。 我們感興趣的驅動程式中使用的條目是

  1. “HUCP.man”:指向 HuC 的清單標頭。

  2. “huc_fw”:指向 FW 程式碼。 在支援透過 DMA 載入和 2 步 HuC 身份驗證(即 MTL+)的平臺上,這是一個完整的基於 CSS 的二進位制檔案,而如果 GSC 正在執行載入(僅在 DG2 上發生),則此部分僅包含 uCode。

基於 GSC 的 HuC 韌體佈局如下所示

+================================================+
|  CPD Header                                    |
+================================================+
|  CPD entries[]                                 |
|      entry1                                    |
|      ...                                       |
|      entryX                                    |
|          "HUCP.man"                            |
|           ...                                  |
|           offset  >----------------------------|------o
|      ...                                       |      |
|      entryY                                    |      |
|          "huc_fw"                              |      |
|           ...                                  |      |
|           offset  >----------------------------|----------o
+================================================+      |   |
                                                        |   |
+================================================+      |   |
|  Manifest Header                               |<-----o   |
|      ...                                       |          |
|      FW version                                |          |
|      ...                                       |          |
+================================================+          |
                                                            |
+================================================+          |
|  FW binary                                     |<---------o
|      CSS (MTL+ only)                           |
|      uCode                                     |
|      RSA Key (MTL+ only)                       |
|      ...                                       |
+================================================+

GSC 二進位制檔案改為以佈局標頭開頭,該標頭包含二進位制檔案的各個分割槽的位置。 我們感興趣的是 boot1 分割槽,我們可以在其中找到 BPDT 標頭,後跟條目,其中一個條目指向分割槽的 RBE 子部分,其中包含 CPD。 GSC blob 不包含基於 CSS 的二進位制檔案,因此我們只需要查詢清單,該清單位於 “RBEP.man” CPD 條目下。 請注意,我們無需找到實際 FW 程式碼在影像中的位置,因為 GSC ROM 本身將解析標頭以找到它並載入它。 GSC 韌體標頭佈局如下所示

+================================================+
|  Layout Pointers                               |
|      ...                                       |
|      Boot1 offset  >---------------------------|------o
|      ...                                       |      |
+================================================+      |
                                                        |
+================================================+      |
|  BPDT header                                   |<-----o
+================================================+
|  BPDT entries[]                                |
|      entry1                                    |
|      ...                                       |
|      entryX                                    |
|          type == GSC_RBE                       |
|          offset  >-----------------------------|------o
|      ...                                       |      |
+================================================+      |
                                                        |
+================================================+      |
|  CPD Header                                    |<-----o
+================================================+
|  CPD entries[]                                 |
|      entry1                                    |
|      ...                                       |
|      entryX                                    |
|          "RBEP.man"                            |
|           ...                                  |
|           offset  >----------------------------|------o
|      ...                                       |      |
+================================================+      |
                                                        |
+================================================+      |
| Manifest Header                                |<-----o
|  ...                                           |
|  FW version                                    |
|  ...                                           |
|  Security version                              |
|  ...                                           |
+================================================+

一次寫入保護內容儲存器 (WOPCM) 佈局

在寫入 GuC WOPCM 大小和偏移暫存器之後,WOPCM 的佈局將固定,這些暫存器的值由 HuC/GuC 韌體大小和一組硬體要求/限制計算和確定,如下所示

  +=========> +====================+ <== WOPCM Top
  ^           |  HW contexts RSVD  |
  |     +===> +====================+ <== GuC WOPCM Top
  |     ^     |                    |
  |     |     |                    |
  |     |     |                    |
  |    GuC    |                    |
  |   WOPCM   |                    |
  |    Size   +--------------------+
WOPCM   |     |    GuC FW RSVD     |
  |     |     +--------------------+
  |     |     |   GuC Stack RSVD   |
  |     |     +------------------- +
  |     v     |   GuC WOPCM RSVD   |
  |     +===> +====================+ <== GuC WOPCM base
  |           |     WOPCM RSVD     |
  |           +------------------- + <== HuC Firmware Top
  v           |      HuC FW        |
  +=========> +====================+ <== WOPCM Base

GuC 可訪問的 WOPCM 從 GuC WOPCM 基地址開始,到 GuC WOPCM 頂部地址結束。 WOPCM 的頂部部分保留給硬體上下文(例如 RC6 上下文)。

GuC CTB Blob

我們分配單個 blob 來儲存 CTB 描述符和緩衝區

偏移量

內容

大小

0x0000

H2G CTB 描述符(傳送)

4K

0x0800

G2H CTB 描述符 (g2h)

0x1000

H2G CT 緩衝區(傳送)

n*4K

0x1000 + n*4K

G2H CT 緩衝區 (g2h)

m*4K

每個 CT Buffer 的大小必須是 4K 的倍數。 我們預計在任何時候都不會有太多的訊息在傳輸中,除非我們使用 GuC 提交。 在這種情況下,每個請求至少需要 2 個 dword,這給我們提供了最多 256 個排隊的請求。 希望這有足夠的空間來避免驅動程式上的反壓。 我們增加了接收緩衝區的大小(相對於傳送緩衝區)以確保 G2H 響應 CTB 具有著陸點。

除了提交之外,G2H 緩衝區還需要能夠容納足夠的空間來處理可恢復的頁面錯誤通知。 頁面錯誤的數量是中斷驅動的,並且可能與可用的計算資源數量一樣多。 但是,這些的大部分實際工作都在單獨的頁面錯誤工作執行緒中。 因此,我們只需要確保佇列有足夠的空間來處理所有的提交和響應,以及一個用於傳入頁面錯誤的額外緩衝區。

GuC 功耗節省 (PC)

GuC 功耗節省 (PC) 支援多種功能,以便在啟用 GuC 提交時,以最有效和效能最高的方式使用 GT,包括頻率管理、Render-C 狀態管理以及各種功率平衡演算法。

單迴圈功耗節省 (SLPC) 是 GuC 韌體中連線的功耗節省功能的套件的名稱。 韌體公開了一個程式設計介面,供主機控制 SLPC。

PCIe Gen5 限制

獨立顯示卡的預設鏈路速度由儲存在其快閃記憶體中的配置引數決定,這些引數可以透過使用者發起的韌體更新來覆蓋。 已經觀察到,配置為將 PCIe Gen5 作為其預設鏈路速度的裝置可能會遇到鏈路質量問題,這是由於主機或主機板的限制造成的,並且在 Gen5 下面臨不穩定鏈路時可能不得不將其鏈路自動降級為 PCIe Gen4 速度,這使得此類設定上的韌體更新相當冒險。 需要確保裝置能夠在推送將 PCIe Gen5 作為預設配置的韌體映像之前,將其鏈路自動降級為 PCIe Gen4 速度。 這可以透過讀取 auto_link_downgrade_capable sysfs 條目來完成,該條目將表示裝置是否能夠將其鏈路自動降級為 PCIe Gen4 速度,並帶有布林輸出值 01,分別表示 不具備能力具備能力

$ cat /sys/bus/pci/devices/<bdf>/auto_link_downgrade_capable

在自動鏈路降級不具備能力的裝置上推送將 PCIe Gen5 作為預設配置的韌體映像,並且由於主機或主機板的限制而面臨鏈路不穩定,可能會導致驅動程式無法繫結到該裝置,從而無法進行進一步的韌體更新,只能求助於 RMA 作為最後的手段。

自動鏈路降級具備能力的裝置的鏈路降級狀態可以透過 auto_link_downgrade_status sysfs 條目獲得,並帶有布林輸出值 01,其中 0 表示鏈路訓練期間不需要自動降級(這是最佳情況),而 1 表示該裝置由於 Gen5 鏈路不穩定而將其鏈路自動降級為 PCIe Gen4 速度。

$ cat /sys/bus/pci/devices/<bdf>/auto_link_downgrade_status

內部 API

待辦事項