图2 Base Address Register for I/O bit0:表示设备寄存器是映射到memory(0)还是IO(1)空间。 bit1: reserved 0 bit2: 在base adress register for Memory 中0表示32位地址空间,1表示64位地址空间。 bit3:在memory BAR中用来表示该设备是否允许prefetch,1表示可以预取,0表示不可以预区。 其余的bit用来表示设备...
resource代表一个资源,可以是一段IO地址区间,或者Mem地址区间,总线树上每枚举一个设备,Host bridge就根据设备的BAR空间大小分配合适的资源给这个PCI设备用,这里的资源就是IO或者内存空间的物理地址。PCI设备BAR寄存器的值就是从这里申请得来的。申请的流程如下 pci_read_bases /* 遍历每个BAR寄存器,读取其内容,并为其...
IORESOURCE_IO IORESOURCE_MEM IORESOURCE_PREFETCH IORESOURCE_READONLY(PCI资源从不设置该标志) 驱动程序不需要访问配置寄存器去获得这些资源信息,因为系统已经构建了这些资源信息,驱动直接使用pci_resource_系列函数获取即可。 11. PCI中断 在linux系统启动时,已经为PCI设备分配了一个唯一的中断号,位于配置空间的第60寄存...
pci_read_bases/*遍历每个BAR寄存器,读取其内容,并为其申请物理地址空间*/for(pos =0; pos < howmany; pos++) {structresource *res = &dev->resource[pos];//申请的地址空间放在这里面reg = PCI_BASE_ADDRESS_0 + (pos <<2); pos+=__pci_read_base(dev, pci_bar_unknown, res, reg); } regi...
pcie枚举完成后,pci总线号已经分配,pcie ecam的映射、 pcie设备信息、BAR的个数及大小等也已经ready, 但此时并没有给各个pci device的BAR, pci bridge的mem, I/O, prefetch mem的base/limit寄存器分配资源。 这时就需要走到pcie的资源分配流程,整个资源分配的过程就是从系统的总资源里给每个pci device的bar分配资...
检测PCI 区域的大小,可利用 <linux/pci.h> 中定义的若干位掩码来简化:如果是内存区域,则 PCI_BASE_ADDRESS_SPACE 位掩码被设置为 PCI_BASE_ADDRESS_SPACE_MEMORY,是 I/O 区域时,设置为 PCI_BASE_ADDRESS_IO。若要知道映射后内存区域的实际地址,可将 PCI 寄存器和 PCI_BASE_ADDRESS_MEM_MASK 进行“与”操作...
PCI总线规定使用负向译码的PCI桥,其Base Class Code寄存器为0x06,Sub Class Code寄存器为0x04,而Interface寄存器为0x01;使用正向译码方式的PCI桥的Interface寄存器为0x00。系统软件(E2PROM)在初始化Interface寄存器时务必注意这个细节。 综上所述,在PCI总线中有两种负向译码设备,PCI-to-E(ISA)桥和PCI桥。但是PCI桥...
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0); } if (pmem) b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; } Pci bridge设备的7,8,9项是属于过滤窗口,也就是对应于总线的资源。 在这里,检查pci bus是否支持I/O和prefetch memory类型的窗口.如果不支持,则相应寄存器是只读的...
PCI总线的扫描流程
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ #define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ #define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) #define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) /* bit 1 is reserved if address_space = 1 */ /* Device cl...