unsigned int memaddr1,memaddr2; unsigned int iobase,ioa; void getbaseaddr(char bus,char device); { iobase=0x80000000+bus*0x10000+(device*8)*0x100; ioa=iobase+0x10;/*寻址基地址寄存器0*/ _outpd(0xcf8,ioa); ioaddr1=(unsigned short)_inpd(0xcfc)&0xfffc; /*屏蔽低两位和高16位*/ ...
假设该PCI设备占用了4个资源空间,分别对应于配置空间10h~1ch,其中前两个为I/O空间,后两个为内存空间,若定义其基地址分别为ioaddr1,ioaddr2,memaddr1,memaddr2,相应的程序如下: unsigned short ioaddr1,ioaddr2; unsigned int memaddr1,memaddr2; unsigned int iobase,ioa; void getbaseaddr(char bus,...
检测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 进行“与”操作...
unsigned int memaddr1,memaddr2; unsigned int iobase,ioa; void getbaseaddr(char bus,char device); { iobase=0x80000000+bus*0x10000+(device*8)*0x100; ioa=iobase+0x10;/*寻址基地址寄存器0*/ _outpd(0xcf8,ioa); ioaddr1=(unsigned short)_inpd(0xcfc)&0xfffc; /*屏蔽低两位和高16位*/ ...
在Linux系统中,设备驱动程序调用pci_enable_device函数(也可以是pci_enable_device_mem-> pci_enable_device_flags-> do_pci_enable_device-> pcibios_enable_device-> pci_enable_resources-> pci_write_config_word),使能该寄存器的I/O和Memory Space位之后,才能访问该设备的存储器或者I/O地址空间。
//判断内存空间位数mem_type = bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK;switch(mem_type) {casePCI_BASE_ADDRESS_MEM_TYPE_32:break;casePCI_BASE_ADDRESS_MEM_TYPE_1M:/* 1M mem BAR treated as 32-bit BAR */break;casePCI_BASE_ADDRESS_MEM_TYPE_64: ...
从上图的寄存器分布中可以看到中间有一段地址空间描述BARS(Base Address Register),这些寄存器组用来存储备PCI设备工作时的io地址、irq号和mem地址起始地址以及长度。这些信息存储的具体位置需要查阅相应PCI设备的datasheet方可得知,在内核中提供了以下几个接口来获取这些资源。
UEMsk - Uncorrectable Error Mask UESvrt - Uncorrectable Error Severity CESta - Correctable Error Status CEMsk - Correctable Error Mask AERCap - Advanced Error Reporting Capabilities For specifics on what the meaning of the bits in these registers are see the PCI Express Base Specification Revision...
pciConfigOutWord(pciBus, pciDevice, pciFunc, PCI_CFG_COMMAND,CI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE); membaseCsr &=PCI_MEMBASE_MASK; iobaseCsr &=PCI_IOBASE_MASK; pDrvCtrl->membase = membaseCsr; pDrvCtrl->iobase = iobaseCsr; ...
Base Address Register for Memory Base Address Register for I/O 获取地址类型 读取bit0,判断该bar是IO空间还是mem空间。如果是mem空间进一步获取该mem是32位还是64位,以及是否是可预取的。__pci_read_base---decode_bar 获取地址长度 通过先全部写1然后读的方式,来获取可用长度。如果bar是64位mem,会多获取一...