PCIe Chapter 5:一次讀寫如何變成 PCIe 交易

【模擬資料】本章封包欄位與讀值為教學用途建立,不代表特定硬體或平台。

先看本章的角色與路徑

主機端提出讀取,裝置端回覆資料,主機端再依交易識別與完成資訊配對。主機端提出讀取,裝置端回覆資料,主機端再依交易識別與完成資訊配對。主機端 Requester:提出讀取裝置端 Completer:提供資料Memory Read Request →← Completion with Data依 Requester ID/Tag 配對檢查狀態、資料量及位址範圍

作者依 Base 6.0 的 Request/Completion 規則繪製的交換示意;分段回覆在正文另行放大。

一次 MMIO(Memory-Mapped I/O,記憶體映射輸入輸出)讀取,會由主機端提出要求,再由目標端回覆資料。PCIe 用 TLP(Transaction Layer Packet,交易層封包)承載這些交換。

前情提要:Chapter 4 已完成本例的 BAR、Bridge Window 與解碼配置。現在沿同一路徑觀察一筆 4-byte 讀取。

BAR
Base Address Register,基底位址暫存器

規格路線:交易類別 Table 2-1 → Request 的 ID/Tag 與 Memory Request 格式 → Completion 格式 → 分段與邊界條件。

位址配置完成後,還要理解一次存取如何形成 Request,以及 Completion 如何回到要求者。本章以一筆 MMIO 讀取串起路由、交易配對、長度與位元組範圍,接著用分段回覆說明「一筆要求」為何不一定只有一個回覆。

MMIO
Memory-Mapped I/O,記憶體映射輸入輸出

完整中文教學 · 課程路線 · English

先辨認交易,再決定要等待什麼

Transaction Layer Packet(TLP)承載交易。Requester 提出要求,Completer 服務目標;這些角色隨交易改變。Memory Request 依位址送往目標,Completion 則依原 Requester ID 回送。Requester ID 與 Tag 配對尚待完成的交易,同一 Requester 不得讓兩筆同時未完成、需要 Completion 的要求共用 Tag。Base 6.0 另有較大 Tag 的能力與啟用條件,不能把它永遠視為 8 bits。

常見交易與成功回覆
交易要求分類成功回覆
Memory ReadNon-Posted一個或多個 CplD。
一般 Memory WritePosted沒有普通 Completion。
Configuration/I/O ReadNon-PostedCplD。
Configuration/I/O WriteNon-PostedCpl。
Message RequestPosted沒有交易層 Completion;上層可能另定回應。

Configuration 依 ID 路由;I/O 依 I/O 位址;Message 依其規定採位址、ID 或隱含路由。普通 MWr 沒收到 Completion 不構成重送理由,也不代表裝置工作已完成;工作結果仍依裝置介面判斷。

來源與閱讀順序

Base 6.0 Table 2-1(pp.116–117)、Table 2-3(pp.120–122)、Figures 2-27/2-28(pp.152–154);§2.2.7.1(pp.162–165)、§2.2.8(pp.170–171)與 Table 2-42(pp.222–223)。

把 4-byte 讀取對到封包欄位

假設平台以 Requester ID=0x0000、Tag=0x12,讀取裝置 0x80004120 的 4 bytes。這個 Requester ID 是平台假設,不能由 Root Port BDF 直接推定。MRd 使用 Fmt=000b、Type=00000b、Length=1 DW、First BE=1111b、Last BE=0000b;Request 本身沒有資料 Payload。3 DW Header 的選擇來自本例的 32-bit 目標位址格式,不是因為資料剛好是 32 bits。

BDF
Bus/Device/Function,匯流排、裝置與功能識別
DW
Double Word,4 bytes的資料單位

成功 CplD 使用 Fmt=010b、Type=01010b,保留原 Requester ID/Tag,Completer ID=0x0300。Length=1 DW、Status=SC、Byte Count=4,Lower Address=0x20。若四個有效 bytes 為 78 56 34 12,且本例 Register 定義為 little-endian,值為 0x12345678。

若另讀取 0x80004121–0x80004126 的 6 bytes,並假設裝置允許該存取,Request 要用對齊位址 0x80004120、Length=2、First BE=1110b、Last BE=0111b。成功回覆 Payload 占 2 DW,但有效資料只有 6 bytes;Byte Count=6、Lower Address=0x21。未啟用的 non-Prefetchable bytes 不得在 Completer 被讀取。

欄位定位

Figure 2-31(p.163)→ Figure 2-26/Table 2-10(pp.150–151)→ Figure 2-73(p.196)→ Tables 2-37、2-40、2-41(pp.197、217–218)。Length 的單位與零編碼見 Table 2-4(p.122):適用的資料交易中,0 表示 1024 DW。

Byte Count 不一定等於這個回覆的 Payload

另假設 Endpoint 從有效 DMA 位址 0x40001000 讀 256 bytes,Requester ID=0x0300、Tag=0x13,BME 與映射都已準備好。Requester 的最大讀取要求為 512 bytes;Completer 的有效 Payload 上限及 RCB 都為 128 bytes,路徑接收能力相容。這筆 Length=64 DW 的要求,可按下表回覆:

DMA
Direct Memory Access,裝置直接存取記憶體
作者推演的兩段成功回覆
資料範圍LengthByte CountLower Address
0x40001000–0x4000107F32 DW256 bytes0x00
0x40001080–0x400010FF32 DW128 bytes0x00

兩個回覆皆為 SC、BCM=0,並保留相同的 Requester ID/Tag。Byte Count 包含目前片段及後續尚待回傳的資料。同一要求的回覆按位址遞增;不同 Transaction ID 的回覆可交換順序,也不得合併成一個 Completion。

另一項獨立限制是 Memory Request 不得跨 4 KiB:從 0x40001FF0 讀 32 bytes 會到 0x4000200F,必須拆成兩筆各 16 bytes 的要求。接收端可以選擇檢查跨界;若已實作的檢查發現違規,便視為 Malformed TLP(格式錯誤的封包)。沒有錯誤紀錄不代表原要求一定合法。這是 Non-Flit Mode 的一般 Memory Read;AtomicOp 的對齊另見 Chapter 15。

若讀取回覆失敗,Cpl 不帶有效讀取資料並終止該要求;UR/CA 不能當成讀到零,RRS 也不是 MMIO 的通用重試結果。

切分與邊界來源

§2.2.7.1(pp.162–163);§2.3.1.1(pp.214–218);§2.4.1 D5a/D5b(p.224)與 §2.4.2(p.228)。RCB 限制回覆切分位置,4 KiB 規則限制 Request,兩者不同。

兩個裝置用了相同 Tag,回覆要怎麼分?

先把每個 Completion 的 Requester ID(原要求者識別號)和 Tag(要求者分配的交易標籤)一起對回原始 Request,再用 Status、Length、Byte Count 和 Lower Address 檢查資料範圍。完成分組後,才知道哪筆讀取還缺哪些資料。

規格閱讀順序:Figure 2-28 先建立 Transaction ID;Figure 2-73 找到 Completion 的 Requester ID、Tag、Status、Byte Count 和 Lower Address,再讀 §2.3.1.1 的 Byte Count 與遞增位址規則。不同 Transaction ID 的 Completion 允許互相超越,不表示一定會重新排序。核對完整封包時還要確認 Completer ID、TC、Attributes、資料長度與適用條件。(Base 6.0,文件頁/PDF 頁 153、196–198、215、218、224。)

TC
Traffic Class,流量類別

Tag 位數變大後,可以任意選數值嗎?

先回到 Figure 2-28:Requester ID 與 Tag 一起識別未完成的交易;在同一個 PCIe Hierarchy(階層)中,同一個 Requester ID 的未完成 Non-Posted Requests,不論 Traffic Class,都必須使用不同的 Tag。現在要擴大可用範圍時,還需要把 Requester 設定、完成端能力與中間路徑一起帶入 Table 2-11。Flit Mode 的跨 Hierarchy Segment 識別另有規則,本例不展開。

表格左邊三欄依序是 14-Bit Tag Requester Enable、10-Bit Tag Requester Enable 和 Extended Tag Field Enable;右邊依完成端及路徑共同支援的最大 Tag 能力分欄。先確認 Requester 本身支援並允許使用該能力,再選正確欄位。Enable=1 不是完成端支援能力的證明,也不是一定會同時送出該數量的要求。

【模擬資料】以下資料為教學用途建立,不代表特定硬體或平台。下列兩列是互不相依的設定;Requester、目標及中間路徑均已確認支援表中使用的能力,且未使用 VF 或 Phantom Function。第二列中使用 14-bit Tag 的路徑均以 Flit Mode 傳送。

VF
Virtual Function,虛擬功能

手機閱讀時,表格可以左右滑動。

14-bit/10-bit/Extended Enable8-bit 完成端/路徑10-bit 完成端/路徑14-bit 完成端/路徑
0/1/10–255256–1023256–1023
1/1/00–31256–10231024–16383

例如第一列如果目的端與路徑共同支援 10-bit Tag,Table 2-11 的可用範圍從 256 開始;不能把它讀成「任何小於 1024 的 Tag 都屬於這個 10-bit 範圍」。同一列若目的端和路徑只支援 8-bit,則使用 0–255。5-bit 完成端/路徑的範圍恆為 0–31。

查設定時,Extended Tag Field Enable 在 PCI Express Capability 的 Device Control;10-Bit Tag Requester Enable 在 Device Control 2;14-Bit Tag Requester Enable 則在 Device 3 Extended Capability 的 Device Control 3。應先走訪對應 Capability,再查各欄位的適用條件;VF 另有 PF 的控制規則。軟體若在 Function 尚有未完成 Non-Posted Requests 時修改 10-bit 或 14-bit Requester Enable,結果為 undefined(未定義)。

VF
Virtual Function,虛擬功能
PF
Physical Function,實體功能

若同時向較大與較小 Tag 能力的目標發送要求,還須依 Table 2-11 使用各自範圍,並避免較大 Tag 因不支援的完成端截斷而與仍未完成的小 Tag 混淆。發送前確認完整路徑,比等到 Completion 的 Tag 異常後再推測更容易定位問題。

PCI Express Base 6.0 §2.2.6.2、Figure 2-28/Table 2-11,文件頁/PDF 頁 153–156;§7.5.3.4、Table 7-21,p.960;§7.5.3.15–§7.5.3.16、Tables 7-33–7-34,pp.991、997;§7.7.9.2–§7.7.9.3、Tables 7-108–7-109,pp.1073、1075。

同時使用大小 Tag,為什麼還要檢查低位元?

前一節的範圍是發送要求前的選擇。§2.2.6.2 還要求:若 Requester 同時向較大與較小 Tag 能力的目標發送要求,即使某筆較大 Tag 要求意外由不具足夠能力的完成端回覆,也要避免它與仍未完成的小 Tag 交易混淆。

【模擬資料】以下資料為教學用途建立,不代表特定硬體或平台。同一 Requester ID 有兩筆尚未完成的 Read:送往它認為支援 10-bit 的路徑 A 的 Tag 是 100h,送往 8-bit 路徑 B 的 Tag 是 00h。A 的完整路徑能力尚未核實。兩個原始 Tag 不同,但低 8 bits 都是 00h。

假設 A 的要求途中出錯,某個不具 10-bit Completer 能力的元件代為回覆,且這次回覆遺失了 Tag 高位,因而帶回 00h。若 Requester 只依這個回覆的 Requester ID 與低位 Tag 配對,就可能把 A 的異常回覆誤認成 B 的結果。這是教學假設,不表示每個中間元件都會以相同方式截斷 Tag。

Base 6.0 p.159 的 Using Larger Tags and Smaller Tags Concurrently Implementation Note 提供一種配置方式:假設小 Tag 只使用低 8 bits 中的 00h–0Fh,則較大的 10-bit Tag 不使用低 8 bits 為 00h–0Fh 的值。這 16 個低位值各對應三個合法的 10-bit 高位組合,原本 768 個 10-bit 值因此少了 48 個,剩下 720 個;小 Tag 還有 16 個。

這是規格提供的一種實作方法,不要求所有 Requester 都用同一種切分。規格要求的是避免上述混淆;實際可同時追蹤的交易數還受裝置資源及路徑條件限制。前一節的 Table 2-11 仍要先用來判斷每筆要求允許使用的 Tag 範圍。

PCI Express Base 6.0 §2.2.6.2,文件頁/PDF 頁 154–155;Implementation Note: Using Larger Tags and Smaller Tags Concurrently,p.159;Table 2-11,pp.155–156。

跨 Hierarchy 的讀取,Completion 要回到哪裡?

前面的例子在同一個 PCIe Hierarchy(階層)內用 Requester ID 與 Tag 配對。Flit Mode 跨 Hierarchy 時,還要先看 Segment:它幫助路徑辨認封包屬於哪個階層,再由 Requester ID 找到要求者。Chapter 3 的 Segment 捕捉例子先說明 Function 如何取得自己的 Segment。

【模擬資料】以下資料為教學用途建立,不代表特定硬體或平台。Endpoint A 在 Segment 02h,Endpoint B 在 Segment 03h;兩端 Segment Captured 均為 1。A 對 B 發出 Non-Posted Memory Read。假設沿途皆為 Flit Mode,位址路由及平台的 Peer-to-Peer 支援已確認,Root Complex(RC)這次不接手交易。A 的 Request 攜帶 OHC-C,Requester Segment 為 02h,Requester Segment Valid(RSV)為 1。

Request 依位址到達 B。B 比較 Requester Segment 02h 與自己捕捉的 Segment 03h:兩者不同,所以該 Request 的每個 Completion 都必須包含 OHC-A5。假設其中一個 Completion 的 Status 為 Successful,Lower Address 低兩位為 00b;依 Figure 2-11,OHC-A5 的四個 bytes 是:

OHC-A5:依 byte 順序解讀
Byte模擬值意義
002hDestination Segment:返回 A 所在的階層。
103hCompleter Segment:B 捕捉的 Segment。
280hDestination Segment Valid(DSV)為 1,其餘 Reserved 位元為 0。
300hLower Address 低兩位與 Successful Completion Status 都為 0。

也就是 02 03 80 00。回程經過 RC 時,Destination Segment 指向 A 的階層;到達要求者後,仍要用 Requester ID 和 Tag 對回原始交易,再檢查 Completion Status 和資料範圍。Requester 不得以收到的 Completion 的 Destination Segment 作為接收條件。

這個例子有兩個重要前提。第一,對非 IDE Memory Request,Requester 是否帶入 Requester Segment 可以是可選的;若 B 收到的 Non-Posted Memory Request 沒有 Requester Segment,B 在有 OHC-A5 的回覆中須將 DSV 清為 0、Destination Segment 設為 00h。第二,RC 接手交易時有另一套識別與還原規則;不要把本例「不接手」的結果直接套到所有路徑。

IDE
Integrity and Data Encryption,完整性與資料加密

閱讀時先看 §2.2.1.2 的 Figure 2-13 找到 Request 的 Requester Segment 與 RSV,再讀同節的 Requester、Completer 及 RC 規則,最後用 Figure 2-11 對照 Completion 的 OHC-A5。§2.2.9.2 補充哪些 Completion 條件需要 OHC-A5。還要分別確認觀察點、路徑模式、Segment Captured 與 RC 是否接手;單看封包內的 Segment 值無法確認整筆交易成功。

PCI Express Base Specification Revision 6.0,§2.2.1.2、Figures 2-11、2-13,文件頁/PDF 頁 133–134、138–141;§2.2.9.2,p.199。

用兩個問題確認理解

第一個回覆帶 128 bytes,Byte Count=256,是錯誤嗎?

不是。它還包含這筆要求後續的 128 bytes;本片段大小另由 Length 表示。

只看到 Base 6.0,就能套 Figure 2-31 解所有封包嗎?

不能。本章選用 Non-Flit Mode;Flit Mode 的 Header 定義在 §2.2.1.2,布局不同。

下一章將從合法交易進一步檢查 DMA 位址與資料可見性。所有來源頁碼均為 Base 6.0 的文件/PDF 頁碼,查核日期為 2026-10-28。

Jia-Chang

Jia-Chang

Human

Comments

  Write a comment ...