硬體週邊裝置會透過匯流排連接到 CPU,例如 PCI 匯流排。
在啟動期間,BIOS (或對等的平台啟動軟體) 會探索連結至 PCI 匯流排的所有周邊裝置。每個週邊裝置都會獲派資源 (明顯會中斷向量和設定暫存器的位址範圍)。
這樣一來,指派給各個週邊裝置的實際資源在重新啟動時可能有所不同。作業系統軟體啟動時,會列舉所有支援的裝置的匯流排和啟動驅動程式。接著,驅動程式會呼叫 PCI 函式,藉此取得其裝置的設定資訊,以便對應暫存器並繫結至中斷。
基準地址註冊
基本地址註冊 (BAR) 是每 PCI 裝置中的設定暫存器,BIOS 會在此儲存裝置相關資訊,例如指派的中斷向量和控制註冊區地址。其他特定裝置資訊也會儲存在裡面。
呼叫 Pci::MapMmio() 以將 BAR 暫存檔對應至驅動程式代管程序的位址空間:
#include <lib/device-protocol/pci.h>
zx_status_t Pci::MapMmio(uint32_t bar_id, uint32_t cache_policy,
std::optional<fdf::MmioBuffer>* mmio);
ddk::Pci
類別是與 PCI 匯流排通訊時使用的介面驅動程式。
第一個參數 bar_id
是 BAR 註冊編號,從 0
開始。
第二個參數 cache_policy
會決定存取的快取政策,並可使用下列的值:
cache_policy 值 |
意義 |
---|---|
ZX_CACHE_POLICY_CACHED |
使用硬體快取功能 |
ZX_CACHE_POLICY_UNCACHED |
停用快取 |
ZX_CACHE_POLICY_UNCACHED_DEVICE |
停用快取,並視為裝置記憶體 |
ZX_CACHE_POLICY_WRITE_COMBINING |
含有寫入組合的非快取 |
請注意,ZX_CACHE_POLICY_UNCACHED_DEVICE
與架構有關,在某些架構上可能相當於 ZX_CACHE_POLICY_UNCACHED
。
最後一個引數是所建立緩衝區的輸出參數。
讀取和寫入記憶體
Pci::MapMmio() 函式傳回有效結果後,您就可以透過 MmioBuffer
介面存取 BAR,例如:
#include <lib/device-protocol/pci.h>
#include <lib/mmio/mmio-buffer.h>
std::optional<fdf::MmioBuffer> mmio;
zx_status_t status = pci.MapMmio(0, ZX_CACHE_POLICY_UNCACHED_DEVICE, &mmio);
if (status == ZX_OK) {
mmio.Write32(0x1234, REGISTER_X); // configure register X for deep sleep mode
}