PCIe Chapter 4:BAR、位址空間與資源配置

【模擬資料】本章位址、設定與裝置 Register 為教學用途建立,不代表特定硬體或平台。

先看本章的角色與路徑

巢狀範圍表示沿途視窗涵蓋同一裝置資源,不代表各層另配置一份裝置記憶體。巢狀範圍表示沿途視窗涵蓋同一裝置資源,不代表各層另配置一份裝置記憶體。CPU 存取裝置資源依平台位址轉譯Root Port Window:涵蓋下游配置Switch 路徑各層 Window:涵蓋同一目標Endpoint Memory BAR已配置的基底、大小與對齊

作者的位址涵蓋示意。CPU 位址與 BAR 中的位址是否相同,需依平台的位址轉譯判定。

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

BAR(Base Address Register,基底位址暫存器)提供裝置資源的型別與配置入口。軟體先取得需求,再分配對齊的位址,讓沿途 Bridge Window 涵蓋它,最後開啟適用的解碼。

前情提要:Chapter 3 已找到這個 Function。現在處理它的資源,尚未開始驅動程式的工作流程。

規格路線:Figures 7-10–7-12/Table 7-9 → Figure 7-14 與 Bridge Window 條文 → Figure 7-5/Table 7-4 的 Command 控制。

找到 Function 後,還要建立資源位址與沿途轉送範圍。BAR 描述 Endpoint 自己需要的空間;Bridge Window 決定要求能否走到下游;Command 的控制位則決定目前允許哪些存取。這三件事必須一起成立。

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

先認格式,再談大小

BAR 位於 Configuration Header,不是工作資料緩衝區。Type 0 Header 提供六個 DWORD 位置;64-bit BAR 佔兩個連續位置。Bridge 的 Type 1 Header 則只有兩個 BAR 位置,與下游 Memory Window 分開。

Memory BAR 的 bit 0 為 0,bits 2:1 的 00b/10b 分別表示 32/64-bit,bit 3 為 Prefetchable;I/O BAR 的 bit 0 為 1,位址從 bit 2 起,不能套用 Memory BAR 的低四位遮罩。本例不用 I/O BAR:一般 PCIe Endpoint 不得依賴 OS 配置 I/O 資源,也不得發 I/O Requests。

Prefetchable 表示資源容許規格列出的無讀取副作用與寫入合併等行為,不是 CPU 快取狀態。對本例的一般 Endpoint,Prefetchable BAR 須支援 64-bit;非 Prefetchable 可以是 32-bit。

查閱順序

先看 Figure 7-10(p.928)或 Figure 7-14(p.936)定位,再看 Figures 7-11/7-12、Table 7-9(p.929)辨識格式;容量、配對與對齊規則在 §7.5.1.2.1(p.930)。一般 Endpoint 限制見 §1.3.2.2,p.105。

探測值必須按 32 或 64 bits 計算

規格的探測方法先停用相應解碼、保存原 BAR,再寫全 1、讀回並遮掉類型 bits。取反加一時,必須限制運算寬度;最後還原原值,或在重新啟用前完成一致的新配置。BME 清零不代表先前交易自動消失,本例另以沒有進行中交易為前提。

教學探測與分配結果
資源全 1 探測的讀回值計算大小與分配
BAR0,0x100xFFFFC00032-bit 非 Prefetchable;16 KiB,配置 0x80004000–0x80007FFF。
BAR2/BAR3,0x18/0x1C0xFFE0000C/0xFFFFFFFF64-bit Prefetchable;2 MiB,配置 0x120000000–0x1201FFFFF。
BAR0 mask = 0xFFFFC000 & 0xFFFFFFF0
size = ((~mask) & 0xFFFFFFFF) + 1 = 0x4000

BAR2/3 mask = (0xFFFFFFFF << 32) | (0xFFE0000C & 0xFFFFFFF0)
size = ((~mask) & 0xFFFFFFFFFFFFFFFF) + 1 = 0x200000

BAR3 是 BAR2 的高 DWORD,不能因為回全 1 就當成另一個 I/O BAR。配置後 BAR0 為 0x80004000;BAR2/3 為 0x2000000C/0x00000001。初始 BAR 為 0 不代表未實作;只有依正確探測取得的未實作結果,才能如此判讀,也不能把全零遮罩誤算成 4 GiB 需求。

假設 BAR0 的 +0x120 是有效 Register,PCI 位址就是 0x80004120。本例另假設 CPU/PCI 相同映射,CPU 因而使用同一數字;這不是所有平台的保證。該 Register 功能與可用資源位址也是教學假設。

來源與限制

Base 6.0 §7.5.1.2.1,pp.928–930,包含 p.930 的 32/64-bit sizing 說明。Firmware 3.3 §3.1.1(p.32)容許 non-identity MMIO mapping。所有分配須另外符合平台資源、對齊、不重疊與位址寬度要求。

沿途每一層 Window 都要涵蓋目標

到 03:00.0 的路徑經 Root Port 00:01.0、Switch Upstream Port 01:00.0、Downstream A 02:01.0。本例三者皆支援並配置下列窗口,平台已保留相應範圍,其他分支不佔用它們。

三個 Bridge 的共同教學配置
欄位設定值解碼後的範圍
Memory Base/Limit,0x20/0x22,各 16 bits0x8000/0x80000x80000000–0x800FFFFF
Prefetchable Base/Limit,0x24/0x26,各 16 bits;Upper,0x28/0x2C,各 32 bits0x2001/0x2011;Upper 均為 10x120000000–0x1201FFFFF

Base 的低 20 address bits 補 0,Limit 補 1,形成 1 MiB 粒度的包含起點與終點的範圍。Prefetchable 欄位的低 nibble=1 表示支援 64-bit,Upper 接成位址高 32 bits。窗口可以比 BAR 大,但不保證空隙中有有效 Register;也不能把 Bus Number 範圍拿來代替 Memory Window。

來源

Figure 7-14,p.936;§7.5.1.3.8–§7.5.1.3.10,pp.940–941。完整教學逐步計算各個遮罩、位移與包含關係。

MSE 與 BME 不是同一個開關

Command 位於 0x04,寬度 16 bits。bit 0 控制 I/O Space,bit 1 的 MSE 控制收到的 Memory 存取,bit 2 的 BME 控制 Function 發起 Memory/I/O Requests;Type 1 Port 的 BME 還控制向上游轉送相關要求,不阻擋 Completion。

在資源、窗口、平台映射與裝置介面均已就緒的前提下,本例 Endpoint 與三個 Bridge 的 Command=0x0002,允許 CPU 讀取已配置的 MMIO,但 Endpoint 尚不能發起 DMA Memory Request;讀取回覆的 Completion 不被 BME 阻擋。BME=0 也禁止 MSI/MSI-X,因為它們是帶內 Memory Write。

MMIO
Memory-Mapped I/O,記憶體映射輸入輸出
DMA
Direct Memory Access,裝置直接存取記憶體
MSI
Message Signaled Interrupt,訊息中斷
MSI-X
Message Signaled Interrupts Extension,表格式訊息中斷

把 Endpoint 改為 0x0006,只增加發起相關要求的許可,仍要準備緩衝區、裝置工作、平台轉譯與上游 Port 的 BME。修改 Command 時也不能任意連同 0x06 的 Status 一起原樣回寫,因為 Status 含 RW1C 位元。

控制位來源

Base 6.0 §7.5.1.1.3,Figure 7-5/Table 7-4,pp.917–920;BME、Completion 與 MSI 說明在 p.919。Command/Status 布局:Figure 7-4,p.916;Status RW1C:Table 7-5,pp.922–923。

設定空間可讀,為什麼 Memory Read 還會失敗?

設定存取用 BDF 與 Register offset 選擇 Function 和欄位;Memory Read 則使用記憶體位址選擇目標。沿用本章案例,先把 0x80004120 放回 BAR0 與每一層 Window,再檢查接收方向上的 Memory Space Enable(MSE,記憶體空間解碼控制)。

BDF
Bus/Device/Function,匯流排、裝置與功能識別

查閱時先由 Figure 7-10/Figure 7-14 定位 BAR 與 Bridge 欄位,使用 §7.5.1.3.8 解碼 Memory Base/Limit,接著讀 Figure 7-5/Table 7-4 的 MSE,注意 Type 1 Header 的 Primary Side 條件。最後用 §2.3.1 的 Request Handling 規則確認需要 Completion 的 UR 如何回覆。(Base 6.0,文件頁/PDF 頁 208、916–918、928、936、940。)

只要位址落在 BAR 內,每個 byte 都可以讀嗎?

BAR 的大小定義資源位址範圍;實際有哪些可用的裝置 Register,要查裝置介面文件。本例只假設 +0x120 是可讀 Register,並未定義 +0x3000 的用途,雖然它也在 BAR0 範圍內。Base 6.0 §7.5.1.2.1(p.930)允許 Function 對程式模型從不存取的未使用位置回 UR。要判定某次存取的結果,還需要該裝置介面及實際交易證據。

配置與交接的結論要分清

Firmware 3.3 §3.5(pp.34–35)以 I/O/Memory Enable 及 ROM Enable 判斷相應資源配置,不使用 BME 判定 BAR 是否有效。已啟用的資源必須由韌體正確配置,但驅動仍須依裝置介面準備工作。

ROM
Read-Only Memory,唯讀記憶體
16 KiB BAR 改放 0x80005000,可以嗎?

不行。低 14 bits 不是全 0,未達自然對齊;本例正確的基底 0x80004000 才符合。(§7.5.1.2.1,p.930。)

窗口正確,Endpoint MSE=0,是否仍可成功讀 MMIO?

不能期待成功。MSE=0 時,Endpoint 收到的 Memory Space 存取按 UR 處理;路徑可轉送不能代替終點啟用。(Table 7-4,p.918。)

Chapter 5 接著追蹤 Request 與 Completion;Chapter 6–7 延伸至 DMA 與中斷。

DMA
Direct Memory Access,裝置直接存取記憶體
Jia-Chang

Jia-Chang

Human

Comments

  Write a comment ...