修改PCIE 设备控制寄存器DevCtl2参数

如何修改PCIE 设备控制寄存器DevCtl2参数?

在这里插入图片描述
参考书籍:PCI_Express_Base_Spec
如图所示:输入Lspci -s 00:08:00 -vvv|grep - i deve
输出DevCap、DevCtl、DevCap2、DevCtl2参数,本节重点分析UEFI BIOS怎么设置DevCtl2参数

在这里插入图片描述
1、能力指针在PCIE 配置空间偏移34h处,
Pci->Pci.Read (Pci, EfiPciIoWidthUint8, 0x34, 1, &CapabilityPtrEntry); 读到能力指针里的内容作为入口地址。
在这里插入图片描述
2、取CapabilityPtrEntry的两个字节进行判断, 如果PCI ExpressCapID 为0x10,为找到能力项的入口地址,如果PCI ExpressCapID 不为0x10,取Next CapabilitiesPointer 的指针地址,查看指针地址的值是否为 0x10,如果是0x10,找到能力项入口地址,如果为00,结束循环,不为0,又不为0x10,继续寻找下一个能力项地址。
3、当找到能力项入口地址,可以看出偏移0x28的两个字节为DeviceCtl2参数入口

在这里插入图片描述
4、找到DeviceCtl2,设备寄存器地址,可以对16个bit位进行分析
0-3 :Completion Timeout Value
4:Completion Timeout Disable
5: ARI Fowarding Enable
根据SPI Spec 对各个参数内容进行设置,设置完成,再写到PCI 配置空间里面

UINT8
LocatePciCapability (EFI_PCI_IO_PROTOCOL  *Pci,IN UINT8             CapabilityId)
{UINT8 CapabilityPtrEntry;UINT8 CapabilityNextPtr;UINT8 CapabilityIdValue;Pci->Pci.Read (Pci, EfiPciIoWidthUint8, 0x34, 1, &CapabilityPtrEntry);CapabilityNextPtr = CapabilityPtrEntry;while ((CapabilityNextPtr >= 0x40) && ((CapabilityNextPtr + 1) != 0x00)) {Pci->Pci.Read (Pci, EfiPciIoWidthUint8, CapabilityNextPtr, 1, &CapabilityIdValue);if (CapabilityIdValue != CapabilityId) {
//      CapabilityNextPtr = CapabilityNextPtr +1;Pci->Pci.Read (Pci, EfiPciIoWidthUint8, CapabilityNextPtr + 1, 1, &CapabilityNextPtr);} else {return CapabilityNextPtr;}}Pci->Pci.Read (Pci, EfiPciIoWidthUint8, CapabilityNextPtr + 1, 1, &CapabilityIdValue);if (CapabilityIdValue == 0x00) {Pci->Pci.Read (Pci, EfiPciIoWidthUint8, CapabilityNextPtr, 1, &CapabilityIdValue);if (CapabilityIdValue == CapabilityId) {return CapabilityNextPtr;}}return 0;
}VOID
EnableTimeOut()
{EFI_STATUS  Status;UINTN                           HandleCount, Index = 0;EFI_HANDLE                      *HandleBuffer;EFI_PCI_IO_PROTOCOL             *PciIo = NULL;UINT8                           ClassCode[3];UINT8                           CapabilityAddr,LinkState;UINT16                          ControlRegister;EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevicePathToText;CHAR16                            *DevicePathString = NULL;EFI_DEVICE_PATH_PROTOCOL          *PciIoDevicePath;// CHAR16 OnboardLanDevicePath[] = L"PciRoot(0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)/Pci(0x3,0x0)";// Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevicePathToText);// if (EFI_ERROR (Status)) {//   return Status;// }Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiPciIoProtocolGuid, NULL,&HandleCount,&HandleBuffer);if (!EFI_ERROR (Status)) {for (Index = 0; Index < HandleCount; Index ++) {Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&PciIo);if (!EFI_ERROR (Status)) {// Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&PciIoDevicePath);// if (!EFI_ERROR (Status)) {// DevicePathString = DevicePathToText->ConvertDevicePathToText(PciIoDevicePath, TRUE, TRUE);// if(!StrnCmp(OnboardLanDevicePath,DevicePathString,StrLen(OnboardLanDevicePath)) &&//   (StrLen(OnboardLanDevicePath) == StrLen(DevicePathString))){CapabilityAddr = LocatePciCapability(PciIo, 0x10);if(CapabilityAddr != 0){CapabilityAddr += 0x28;Status = PciIo->Pci.Read (PciIo,EfiPciIoWidthUint16,CapabilityAddr,1,&ControlRegister);DEBUG((EFI_D_ERROR, "James: ControlRegister is %0x\n", ControlRegister));if (!EFI_ERROR (Status)) {// Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);ControlRegister = ControlRegister | 0x10;//DEBUG((EFI_D_ERROR, "James: LinkState is %0x\n", LinkState));PciIo->Pci.Write (PciIo,EfiPciIoWidthUint16,CapabilityAddr,1,&ControlRegister);Status = PciIo->Pci.Read (PciIo,EfiPciIoWidthUint8,CapabilityAddr,1,&LinkState);DEBUG((EFI_D_ERROR, "James: ControlRegister is %0x\n", ControlRegister));}}}}// }// }}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/299915.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【基础篇】一、认识JVM

文章目录 1、虚拟机2、Java虚拟机3、JVM的整体结构4、Java代码的执行流程5、JVM的三大功能6、JVM的分类7、JVM的生命周期 1、虚拟机 虚拟机&#xff0c;Virtual Machine&#xff0c;一台虚拟的计算机&#xff0c;用来执行虚拟计算机指令。分为&#xff1a; 系统虚拟机&#x…

《PySpark大数据分析实战》-19.NumPy介绍ndarray介绍

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

.net6使用Sejil可视化日志

&#xff08;关注博主后&#xff0c;在“粉丝专栏”&#xff0c;可免费阅读此文&#xff09; 之前介绍了这篇.net 5使用LogDashboard_.net 5logdashboard rootpath-CSDN博客 这篇文章将会更加的简单&#xff0c;最终的效果都是可视化日志。 在程序非常庞大的时候&…

时间Date

你有没有思考过时间问题&#xff1a; 前端为什么可以直接看见时间格式的数据 后端怎么接受的数据&#xff0c;怎么处理的 一般来说&#xff1a;前端传输来数据都是时间格式的字符串&#xff0c;那么后端需要能够解析时间格式的字符串&#xff0c;归功于JSONFormat ,可以解析…

C#教程(五):枚举

1、什么是枚举 枚举&#xff08;Enum&#xff09;是一种用于定义命名常量集合的数据类型。它允许开发人员创建一个命名的整数常量集合&#xff0c;这些常量可以在代码中代表特定的值。 2、示例 以下是一个简单的枚举示例&#xff1a; // 定义一个枚举类型 enum DaysOfWeek …

JavaScript进阶(事件+获取元素+操作元素)

目录 事件基础 事件组成 执行事件的步骤 获取元素 根据ID获取元素 根据标签名获取元素 获取ol中的小li 类选择器&#xff08;html5新增的I9以上支持&#xff09; 获取body和html 操作元素 innerText和innerHtml 表单标签 样式属性操作 操作元素总结 事件基础 事…

每日一题-----逆序字符串

大家好我是Beilef&#xff0c;在一个美好的下午我意外接触到编程并且产生了兴趣&#xff0c;哈哈我要努力成为一个跨界者&#xff0c;让我们一起加油吧O(∩_∩)O 文章目录 目录 文章目录 前言 大家好请上车 一、逆序字符串 题⽬描述&#xff1a; 输⼊⼀个字符串&#xff0c;写…

Mac 右键拷贝文件失效

问题&#xff1a;Mac 右键拷贝文件失效&#xff0c;有时候拷贝可以成功&#xff0c;有时候拷贝不成功 发现问题所在&#xff1a;开了百度翻译的划词&#xff0c; 解决&#xff1a;把划词关掉就好了&#xff0c;或者设置划词快捷键翻译就好了&#xff0c;反正就不要一划就翻译那…

数据仓库【2】:架构

数据仓库【2】&#xff1a;架构 1、架构图2、ETL流程2.1、ETL -- Extract-Transform-Load2.1.1、数据抽取&#xff08;Extraction&#xff09;2.1.2、数据转换&#xff08;Transformation&#xff09;2.1.3、数据加载&#xff08; Loading &#xff09; 2.2、ETL工具2.2.1、结构…

iMazing2024免费版iOS移动设备管理软件

以自己的方式管理iPhone&#xff0c;让备受信赖的软件为您传输和保存音乐、消息、文件和数据。安全备份任何 iPhone、iPad 或 iPod touch。iMazing 功能强大、易于使用&#xff0c;称得上是 Mac 和 PC 上最好的 iOS 设备管理器。 正在为iTunes繁琐的操作发愁&#xff1f;设备数…

基于SpringBoot+Vue实现的电影院售票系统

文章目录 项目介绍影院管理影片管理影厅管理订单管理用户管理角色权限管理 技术选型成果展示前台系统后台管理系统 账号及其他说明 项目介绍 基于SpringBootVue实现的电影院售票系统整体设计了用户、管理员两个角色。 用户登录系统可进行电影查看、分类查看、影片搜索、选择影…

Java之Atomic 原子类总结

Java之Atomic 原子类总结 Atomic 原子类介绍 Atomic 翻译成中文是原子的意思。在化学上&#xff0c;我们知道原子是构成一般物质的最小单位&#xff0c;在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候&#xff0c;一…