SylixOS PCI BAR寄存器

  1. 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,以後再讀取該寄存器。內存

  2. 技術實現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);
        }

    當BAR寄存器映射到I/O空間時,有2種訪問途徑,即I/O映射方式(I/O - mapped)和內存映射方式(Memory - mapped)。前一種途徑不映射到內存空間,直接使用in8/out8之類的函數進行訪問I/O端口;後一種途徑是先把I/O端口映射到I/O內存,再使用訪問I/O內存的函數來訪問I/O端口。其中第一種途徑的使用流程如程序清單2.2所示。

     

    程序清單 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);
     

     

  3. 參考資料

相關文章
相關標籤/搜索