====== PCIE 存取方式 ======
===== PCIe Configuration Access 兩大機制比較 =====
^項目 ^ Mechanism #1(I/O Port Based)^ Mechanism #2(MMIO / ECAM Based)^
|📜 標準名稱 | PCI Spec | PCIe Base Spec(ECAM)|
|👨💻 存取方式 | 透過 I/O Port 0xCF8/0xCFC|透過 MMIO 直接對應 Config 空間|
|🧱 硬體需求 | 不需要 MMCONFIG | 需提供 MMCONFIG base 地址 |
|📍 典型使用平台 | Legacy BIOS, x86(PCI)| UEFI, modern x86-64(PCIe)|
| 🗂 Address 空間 | 利用 32-bit I/O Port 做定址 | 每個 Function 對應 4KB MMIO 區 |
| ⚙️ 實體地址組成 | CF8 / CFC | PCIEX_BASE_ADDRESS + Calculation |
| 🔄 支援 Config 空間大小 | 256 Bytes(PCI)| 4KB(PCIe)|
| 🔍 可見性 | 無法被一般 Memory View 工具看到 | 可透過 memtool / debugger 查看 |
| 🔒 安全性 | 較低,容易誤操作 | 較安全,區段獨立清楚 |
| 🚫 限制 | 無法存取多段 Bus 空間、無法支援完整 PCIe 擴展功能 | 需 BIOS/ACPI 支援並正確配置 MMCONFIG |
==== Mechanism #1:I/O Port-based(0xCF8 / 0xCFC)====
#define PCI_ADDR(bus, dev, func, reg) \
(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xFC))
IoWrite32(0xCF8, PCI_ADDR(0, 31, 0, 0x10));
UINT32 val = IoRead32(0xCFC); // 讀 BAR0
* 限制在 I/O Port 空間
* 不能存取 offset 超過 256B(無法取到 PCIe Capability 結構)
* 項目適用於老式 PCI 裝置或 BIOS 內存取 Host Bridge
0xCF8 Address 格式(32-bit)
^ Bit ^ 範圍 名稱 ^ 寬度 ^ 說明 ^
| 31 | Enable Bit | 1 | 必須設為 1 才能啟用 |
| 30–24 | Reserved | 7 | 必須為 0 |
| 23–16 | Bus | 8 | Bus number |
| 15–11 | Device | 5 | Device number |
| 10–8 | Function | 3 | Function number |
| 7–2 | Register | 6 | Config register number (dword aligned)|
| 1–0 | Always 0 | 2 | 必須為 0(因為只能對齊讀取)|
如何透過 Mechanism 1 存取 bus 0 device 31 function 0 offset 0
UINT32 pci_addr = (1U << 31) // Enable Bit
| (0x00 << 16) // Bus 0
| (0x1F << 11) // Device 31
| (0x0 << 8) // Function 0
| (0x10 & 0xFC); // Offset (dword aligned)
Enable Bit = 0x80000000
+ Bus = 0x00000000
+ Devicec = 0x0000F800
+ Function = 0x00000000
+ Offset = 0x00000000
-------------------------------
最終地址 = 0x800F8000
將最終 32bit 地址放入IO 0xCF8 , 再從 0xCFC 讀回
==== Mechanism #2:MMIO / ECAM-based(Memory Mapped) ====
#define PCIEX_BASE_ADDRESS 0xC0000000
UINT32* bar0 = (UINT32*)(PCIE_ECAM_BASE + (0 << 20) + (31 << 15) + (0 << 12) + 0x10);
val = *bar0; // 直接透過 Memory Read 存取 BAR0
* 每個 Function 對應 4KB
* 可完整存取 PCIe Capabilities(超過 256 bytes)
* 搭配 ACPI 的 MCFG Table 可以動態獲得配置空間範圍
^ 欄位 ^ 位元區間 ^ 寬度 ^ 對應意義 ^
| Bus | 27–20 | 8 位元 | 支援 Bus 0–255 |
| Device | 19–15 | 5 位元 | 支援 Device 0–31 |
| Function | 14–12 | 3 位元 | 支援 Function 0–7 |
| Offset | 11–0 | 12 位元 | 支援 4KB 配置空間 |
| MMCONFIG BASE | 28+ | 不定 平台定義的起始地址 |
如何透過 Mechanism 2 存取 bus 0 device 31 function 0 offset 0
Bus << 20 = 0 << 20 = 0x00000000
Device << 15 = 31 << 15 = 0x000F8000
Function << 12 = 0 << 12 = 0x00000000
Offset = 0x00000000
-------------------------------
總和 = 0x000F8000
PCIEX_BASE_ADDRESS = 0xC0000000
+ Offset Sum = 0x000F8000
-------------------------------
最終地址 = 0xC00F8000
使用 Utility -> RW -> Memory 讀取 0xC00F8000
AMI code 直接 search "PCIEX_BASE_ADDRESS" 確認 base Address 值。
P2SB Device / Bus 0 Device 31 Function 1 0ffset 0 最終位址 0xC00F9000\\
PMC Device / Bus 0 Device 31 Function 2 0ffset 0 最終位址 0xC00FA000