上次说到了除了IO枚举PCI设备,还有另一种方式枚举PCI设备,那就是通过pciio,这也是UEFI代码中的常规操作(当然还有MMIO,不过不写了)

UEFI BIOS 提供了两个主要的模块来支持PCI 总线,一个是PCI Host Bridge 控制器驱动,另一个是PCI 总线驱动。

PCI Host Bridge 控制器驱动是跟特定的平台硬件绑定的,根据系统实际IO 空间和memory map, 为PCI设备指定I/O 空间和Memory 空间的范围,并且产生PCI Host Bridge Resource Allocation 协议(protocol)供PCI 总线驱动使用。该驱动还对HostBridge控制器下所有RootBridge 设备产生句柄(Handle), 该句柄上安装了PciRootBridgeProtocol。PCI 总线驱动则利用PciRootBridgeIo Protocol 枚举系统中所有PCI 设备,发现并获得PCI 设备的Option Rom, 并且调用PCI Host Bridge Resource Allocation protocol 分配PCI设备资源,PCI RootBridge设备又产生了PCI Local Bus。PCI 设备驱动不会使用PCI Root Bridge I/O protocol访问PCI 设备,而是会使用PCI总线驱动为PCI 设备产生的PCI IO Protocol 来访问PCI IO/MEMORY 空间和配置空间。

看完上面的话,咱们就开始直接进入主题:

EFI_STATUS
EFIAPI
ShellAppMain (IN UINTN Argc,IN CHAR16 **Argv)
{EFI_STATUS                  Status = EFI_SUCCESS;EFI_HANDLE                  *HandleBuffer;UINTN                       PciController_Count, Seg, BufferSize=0;UINTN                       NumHandles, i;EFI_PCI_IO_PROTOCOL         *PciIoProtocol;UINT8                       ListDevice = 0, SaveOpRom=0;UINT8                       IndexOfSavedDevice=0;PCI_CONTROLLER_INFO         PciController_Info[50];UINT32                      VenderDevId;CHAR16                      SaveFileName[100];       Print(L"===============================================\n");PciController_Count = 0;if(Argc >= 2){if(StrCmp(Argv[1], L"-L")==0){ListDevice = 1;}else if(StrCmp(Argv[1], L"-S")==0){if(Argc!=3){Status = EFI_INVALID_PARAMETER;Print(L"Please Specify Index of Device when save OpRom\n");goto ProcExit;}else{IndexOfSavedDevice = StrDecimalToUint64(Argv[2]);SaveOpRom = 1;}}}else{Print(L"Too few parameters\n");Status = EFI_INVALID_PARAMETER;goto ProcExit;    }Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPciIoProtocolGuid, NULL, &NumHandles, &HandleBuffer);for(i=0; i< NumHandles; i++){Status = gBS->HandleProtocol(HandleBuffer[i], &gEfiPciIoProtocolGuid, (void**)&PciIoProtocol);if(!EFI_ERROR(Status)){if(PciIoProtocol->RomSize>0){VenderDevId = 0xFFFFFFFF;PciIoProtocol->Pci.Read(PciIoProtocol, EfiPciIoWidthFillUint32, 0, 1, &VenderDevId);Seg = 0;PciIoProtocol->GetLocation(PciIoProtocol,&Seg,&PciController_Info[PciController_Count].Bus,&PciController_Info[PciController_Count].Device,&PciController_Info[PciController_Count].Func);PciController_Info[PciController_Count].Handle =   HandleBuffer[i];PciController_Info[PciController_Count].PciIo = PciIoProtocol;PciController_Info[PciController_Count].VidDid = VenderDevId;PciController_Count +=1;    }}}if(ListDevice){Print(L"Controller With OpRom Number: %d \n",PciController_Count);for(i=0;i<PciController_Count;i++){Print(L"Controller ID: %d  VidDid: %08x  Bus: %x  Dev: %x Func: %x  Size: 0x%x\n",i,PciController_Info[i].VidDid ,PciController_Info[i].Bus,PciController_Info[i].Device,PciController_Info[i].Func,PciController_Info[i].PciIo->RomSize);}
....

代码贴出了一部分,不过已经足够了,完全可以通过上述的代码自己写一个app,代码非常好理解

BIOS实战之PCI设备枚举二相关推荐

  1. BIOS实战之PCI设备枚举一

    PCI设备枚举主要通过两种不同方式进行表现,一种就是IO了,那么另一种就是UEFI中的pciio协议,首先看下第一种 IO方式进行PCI设备枚举 先写一个读PCI配置空间的函数,这是通过汇编写,很好理 ...

  2. Linux源码阅读——PCI总线驱动代码(三)PCI设备枚举过程

    目录 前言 1.枚举过程 1.1 acpi_pci_root_add 1.2 pci_acpi_scan_root(枚举开始) 1.3 acpi_pci_root_create 1.4 pci_sca ...

  3. PCI/PCIE之总线、设备枚举

    先思考一个问题,系统配置PCI设备的时候,需要指明Bus Device Function Register构成的地址,但是系统如何知道主板上有多少总线,设备呢?整个系统的PCI拓扑需要系统去枚举遍历, ...

  4. linux枚举pcie设备,pcie设备枚举(转载)

    转载自chinaunix 枚举所有PCI设备 冷胜魁(Seaquester) lengshengkui@gmail.com 2009-11-16 在Linux下,lspci可以枚举所有PCI设备.它是 ...

  5. Pci设备驱动:设备枚举

    有了设备模型基础及usb设备驱动的基础知识,来了解PCI设备驱动,就相对简单了,因为PCI设备驱动仍然套用了设备驱动模型的方式,用到的仍然是设备模型的相应函数,只是把相应的pci设备挂载到PCI总线的 ...

  6. 如何在DOS中枚举PCI设备

    From:http://blog.csdn.net/zyl910/article/details/858349 如何在DOS中枚举PCI设备 分类: #All - 所有             微机原 ...

  7. 枚举PCI设备的讨论

    作者很明显不是做底层的,但是也研究出如何访问PCI设备. 可以借鉴和参考原作者的Source code. --------------------以下为转载内容-------------------- ...

  8. 如何在DOS中枚举PCI设备(作者zyl910)

    File:      zEnumPCI Name:      如何在DOS中枚举PCI设备 Author:    zyl910 Blog:      http://blog.csdn.net/zyl9 ...

  9. 浅谈Linux PCI设备驱动(二)

    我们在浅谈Linux PCI设备驱动(一)中(以下简称浅谈(一) )介绍了PCI的配置寄存器组,而Linux PCI初始化就是使用了这些寄存器来进行的.后面我们会举个例子来说明Linux PCI设备驱 ...

最新文章

  1. libcurl下载限速编程调研
  2. 2-2 工程源码文件结构
  3. 理解Windows窗体和WPF中的跨线程调用
  4. 可爱的朋友,你是否有很多问号
  5. maven中scope属性
  6. Linux复习-进程及其管理
  7. 安装IBM Data Studio Client
  8. fataexception matlab,人工势场法路径规划(附MAtlab程序)
  9. Apache 绿色版本官方版本下载
  10. 【锋会现场】大屏世界杯:电视到底是个什么东西?
  11. 快手调整员工福利,​减少房补,增加生育津贴;百度网盘青春版正式上线,被吐槽;雷军回应小米对标苹果遭冷嘲热讽 | EA周报...
  12. N点虚拟主机管理系统 企业版稳定亲测
  13. 计算机usb 不显示错误的是,电脑插入U盘不显示USB Mass storage device感叹号
  14. POJ 1877 Flooded!
  15. 使用JWPL处理维基百科数据-使用eclipse
  16. AndroidManifest.xml参数
  17. linux中使用crontab出现crontab: installing new crontab
  18. 杰理之上下文件夹播放上文件夹从最后一首播放【篇】
  19. C# 保存窗口为图片(保存纵断面图)
  20. 汽车振动响应分析-频响函数法(附程序)

热门文章

  1. 一个很牛的 linux shell脚本编写的俄罗斯方块游戏实例代码,非常牛逼
  2. Vegas 使用教程(三)视频比例和素材去黑边
  3. 统计整个同学录有多少在线同学
  4. BDD100K数据集下载(百度网盘)
  5. 课程设计-单机版五子棋游戏-Java
  6. android创建一个新文件,如何在android中创建一个新文件夹DCIM
  7. 树莓派实现USB存储设备自动挂载
  8. note同步不及时 one_成功解决onenote 与windowsmobile无法正常同步问题
  9. 用户反馈信息textbox填充数据表,页面使用gridview显示反馈意见
  10. 电脑联机获取更多主题服务器未响应,高手讲解win10系统联机获取更多主题的修复方法...