BIOS实战之PCI设备枚举二

2024-06-07 05:18
文章标签 实战 设备 枚举 pci bios

本文主要是介绍BIOS实战之PCI设备枚举二,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上次说到了除了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设备枚举二的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038263

相关文章

Java 枚举的基本使用方法及实际使用场景

《Java枚举的基本使用方法及实际使用场景》枚举是Java中一种特殊的类,用于定义一组固定的常量,枚举类型提供了更好的类型安全性和可读性,适用于需要定义一组有限且固定的值的场景,本文给大家介绍Jav... 目录一、什么是枚举?二、枚举的基本使用方法定义枚举三、实际使用场景代替常量状态机四、更多用法1.实现接

Java Spring 中的监听器Listener详解与实战教程

《JavaSpring中的监听器Listener详解与实战教程》Spring提供了多种监听器机制,可以用于监听应用生命周期、会话生命周期和请求处理过程中的事件,:本文主要介绍JavaSprin... 目录一、监听器的作用1.1 应用生命周期管理1.2 会话管理1.3 请求处理监控二、创建监听器2.1 Ser

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性

MQTT SpringBoot整合实战教程

《MQTTSpringBoot整合实战教程》:本文主要介绍MQTTSpringBoot整合实战教程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录MQTT-SpringBoot创建简单 SpringBoot 项目导入必须依赖增加MQTT相关配置编写

JavaScript实战:智能密码生成器开发指南

本文通过JavaScript实战开发智能密码生成器,详解如何运用crypto.getRandomValues实现加密级随机密码生成,包含多字符组合、安全强度可视化、易混淆字符排除等企业级功能。学习密码强度检测算法与信息熵计算原理,获取可直接嵌入项目的完整代码,提升Web应用的安全开发能力 目录

Redis迷你版微信抢红包实战

《Redis迷你版微信抢红包实战》本文主要介绍了Redis迷你版微信抢红包实战... 目录1 思路分析1.1hCckRX 流程1.2 注意点①拆红包:二倍均值算法②发红包:list③抢红包&记录:hset2 代码实现2.1 拆红包splitRedPacket2.2 发红包sendRedPacket2.3 抢

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red

Spring Boot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)

《SpringBoot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)》:本文主要介绍SpringBoot拦截器Interceptor与过滤器Filter深度解析... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx