PCIe Chapter 0:從系統全貌到第一次規格查詢
PCI Express(PCIe)讓主機與周邊裝置交換要求與資料。本章先定位系統角色,再沿設定空間的能力清單完成連線查詢,分別取得支援速率與目前結果。
完整中文教學與逐步圖解 · 課程路線 · English
裝置接上後,還要完成哪些工作?
Root Complex 把 CPU/記憶體子系統接到 I/O 階層;Root Port 對外建立 Link(相鄰兩端的連線),Switch 可以延伸連接路徑,Endpoint 提供裝置功能。Link(相鄰兩端的連線) 連接相鄰兩端,Lane 是構成 Link 的通道;x4 表示 4 個 Lane,不是 4 個裝置。
軟體辨識與設定的基本對象是 Function(可個別辨識與設定的功能)。一張卡可以有多個 Function(可個別辨識與設定的功能);本例用 0000:03:00.0 表示 Segment(匯流排的邏輯分組)、Bus、Device、Function,其中 Bus、Device、Function 常合稱 BDF(Bus、Device、Function 識別號)。Segment 是邏輯分組,不是額外的硬體元件;這組識別號也不是記憶體位址。
- BDF
- Bus/Device/Function,匯流排、裝置與功能識別
兩端硬體先具備建立 Link 的條件,系統軟體再發現 Function、配置資源,驅動程式則準備裝置的工作介面。這是理解依賴關係的教學整理,實際平台可能分階段處理。Firmware 3.3 §3.5 要求韌體設定開機與主控台裝置的完整路徑,以及所有 Host Bridge,卻不保證每個 Endpoint 都已配置完成。
| 目的 | 應找的資料 |
|---|---|
| 辨識 Function、查 PCIe 能力 | Configuration Space(設定空間)中的標頭與 Capability。 |
| 由 CPU 操作裝置介面 | BAR 所描述的資源及裝置暫存器;若經記憶體映射存取,稱為 MMIO(Memory-Mapped I/O,記憶體映射 I/O)。 |
| 由裝置搬移工作資料 | DMA(Direct Memory Access,直接記憶體存取)所用的緩衝區、裝置可用位址及存取條件。CPU 仍需先準備工作。 |
- BAR
- Base Address Register,基底位址暫存器
BAR 是設定空間中的 Base Address Register,不是資料緩衝區。能讀取設定空間,尚不足以證明 MMIO 或 DMA 已準備好。
- MMIO
- Memory-Mapped I/O,記憶體映射輸入輸出
- DMA
- Direct Memory Access,裝置直接存取記憶體
系統觀的規格位置
Base 6.0 §1.2–§1.4,pp.100–109(Figure 1-2:p.103);§2.1.1,pp.116–117;BAR:§7.5.1.2.1,pp.928–930。Firmware 3.3 §1.3,pp.8–9;§3.1–§3.2,pp.32–33;交接要求:§3.5,pp.34–35。
同一筆讀取,為什麼要分三層查?
接續前面的記憶體讀取:Endpoint 發出 Request,經過 Switch 到達目標,再等待 Completion(完成回覆)。Figure 1-4 把每個元件的收送功能分成三個邏輯層;Figure 1-5 則用封包流向說明各層如何接手。這是閱讀規格的分工,不要求硬體內部一定照圖切成三塊電路。
手機閱讀時,可左右滑動表格查看完整內容。
| 層 | 先問什麼? | 與案例的關係 |
|---|---|---|
| Transaction Layer(交易層) | 要求什麼、送到哪裡、回覆對應哪筆要求? | 建立與解讀 TLP(Transaction Layer Packet,交易層封包),並管理 TLP 的 Flow Control。 |
| Data Link Layer(資料鏈結層) | 這一條 Link 上的資料是否完整交付? | 處理逐 Link 的完整性、確認與重送;Switch 兩側各有獨立的 Link。 |
| Physical Layer(實體層) | 兩端如何建立 Link、使用哪些 Lane 傳輸? | 處理 Link 初始化、Lane 和訊號傳輸等工作。 |
分析時可以先沿這條路線:確認正在觀察哪一條 Link → 看實體連線及 Link 狀態 → 檢查該段傳輸與 Flow Control → 最後配對 Request 和 Completion。某段 Link 的傳輸成功,只能支持該段的結果;要確認整筆讀取,還要看回覆是否真的到達 Requester。
Figure 1-5 是分層概念圖;實際封包如何承載與保護,還要依 Non-Flit Mode 或 Flit Mode 查對應章節,不能把圖中每個傳輸細節直接套到所有模式。
相鄰層還要交換資料邊界、傳送握手、電源與 Link 狀態等資訊;哪些訊息在兩個介面之間傳遞,可接著查 §1.5.4.4。這些是邏輯服務,內部介面的具體實作不由這張分層圖決定。
Base 6.0 §1.5、Figures 1-4/1-5,pp.109–110;§§1.5.1–1.5.4.4,pp.110–114。此處的讀取與 Switch 路徑為教學情境。
要查支援速率,為什麼不能只讀目前速率?
先按查詢目的選欄位:能力描述支援範圍,控制描述相關設定,狀態描述目前結果。本次找到能力結構後,先讀本端支援集合,再查看連線目前的速率與寬度;控制上限留待後續連線章處理。
每個 Function 的 PCIe 設定空間為 4096 bytes。PCI Express Capability(描述或控制能力的結構) 位於前 256 bytes 的傳統 Capability(描述或控制能力的結構) 清單,不能因名稱含有 PCI Express,就跳去找 Extended Capability。(Base 6.0 §7.2/Figure 7-3,pp.905–906;§7.5.3,p.951。)
| 步驟 | 假設讀值與判讀 | Base 6.0 閱讀位置 |
|---|---|---|
| 辨識標頭 | 0x0E 讀 8 bits 得 0x00;0x00 & 0x7F = 0,採 Type 0。0x06 讀 16 bits 得 0x0010,Status bit 4 為 1。 | Figure 7-8/Table 7-7,pp.924–925;Figure 7-10,p.928;Figure 7-6/Table 7-5,pp.921–922。 |
| 找到清單入口 | 0x34 讀 8 bits 得 0x40。先遮掉低 2 bits:0x40 & 0xFC = 0x40。 | §7.5.1.1.11,p.926。 |
| 經過 PM Capability | 0x40 讀 16 bits 得 0x7001;低 byte 的 ID 為 0x01,高 byte 的 Next Pointer 為 0x70。 | Figure 7-18/Table 7-14,p.945。 |
| 找到 PCIe Capability | 0x70 讀 16 bits 得 0x0010;ID 為 0x10,Next Pointer 為 0。記下 cap_base = 0x70。 | Figure 7-22/Table 7-18,p.953。 |
| 確認版本與類型 | 0x72 讀 16 bits 得 0x0002;低 4 bits 為 Version 2,bits 7:4 為 0,表示 PCI Express Endpoint。 | Figure 7-23/Table 7-19,pp.953–954。 |
設定空間採小端序,所以 0x7001 的低位址 byte 是 0x01(Base 6.0 §7.5.1.1,p.916)。清單位置與順序可以改變;0x70 不能寫成通用常數。
若清單已結束卻沒找到目標,或讀取失敗,就不能繼續把某個位置當成該結構。讀不到資料也不等於已取得「不支援」的有效回覆。
Capability Version 2 不等於 PCIe Gen2,也不能單獨保證舊硬體實作了速率向量。本例已另列實作前提;採用 Base 6.0 解讀欄位,也不表示裝置必然支援 64 GT/s。舊硬體分支見 §7.5.3.18 的實作說明(p.1000)。
找到結構後,怎麼把讀值轉成答案?
先看 Figure 7-21(p.952),將欄位相對位移加到起點;接著先查能力的 Figure 7-38/Table 7-35(pp.998–1000),再回到狀態的 Figure 7-29/Table 7-26(pp.978–979)。順序由問題決定,圖用來定位,表格與條文用來判讀。每一步都要確認版本與適用對象,不能只從欄位名稱推測它的意義。
Link Capabilities 2:0x70 + 0x2C = 0x9C,讀 32 bits → 0x0180001E
Link Status :0x70 + 0x12 = 0x82,讀 16 bits → 0x0043
Supported Link Speeds Vector 在整個 Register 的 bits 7:1。先用遮罩保留,再右移成欄位值:
(0x0180001E & 0x000000FE) >> 1 = 0x0F
欄位內 bits 0–3 都為 1,分別表示支援 2.5、5、8、16 GT/s;bits 4–5 為 0,未宣告 32、64 GT/s;bit 6 為保留位元。欄位 bit 0 原本位於 Register bit 1,兩種編號不要混用。完整讀值保留 bits 23、24,是 Table 7-35 對支援 16 GT/s 以上裝置的偵測能力要求;它們不證明路徑中已有 Retimer。
Link Status 則使用編碼,不是另一個支援 bitmap:
Current Link Speed:0x0043 & 0x000F = 3
Negotiated Link Width:(0x0043 & 0x03F0) >> 4 = 4
代碼 3 對應速率向量的欄位 bit 2,也就是 8 GT/s;寬度 4 表示 x4。這些遮罩以表中讀取寬度為前提,不能直接套到不同位置的 32-bit 讀值。
Table 7-26 指出,Link 未建立時,這兩個欄位為 undefined。0x0043 本身不能證明 Link 已建立;也不能僅憑 bit 13 為 0 就認定 Link 中斷,因為該狀態位是否實作取決於回報能力(Table 7-23、Table 7-26,pp.969、979)。
目前只有 8 GT/s,可以認定裝置有問題嗎?
Figure 7-21(p.952)先提供相對位置。找到能力欄位後,讀 Figure 7-38/Table 7-35(pp.998–1000)解釋速率向量;再用 Figure 7-29/Table 7-26(pp.978–979)讀目前速率與寬度。每一步都連同表格的編碼、版本及適用條件判讀。
換一個條件,原來的判斷還成立嗎?
完整查詢先選 Function、沿清單找結構,再核對版本與類型,分別解碼能力及狀態。下面沿用這條路徑,只更動一項條件,說明需要重新確認的位置。
Capability 起點改為 0x90,還能到 0x9C 查能力嗎?
不能。依 Figure 7-21(p.952),Link Capabilities 2 應為 0x90 + 0x2C = 0xBC,Link Status 為 0x90 + 0x12 = 0xA2。起點是新教學假設,相對位移不變。
Current Link Speed 為 4,是同時支援兩種速率嗎?
不是。有效的 Link 狀態下,編碼 4 表示目前為 16 GT/s。支援集合仍須另外查向量。(Table 7-26、Table 7-35,pp.978、998。)
Link 已中斷,手上仍有 0x0043 這筆讀值,能報成目前 8 GT/s、x4 嗎?
不能。Table 7-26(p.978)將 Link 未建立時的速率與寬度定為 undefined;看似合理的數字不能取代有效條件。
下一步先釐清拓樸、Function 與識別範圍,再深入設定空間。逐步欄位圖、完整案例與來源整理,見Chapter 0 中文教學;Chapter 1 已可閱讀,Chapter 2–13 已完成,Chapter 14–19 仍在規劃中。


Comments