PCIE 设备扫描的过程_第1页
PCIE 设备扫描的过程_第2页
PCIE 设备扫描的过程_第3页
PCIE 设备扫描的过程_第4页
PCIE 设备扫描的过程_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PCIE设备扫描的过程初步了解完PCI总线标准之后,我们接下来正式开始PCIe设备的漫游之旅。从我们按下PC的电源按钮开始,BIOS就接管系统控制权开始工作,它会先进行PCI设备),由于商业上的原因,Phoenix等厂商的BIOS代码需要授权协议,在此,我们以另外一个款开源BIOS(openbios)为例,来剖析BIOS中,我们的PCIe设备是如何被找到以及初始化的。PCI设备的扫描是基于深度优先搜索(DFSDepthFirst,也就是PCI说明,BIOS是如何一步步完成PCI设备扫描的。PCIHost主桥扫描Bus0HOST主桥直接相连的PCI总线被命名为PCIBusBus0上的D1,D2等不会挂接PCIBridge1Bridge1下面的PCIBus定为Bus1,系统将初始化Bridge1的配置空间,并将该桥的PrimaryBusNumber和SecondaryBusNumber寄存器分别设置成0和1,以表明Bridge1的上游总线是01Bridge1下挂载设备SubordinateBusNumber设为0xFF系统开始扫描Bus,将会发现Bridge2。系统将Bridge2下面的PCIBus定为Bus2,并将该桥的PrimaryBusNumber和SecondaryBusNumber寄存器分别设置成1和,和上一步一样暂时把Bridge2的SubordinateBusNumber设为0xFF。如下图所示:系统继续扫描Bus,将会发现Bridge4。系统将Bridge4下面的PCIBus定为Bus3,并将该桥的PrimaryBusNumber和SecondaryBusNumber寄存器分别设置成2和,此后系统继续扫描后发现Bus3下面已经没有任何BridgePCI总线下已经没有任何挂载下游总线了,因此Bridge4的SubordinateBusNumber的值已经可以确定为3了。如下图所示:完成Bus3的扫描后,系统返回到Bus2继续扫描,发现Bus2下面已经没有其他Bridge了。此时Bridge2的SubordinateBusNumber的值也已经可以确定为3了。如下图所示:完成Bus2的扫描后,系统返回到Bus1继续扫描,会发现Bridge3,系统将Bridge3下面的PCIBus定为Bus。并将Bridge4的PrimaryBusNumber和SecondaryBusNumber寄存器分别设置成1和4现Bus4下面已经没有任何BridgePCI总线下已经没有挂载任何下游总线了,因此Bridge3的SubordinateBusNumber的值已经可以确定为4了。如下图所示:完成Bus4的扫描后,系统返回到Bus1继续扫描,发现Bus1下面已经没有其他Bridge了。此时Bridge1的SubordinateBusNumber的值已经可以确定为4,系统返回Bus0继续扫描(Bus0下如果有其他它Bridge,将重复上PCI的设备扫描已经完成了。最终的设备和总线的扫描结果如下图所示。了解了上面PCI设备扫描的大概流程,我们接下来看看Bios代码中具体是如何实现这些扫描的。一般来说,我们可以通过两个寄存器来访问PCI的配置空间(寄存器CONFIG_ADDRESS与CONFIG_DATA),在x86体系下,这两个寄存器分别对应0xCF8和0xCFC来实现先。CONFIG_ADDRESS寄存器的具体位组成如下图所示:BusNumber:8bit),范围0--255。FunctionNumber:功能号(3bit),范围0--7。RegisterNumber:6范围0--63(配置空间一共256个字节,分割成64个4字节的寄存器,从0--63编号)。,1.staticinlineuint32_tpci_config_read32(pci_addrdev,uint8_treg)7.staticinlinevoidpci_config_write32(pci_addrdev,uint8_treg,9.outl(dev|reg,0xcf8);10.outl(val,0xcfc);11.}1.intob_pci_init(void)unsignedlongmem_base,io_base;//获取系统指定的memeory与I/OPCIe设备。16.mem_base=arch->mem_base;/*I/Oportsunder0x400areusedbydevicesmappedatfixedlocation.*/io_base=arch->io_base+0x400;26.free(path);27.return0;28.}总线扫描具体实现:1.staticvoidob_scan_pci_bus(intbus,unsignedlong*mem_base,7.pci_config_tconfig;12.activate_device("/");13.for(devnum=0;devnum<32;devnum++){16.#ifdefCONFIG_XBOX/*获取设备配置空间vid=pci_config_read16(addr,PCI_VENDOR_ID);/*获取did=pci_config_read16(addr,PCI_DEVICE_ID);/*获取Device23.24.25.26.ccode=pci_config_read16(addr,PCI_CLASS_DEVICE);class=ccode>>8;pci_dev=pci_find_device(class,subclass,iface,/*具体设备查printk("%x:%x.%x-%x:%x-",bus,devnum,fn,if(pci_dev==NULL||pci_dev->name==NULL)snprintf(config.path,(config.path),"%s/pci%x,%x",*path,vid,did);else47.config.dev=addr&0x00FFFFFF;REGISTER_NAMED_NODE(ob_pci_node,config.path);activate_device(config.path);ob_pci_configure(addr,&config,mem_base,io_base);ob_pci_add_properties(addr,pci_dev,&config);60.61.62.63.64.65.66.67.68.if(class==PCI_BASE_CLASS_BRIDGE&&(subclass==PCI_SUBCLASS_BRIDGE_HOST||subclass==PCI_SUBCLASS_BRIDGE_PCI)){/*hostorbridge*/*path=strdup(config.path);}72.device_end();73.}1.<prename="code"="cpp">constpci_dev_t*pci_find_device(uint8_tclass,uint8_tsubclass,5.int(*config_cb)(constpci_config_t*config);6.constpci_class_t*pclass;7.constpci_subclass_t*psubclass;8.constpci_iface_t*piface;9.constpci_dev_t*dev;10.constvoid*private;11.pci_dev_t*new;12.constchar*name,*type;13.19.if(class==0x00&&subclass==0x01){/*Specialcaseformiscdevices*/dev=misc_pci;28.if(class>(sizeof(pci_classes)/sizeof(pci_class_t))){33.pclass=&pci_classes[class];34.name=pclass->name;35.type=pclass->type;36.for(psubclass=pclass->subc;;psubclass++){if(psubclass->subclass==0xFF)gotobad_device;if(psubclass->private!=NULL)private=psubclass->private;if(psubclass->iface!=NULL)break;55.for(piface=psubclass->iface;;piface++){56.57.dev=psubclass->devices;75.if(dev==NULL)76.gotobad_device;77.for(;;dev++){78.79.if(dev->vendor==0xFFFF&&dev->product==0xFFFF){gotobad_device;80.81.82.83.84.85.86.87.88.89.90.91.92.93.94.95.96.97.98.99.100.101.if(dev->vendor==vendor&&dev->product==product){if(dev->name!=NULL)name=dev->name;if(dev->type!=NULL)type=dev->type;new->name=name;new->model=dev->model;new->compat=dev->compat;new->acells=dev->acells;new->scells=dev->scells;printk("Cannotmanage'%s'PCIdevicetype'%s':\n%x%xname,type,vendor,product,class,subclass,iface);配置具体设备的配置空间staticvoidob_pci_configure(pci_addraddr,pci_config_t*config,unsignedlong*mem_base,121.unsignedlong*io_base)uint32_tsmask,omask,amask,size,reloc,min_align;unsignedlongbase;pci_addrconfig_addr;uint8_tirq_pin,irq_line;/*配置中断引脚与中断编号*/irq_pin=pci_config_read8(addr,PCI_INTERRUPT_PIN);if(irq_pin){irq_pin=(((config->dev>>11)&0x1F)+irq_pin-1)&135.136.137.138.139.140.141.142.irq_line=arch->irqs[irq_pin];pci_config_write8(addr,PCI_INTERRUPT_LINE,irq_line);config->irq_line=irq_line;}elseconfig->irq_line=-1;/*配置memory空间和I/O空间*/omask=0x00000000;for(reg=0;reg<7;reg++){config->assigned[reg]=0x00000000;config->sizes[reg]=0x00000000;if((omask&0x0000000f)==0x4){/*64bitsmemorymapping*/159.160.161.162.163.pci_config_write32(addr,config_addr,0xffffffff);smask=pci_config_read32(addr,config_addr);164.165.166.167.168.169.170.171.172.173.174.175.176.177.178.179.180.181.182.183.184.185.min_align=1<<7;amask=0x00000001;pci_config_write16(addr,PCI_COMMAND,pci_config_read1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论