從設定表走到一次中斷通知
選擇步驟後,圖中對應的元件與下方解說會加上重點標示。完整圖與所有解說會持續顯示;也可用方向鍵切換步驟。
圖由上往下表示本例的先後順序。系統先準備通知路徑,裝置再開始產生事件。
- MSI-X
- Message Signaled Interrupts Extension,表格式訊息中斷
本章使用 MSI-X 中斷通知機制,把裝置的事件送到系統軟體。主線是找到設定表、填入通知目標、開放通知,再追蹤事件發生後的傳送。遮罩期間的待送通知與資料順序,會在主線之後說明。
- MSI-X
- Message Signaled Interrupts Extension,表格式訊息中斷
必要前情:Chapter 2 已找到本例的 Capability(能力與控制結構),Chapter 4 已配置 BAR0(描述裝置記憶體區域的基底位址暫存器)。本章接著使用這兩個位置,建立中斷路徑。
規格閱讀路線:Figure 7-56 找結構 → Figures 7-60–7-62 看容量、控制與表格位置 → Figure 7-57 看通知項目 → §6.1.4.5 看遮罩與待送事件。下文會在每一步指出本次使用的欄位。
找到設定表
沿用 Chapter 2 已找到的能力結構,以及 Chapter 4 已配置的裝置記憶體範圍。
系統從 MSI-X的能力結構找到中斷設定表。先讀 Figure 7-56 的 Table 欄位,再以 Figures 7-61/7-62 的 BAR(基底位址暫存器)的選擇值與位移,定位裝置記憶體中的設定表和待送通知位元。
- BAR
- Base Address Register,基底位址暫存器
Base 6.0 Figure 7-56(p.1018)、Tables 7-50/7-51(pp.1023–1024)。
在遮罩下填入目標
本例事件來源尚未啟動;通知接收資源已配置,其他項目維持遮罩。
系統軟體保持通知遮罩,再依 Figure 7-57 填入第 3 號項目的目的位址與資料。平台會提供這組值,裝置稍後用它發出通知。
Base 6.0 Figure 7-57(p.1019)、§6.1.4.2(pp.662–663)。
啟用通知路徑
所有必要設定就緒後,才依裝置介面啟動工作。
系統確認設定已依平台規則生效,啟用中斷機制,再解除第 3 號項目與整個 Function(可獨立設定的功能單位)的遮罩。Table 7-49 說明全域控制,Table 7-55 說明單一項目的遮罩。
Base 6.0 Tables 7-49/7-55(pp.1022、1026)、§6.1.4.5(pp.664–665)。
由裝置發出通知
本例已啟用中斷,兩層遮罩都已解除,裝置與平台間的通知路徑可用。
事件發生後,裝置讀取設定表中的位址與資料,發出記憶體寫入。中斷處理常式接著依裝置介面找出待處理工作;裝置介面也負責提供事件內容與數量。
Base 6.0 §6.1.4.4、§6.1.4.6–§6.1.4.7(pp.664–667)。
圖中元件
系統軟體
在設定階段配置接收資源、填入通知目標並管理控制欄位。
基本責任
系統軟體管理中斷資源;裝置驅動程式透過系統介面協調通知。
裝置 03:00.0
保存設定表,依事件與遮罩狀態決定何時發出通知。
基本責任
本例的 Endpoint 是 PCIe 階層末端的裝置;03:00.0 表示這次使用的功能單位。
平台中斷接收端
接收裝置送來的中斷寫入,讓軟體處理通知。
基本責任
通知目的位址與資料由平台配置;其編碼須依平台規格解讀。
1. 先認識三種中斷通知方式
MSI(Message Signaled Interrupts,訊息式中斷)將資料寫到平台指定的位址;本章主線的擴充機制另外提供逐項設定表。INTx 是傳統電位式中斷的相容介面,PCIe 用訊息模擬其有效與解除狀態。
| 機制 | PCIe 上如何通知 | 設定與判讀重點 |
|---|---|---|
| INTx emulation(電位式中斷模擬) | 使用 Assert_INTx/Deassert_INTx Message 模擬電位式中斷。 | PCI 相容機制;不是 PCIe Link 上另外拉一條傳統 INTx 訊號線。 |
| MSI(訊息式中斷) | 將系統指定的資料寫到指定的位址。 | Capability ID=0x05;Address/Data 與控制欄位位於設定空間。 |
| MSI-X | 同樣發出 DWORD(4 bytes)的記憶體寫入。 | Capability ID=0x11;每個 entry 的 Address/Data 位於 Memory Space 的 Table。 |
- MSI
- Message Signaled Interrupt,訊息中斷
MSI/MSI-X 使用 Memory Write(MWr,記憶體寫入)這一種 TLP(Transaction Layer Packet,交易層封包),依位址路由,並受 BME(裝置發送許可)控制。它屬於 Posted Request(發出後沒有一般交易回覆的請求),因此沒有對應的 Completion(完成回覆)。INTx 的有效與解除通知則使用 Message TLP(訊息類交易封包),對應表中的 Assert_INTx/Deassert_INTx。
如果 Function 能產生中斷,Base 6.0 要求支援 MSI、MSI-X 或兩者;INTx 相容機制可以不實作。一個 Function 可以同時具有 MSI 與 MSI-X Capability,但系統不得同時啟用兩者;啟用 MSI 或 MSI-X 時,也不得改用 INTx 要求服務。運作中任意切換機制可能遺失或重複事件。
機制與互斥條件來源
§6.1–§6.1.4(pp.659–661)、§6.1.4.3–§6.1.4.4(pp.663–664)。Capability ID 見 Table 7-40(p.1013)、Table 7-48(p.1022)。MSI/MSI-X 的 Memory Write 格式也見 §2.2.7.1.1 前的說明(p.166)。
2. MSI 對照:先選布局,再看向量數量
這一節使用獨立的 MSI 對照案例,說明另一種通知設定方式。主線 Function(可獨立設定的功能單位)仍使用前述的 MSI-X。先找到 ID=0x05,再看相對位移 +0x02 的 Message Control。假設讀到 0x0184:
| 欄位 | 解碼 | 對後續閱讀的影響 |
|---|---|---|
| Multiple Message Capable(MMC,可要求的向量數),bits 3:1 | 010b:要求 4 個向量 | 以 2 的冪次編碼,010b 對應 4 個。 |
| Multiple Message Enable(MME,已配置的向量數),bits 6:4;MSI Enable,bit 0 | 000b;0 | Enable=0 表示通知尚未啟用;MME 的單向量編碼只描述數量。 |
| 64-bit Address Capable,bit 7;Per-Vector Masking(PVM,個別向量遮罩)Capable,bit 8 | 兩者都為 1 | 依 Figure 7-47 閱讀 64-bit Address 加 Per-Vector Masking 的布局。 |
| Extended Message Data Capable,bit 9 | 0 | 本例不使用 Base 6.0 的 Extended Message Data。 |
系統若只配置 2 個向量,可在 MSI 關閉時把 MME(已配置的向量數)設為 001b,完成 Address、Data 與遮罩設定後再啟用;配置數量不得超過能力。MSI 最多支援 32 個向量,且使用 2 的冪次編碼。MSI-X 的 Table Size(設定表容量)使用 N−1 編碼,下一節會帶讀。
MSI 的四種布局取決於 32/64-bit Address 與是否支援 PVM(個別向量遮罩)。普通 PCI Express Endpoint 若實作 MSI,必須支援 64-bit Message Address(訊息目的位址)。Legacy Endpoint 的地址能力規則另有規定。MSI Message Control 的 RW(可讀寫)欄位由系統軟體管理,裝置驅動程式不能直接修改;本章的「配置」是指這個系統軟體流程。
MSI 的查詢路線
先讀 Figures 7-44–7-47(pp.1011–1012),依能力選布局,再讀 Figure 7-49/Table 7-41(pp.1013–1014)解碼控制。向量配置與 Endpoint 地址能力見 §6.1.4–§6.1.4.1(pp.661–662)。本節只比較必要欄位,以下完整案例使用 MSI-X。
3. 找到 MSI-X Capability 後,怎麼走到 Table?
回到 03:00.0。Chapter 2 已用傳統 Capability 清單找到 0xD0,這裡直接從該處往下讀,不重走清單。Figure 7-56 告訴我們:Control 在 +0x02,Table 定位值在 +0x04,PBA(Pending Bit Array,待送通知位元陣列)定位值在 +0x08。
| Function 內位移 | 寬度 | 假設讀值 | 欄位 |
|---|---|---|---|
| 0xD0 | 16 bits | 0x0011 | ID=0x11,Next=0。 |
| 0xD2 | 16 bits | 0x0007 | Table Size(設定表容量)編碼 7;MSI-X Enable 與 Function Mask 都為 0。 |
| 0xD4 | 32 bits | 0x00002000 | Table Offset/Table BIR(BAR 選擇值)。 |
| 0xD8 | 32 bits | 0x00003000 | PBA(待送通知位元陣列)Offset/PBA BIR(BAR 選擇值)。 |
- BAR
- Base Address Register,基底位址暫存器
先看 Tables 7-50/7-51:BAR Indicator Register(BIR,BAR 選擇值)占低 3 bits,其餘 bits 保存 byte 位移。本例兩個 BIR(BAR 選擇值)都是零,因此都選 BAR0。遮掉低 3 bits 後,將位移直接加到 BAR0 基底,就得到表格位置。
N = (0x0007 & 0x07FF) + 1 = 8
Table BIR = 0x00002000 & 0x7 = 0
Table offset = 0x00002000 & 0xFFFFFFF8 = 0x2000
Table base = 0x80004000 + 0x2000 = 0x80006000
PBA base = 0x80004000 + (0x00003000 & 0xFFFFFFF8) = 0x80007000
8 個 entries 各占 16 bytes,因此 Table 使用 0x80006000–0x8000607F。待送通知陣列每個 entry(設定項目)對應 1 bit,按 QWORD(8 bytes)組織;8 個 entries 需要 1 個 8-byte QWORD,位於 0x80007000–0x80007007。兩者都落在 BAR0 內,也沒有重疊。
此外,Table/PBA 與不屬於 MSI-X 的其他可用 Register 不得共用同一個自然對齊 4 KiB 範圍。本例將一般 Register 放在 BAR0 的第一頁、Table 放在第三頁、PBA 放在第四頁,因此 Chapter 5 的 BAR0+0x120 不會混入 MSI-X 所在的頁面。這項內部分布是本例另外指定的配置。
從 Capability 到 BAR 的閱讀路線
Figure 7-56(p.1018)定位三組欄位;Figure 7-60/Table 7-49(p.1022)解 Table Size、Mask、Enable;Figures 7-61/7-62、Tables 7-50/7-51(pp.1023–1024)解 BIR 與 Offset。若選到 64-bit BAR,BIR 必須指向低 DWORD。Table/PBA 大小、對齊與頁面隔離見 §7.7.2(pp.1018–1021)。
4. 從 entry 3 取得通知目標
Table entry(設定表中的一個項目)位於裝置的記憶體區域,供系統軟體填寫通知設定。裝置發出通知時,會使用其中的 Message Address(訊息目的位址)寫入平台接收端。下圖將設定位置與通知目的地分別畫出。
Entry 從零編號,所以 entry 3 是第四個。由 Equation 7-1 得到 0x80006000 + 3 × 16 = 0x80006030。依 Figure 7-57 的四個 DWORD(各 4 bytes),再逐一找到:
| PCI Memory 位址 | Entry 內位移/欄位 | 假設設定 |
|---|---|---|
| 0x80006030 | +0x00,Message Address | 0xFEE01000 |
| 0x80006034 | +0x04,Message Upper Address | 0x00000000 |
| 0x80006038 | +0x08,Message Data | 0x00000045 |
| 0x8000603C | +0x0C,Vector Control | 初始讀回 0x00000001;保留其他 bits,只在適當時機清除 bit 0。 |
這組 Message Address/Data 假設由平台中斷配置機制提供,且已能正確導向接收端。0x45 是本例寫入的 Message Data(訊息資料),其平台編碼須查平台規格;Table 中的項目編號仍是 3。
發送時,裝置向 0xFEE01000 送出 1 DW(4 bytes)的 MWr(記憶體寫入),Payload(承載資料)為 0x00000045,四個 bytes 都啟用。MSI-X 不會自行修改 Message Data 的低位元。此例的 Upper Address 為零,因此使用 32-bit 目的位址格式;Relaxed Ordering(RO,放寬排序)與 No Snoop(免除一致性窺探提示)必須為零,IDO(依識別碼放寬排序)本例也設為零。
- DW
- Double Word,4 bytes的資料單位
Entry 與訊息欄位來源
Figure 7-57(p.1019)、Equation 7-1(p.1021);Figures 7-63–7-66/Tables 7-52–7-55(pp.1024–1026)。Message Address 低 2 bits 必須寫零。傳送方式見 §6.1.4.4(p.664);RO/No Snoop 與 TC 條件見 §6.1.4(p.661)。MSI-X Message Address 的讀取結果未定義,不能把它當作一般可讀 Register(p.1019)。
5. 先準備通知目標,再開放事件
系統先保持遮罩,填好有效目標並確認設定生效,最後開放通知。以下是作者選擇的一種初始化安排;規格也容許符合相同條件的其他安排。假設裝置尚未產生活動事件,系統已配置中斷接收資源,其他 entries 保持遮罩;MSI-X Table/PBA 的 Memory 存取及中斷上行路徑都已準備好。
| 步驟 | 系統與裝置的狀態 | 原因 |
|---|---|---|
| 1. 保持遮罩 | 系統軟體將 Function Mask 設為 1,MSI-X 仍關閉;Message Control 讀回 0x4007。 | Table Size 的 7 是唯讀欄位的讀值;此處只改可寫控制位元。 |
| 2. 填 entry | entry 3 的 Mask=1 時,填入 Address、Upper Address 與 Data,保留 Vector Control 其他 bits。 | 不得在 entry 未遮罩時修改 Address/Data/適用的 Steering Tag。 |
| 3. 啟用並確認設定可見 | 系統軟體啟用 MSI-X,保持 Function Mask=1;Control 讀回 0xC007。 | MSI 必須關閉;並由平台 I/O 存取規則確保 Table 更新已按要求生效。 |
| 4. 開放此 entry | 清 entry 3 的 Mask bit,再清 Function Mask;Control 讀回 0x8007。 | 只有配置好的 entry 3 開放,其餘 entries 仍保持各自的 Mask。 |
| 5. 允許裝置開始工作 | 依裝置介面啟動工作及事件來源。 | 避免在通知路徑尚未準備好時產生活動事件。 |
Message Control 的 RW(可讀寫)欄位由系統軟體管理,規格不允許裝置驅動程式直接修改這些欄位;驅動程式應透過系統提供的介面協調。設定 Table/PBA 時,軟體必須使用對齊的完整 DWORD 或 QWORD 存取,不能以 byte 存取代替。若要遮罩原本未遮罩的 entry,不能同時用一個 QWORD 更新 Message Data 與 Vector Control,因為 Data 可能先改變;應先按規定以 DWORD 寫入 Mask。
Function Mask=1 時,即使 entry 的 Mask=0,仍不得送出該訊息。清除 Function Mask 也不會把每個 entry 的 Mask bit 一起清零。因此,開放通知時要分別確認 Function Mask(整個功能的遮罩)和 entry Mask(單一項目的遮罩)。
初始化安排使用的規格條件
§6.1.4.2–§6.1.4.5(pp.662–664);QWORD 更新限制見 p.663 的 Implementation Note;Table 7-49 與系統軟體權限見 p.1022;Memory 存取寬度與對齊見 p.1020;Reserved/Steering Tag 保存條件見 Table 7-55(p.1026)。本表假設適用的 I/O 同步已完成,不把程式書寫順序當成硬體可見性證據。
6. 遮罩期間的事件,如何留待通知?
Pending bit(待送位元)記錄該項目是否有訊息待送;事件數量由裝置的事件佇列或狀態保存。假設 MSI-X 已啟用、Function Mask=0,而 entry 3 的 Mask=1;在這段期間,裝置發生了本來應透過 entry 3 通知的事件。裝置不得送該訊息,必須將對應 Pending bit 設為 1。
依 Equation 7-2,entry 3 對應 PBA 的 QWORD 0、bit 3。本例若其他 bits 都為零,讀到的 QWORD 是 0x0000000000000008。再發生兩次相同通知需求,Pending bit(待送位元)仍可維持 1,因此整個值仍可能是 8。軟體要查看裝置自己的事件佇列或狀態,才知道待處理工作的數量。
| 後續條件 | 裝置應如何處理 |
|---|---|
| 事件仍待處理;軟體解除有效遮罩 | 裝置必須安排送出訊息,送出後清除 Pending bit。不是保證解除遮罩的當下 CPU 已進入處理常式。 |
| 仍在遮罩期間,但底層事件已依裝置介面被處理 | 裝置必須清除 Pending,避免稍後解除遮罩時送出不必要的訊息;若又發生新事件,再重新設 Pending。 |
Pending bits 由裝置依事件狀態更新。規格建議軟體只讀、不寫;寫入的結果未定義。RW1C(寫入 1 清除)的方式不適用於這些位元。訊息送出後 PBA 可先清零,CPU 的處理常式則可能稍後才執行。
Pending 與服務次數來源
Figure 7-58(p.1019)、Equation 7-2/7-3(p.1021)、Figure 7-67/Table 7-56(pp.1026–1027)。遮罩、事件已滿足與清除 Pending 的條件:§6.1.4.5(p.664)。同一向量重複傳送不保證每個訊息都各自獲得服務,需配合裝置與驅動程式交握:§6.1.4.6(pp.665–666)。
7. 資料寫入如何接上中斷通知?
本例讓同一 Function 的資料寫入與 MSI-X 都使用 TC0(同一流量類別)。中斷寫入是 Posted Request(沒有一般完成回覆的請求),且 RO(放寬排序)必須為零;適用的排序規則不允許它越過該 Function 先前送出的 Posted 寫入。§6.1.4.7 進一步要求系統保證:由該訊息引發的中斷處理常式,能觀察到先於該訊息到達的 Posted 更新。因此,不必為了沖出這些先前寫入,額外讀一次裝置 Register。
使用資料時仍須滿足 Chapter 6 的映射與同步前提。處理常式依裝置介面找出完成項目,再存取對應資料。若資料與中斷使用不同 TC,裝置必須另外確保同步。
- TC
- Traffic Class,流量類別
訊息接收順序也不保證處理常式的執行順序。若裝置一定要先服務事件 A 才能服務 B,就需要相應交握,不能只以先送 A、後送 B 達成。MSI/MSI-X 本身也不保證固定的中斷延遲。
通知與資料順序的適用範圍
§6.1.4 的跨 TC 同步說明與屬性限制(p.661);§6.1.4.7(p.667)規定資料可見性、接收端獨立處理與服務順序;延遲不保證見 §6.1.4(p.660)。若多個 entries 共用同一向量,仍可能需要讀裝置狀態辨識事件來源;那是辨識用途,不是前述資料一致性的 flush。
8. 沿同一個事件再走一次
第 3 號項目要發出通知,系統先準備哪些內容?
先由 Figure 7-56 找設定表,再按 Figure 7-57 填入平台指定的 Address/Data。系統確認兩層遮罩、啟用控制、裝置發送許可與平台接收資源都已就緒,最後開放事件來源。Table Size=7 表示共有 8 個項目;實際向量配置由系統決定,多個項目也可能共用向量。
通知暫時被遮罩時,沿哪些欄位追蹤事件?
先看 Table 7-49 的 Function Mask,再看 Table 7-55 的 entry Mask。任一層遮罩有效,裝置就按 §6.1.4.5 將通知留待處理,以 Table 7-56 的 Pending bit 表示。事件仍待處理而遮罩解除後,裝置安排送出通知,送出後清除 Pending。
之後要更改通知目標,如何接回設定流程?
先依規定遮罩,確認更新順序,再改 Address/Data,完成後解除遮罩。對原本未遮罩的項目,先以 DWORD 更新 Mask,避免用同一次 QWORD 寫入同時更動 Data 與遮罩;未遮罩時更改目的資料的結果未定義。(§6.1.4.2、§6.1.4.5,pp.662–665。)
9. 下一步:這些封包如何可靠地通過 Link?
到這裡,已能從設定空間走到資料搬移與通知。Chapter 8 回到 Link,說明訓練、流量控制與重送的責任;Chapter 9–10 接續 Reset 與電源管理,可由 課程路線 查看安排。
版本與來源
本章以 PCI Express Base Specification Revision 6.0 的 §6.1、§7.7.1–§7.7.2 為準;文件頁碼與 PDF 頁碼一致。查核日期:2026-10-28。未把其他版本的中斷欄位或特定 CPU 的中斷編碼混入通用規則;數值案例與初始化安排均已標示為作者推演。