PCI BAR簡介編程
PCI設備都有獨立的配置空間,HOST主橋經過配置讀寫事務訪問這段空間。PCI設備的配置空間大小爲256字節,其中頭部64字節爲PCI標準規定,剩餘部分爲PCI設備自定義的。PCI配置空間頭部包含6個BAR(Base Address Registers)寄存器,BAR寄存器保存了PCI設備使用的地址空間的類型(Memory 空間或者I/O 空間),基地址以及其餘屬性。其中基地址保存的是該設備在PCI總線域中的地址,但在x86中通常與存儲器域地址直接相等。app
PCI設備復位以後,該寄存器將存放PCI設備須要使用的基址空間大小,這段空間是I/O空間仍是Memory空間,若是是Memory空間該空間是否預取。當BAR寄存器映射到Memory空間時,Bit 0等於0,如圖1.1所示。當BAR寄存器映射到I/O空間時,Bit 0等於1,如圖1.2所示。函數
圖 1.1 Memory Space的BAR寄存器spa
圖 1.2 I/O Space的BAR寄存器指針
I/O 空間是x86系統上面的專用空間,與內存獨立編址,使用專用指令進行讀寫。如今的I/O空間大小是64KB,從0x0000到0xFFFF,能夠供設備使用。目前多數PCI設備都不支持I/O空間,而僅支持Memory空間,可是仍有部分PCI設備同時包含I/O空間和Memory空間。事務
系統軟件對PCI總線進行配置時,首先得到BAR寄存器中的初始化信息,以後根據處理器系統的配置,將合理的基地址寫入相應的BAR寄存器中。系統軟件還能夠使用該寄存器,得到PCI設備使用的BAR空間的長度,其方法是向BAR寄存器寫入0xFFFF_FFFF,以後再讀取該寄存器。內存
技術實現ci
當BAR寄存器映射到Memory空間時,I/O地址空間是物理主存的一部分,對於編程而言,咱們只能操做虛擬內存,因此,訪問的第一步就是要把設備所處的物理地址映射到虛擬地址。而後,咱們能夠直接經過指針訪問這些地址,通常的使用過程如程序清單2.1所示。資源
程序清單 2.1 Memory資源使用流程it
hResource = API_PciDevResourceGet(hPciDevHandle, PCI_IORESOURCE_MEM, 0); if (!hResource) { return (PX_ERROR); } ulBaseAddr = (ULONG)(PCI_RESOURCE_START(hResource)); stBaseSize = (size_t)(PCI_RESOURCE_SIZE(hResource)); pvBaseAddr = API_PciDevIoRemap((PVOID)ulBaseAddr, stBaseSize); if (!pvBaseAddr) { return (PX_ERROR); }
程序清單 2.2 I/O資源使用流程
hResource = API_PciDevResourceGet(hPciDevHandle, PCI_IORESOURCE_IO, 0); if (!hResource) { return (PX_ERROR); } ulBaseAddr = (ULONG)(PCI_RESOURCE_START(hResource)); stBaseSize = (size_t)(PCI_RESOURCE_SIZE(hResource)); out8(0x1, ulBaseAddr + 0x10);
參考資料
無