5.1 先验知识

驱动模型:Linux建立了一个统一的设备模型,分别采用总线、设备、驱动三者进行抽象,其中设备和驱动均挂载在总线上面,当有新的设备注册或者新的驱动注册的时候,总线会进行匹配操作(match函数),当发现驱动和设备能进行匹配的时候,就会执行probe函数的操作

对于PCI:PCI设备,PCI总线和PC驱动的创建,PCI设备和PCI驱动挂接在PCI总线上面

对于PCIe的控制器,遵循设备,总线,驱动的匹配模型,这里的总线是由虚拟总线platform总线来替代,相应的设备和驱动分别为platform_device和platform_driver;

5.2 PCIe驱动程序的实现

5.2.1 Linux PCI的初始化过程

Linux PCI初始化的主要工作是遍历当前处理器系统中的所有PCI总线树,并且初始化PCI总线树上面的全部设备,包括PCI桥和PCI Agent设备。在Linux系统中,多次使用DFS算法对PCI总线树进行遍历查找,并分配相关的PCI总线号与PCI总线地址资源。

*参考博客:*【原创】Linux PCI驱动框架分析(三) - LoyenWang - 博客园

1.设备树

设备树用于描述硬件的信息,包含节点各类属性,在dts文件中定义,最终编译为dtb文件加载到内存中

内核会在启动过程中解析dtb文件,解析为device_node描述的Device Tree;

根据device_node节点,创建platform_device结构,并最终注册进系统,这个也就是PCIe设备的创建过程。

2.probe流程

系统会根据dtb文件创建对应的platform_device并进行注册;

当驱动与设备通过compatible字段匹配上后,会调用probe函数,也就是nwl_pcie_probe;

看一下nwl_pcie_probe函数:

通常probe函数都是进行一些初始化操作和注册操作:

  1. 初始化包括:数据结构的初始化以及设备的初始化等,设备的初始化则需要获取硬件的信息(比如寄存器基地址,长度,中断号等),这些信息都是从DTS获取

  2. 注册操作主要是包含中断处理函数的注册,以及通常的设备文件注册等。

针对PCI控制器的驱动,核心的流程是需要分配并且初始化一个*pci_host_bridge*结构,最终通过这个*bridge*去枚举PCI总线上的所有设备;

*devm_pci_alloc_host_bridge*:分配并且初始化一个基础的pci_host_bridge结构

*nwl_pcie_parse_dt*:获取DTS中的寄存器信息以及中断信息,并且通过*irq_set_chained_handler_and_data*设置intx中断号对应的中断处理函数,该处理函数用于中断的级联;

*nwl_pcie_bridge_init*:硬件的Controller一堆设置,这部分需要查阅Spec,了解硬件工作细节。此外,通过*devm_request_irq*注册misc中断号对应的中断处理函数,该处理函数,该处理函数用于控制器自身状态的处理;

*pci_parse_request_of_pci_ranges*:用于解析PCI总线的总线范围和总线上的地址范围,也就是CPU可以看到的地址区域

*nwl_pcie_init_irq_domain**mwl_pcie_enable_msi*与中断级联相关

pci_scan_root_bus_bridge:对总线上的设备进行*扫描枚举*,(枚举具体介绍:【原创】Linux PCI驱动框架分析(二) - LoyenWang - 博客园)bridge结构体中的pci_ops字段,用于指向PCI的读写操作函数集,当具体扫描到设备要读写的配置空间的时候,调用的就是这个函数,由具体的Controller驱动实现

3.中断处理

PCIe控制器,通过PCIe总线连接各种设备,因此它本身充当一个中断控制器,级联到上一层的中断控制器(比如GIC),如下图:

PCIe总线支持两种中断的处理方式:

  1. Legacy Interrupt:总线提供INTA#,INTB#,INTC#,INTD#四根中断信号,PCI设备借助这四根信号使用电平触发方式提交中断请求;

  2. MSI(Message Signaled Interrupt)Interrupt:基于消息机制的中断,也就是往一个指定地址写入特定消息,从而触发一个中断;

针对两种处理方式,NWL PCIe驱动中,实现了两个irq_chip,也就是两种方式的中断控制器:

irq_domain对应一个中断控制器(irq_chip),*irq_domain负责将硬件中断号映射到虚拟中断号上面*

再来看一下nwl_pcie_enable_msi函数:

在该函数中主要完成的工作就是设置级联的中断处理函数,级联的中断处理函数中最终回去调用具体设备的中断处理函数;

总结,作为两种不同的中断处理方式,套路都是一样的,均为创建irq_chip中断控制器,为该中断控制器添加irq_domain,具体设备的中断响应流程如下:

1)设备连接在PCI总线上面,触发中断的时候,通过PCIe控制器充当的中断控制器路由到上一级控制器,最终路由到CPU;

2)CPU在处理PCIe控制器的中断时,调用它的中断处理函数,也就是上文中提到过的new_pcie_leg_handler,nwl_pcie_msi_handler_high,和nwl_pcie_leg_handler_low;

3)在级联的中断处理函数中,调用chained_irq_enter进入中断级联处理;

4)调用irq_find_mapping找到具体的PCIe设备的中断号;

5)调用generic_handle_irq触发具体的PCIe设备的中断处理函数执行;

6)调用chained_irq_exit退出中断级联的处理

4.总结

各类的驱动,大体都是硬件初始化配置,资源申请注册,核心时处理和硬件的交互(一般就是中断的处理),如果需要用户来进行交互,则还需要注册设备文件,实现一堆file_operation操作函数集。

PCI驱动程序实现关键数据结构

PCI设备有三种地址空间:

PCI的I/O空间

PCI的存储空间

PCI的配置空间。

CPU可以访问PCI设备上的所有地址空间,其中I/O空间和存储空间提供给设备驱动程序使用,而配置空间则由Linux内核中的PCI初始化代码使用。内核在启动时负责对所有的PCI设备进行初始化,配置好所有的PCI设备,包括中断号以及I/O基址,并在文件 /proc/pci中列出所有找到的PCI设备,以及这些设备的参数和属性

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

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

相关文章

2.2 TF-A在ARM生态系统中的角色

目录2.2.1 作为ARM安全架构的参考实现2.2.2 与ARM处理器内核的协同关系2.2.3 在启动链中的核心地位2.2.4 与上下游软件的关系与底层固件的协作与上层软件的接口2.2.5 在ARM生态系统中的标准化作用2.2.6 典型应用场景2.2.1 作为ARM安全架构的参考实现 TF-A(Trusted …

Chrome 开发者警告:`DELETE err_empty_response` 是什么?jQuery AJAX 如何应对?

在Web开发的世界里,我们时常会遇到各种各样的错误信息,它们像一个个谜语,等待我们去破解。今天我们要聊的这个错误——DELETE err_empty_response,尤其是在使用 jQuery 的 $.ajax 发送 DELETE 请求时遇到,确实让人头疼。它意味着浏览器尝试删除某个资源,却收到了一个空荡…

python作业 1

1.技术面试题 (1)TCP与UDP的区别是什么? 答: TCP建立通信前有三次握手,结束通信后有四次挥手,数据传输的可靠性高但效率较低;UDP不需要三次握手就可传输数据,数据传输完成后也不需要…

centos7 java多版本切换

文章目录前言一、卸载原来的jdk二、下载jdk三、解压jdk三、配置环境变量四、切换JAVA环境变量前言 本来是为了安装jenkins,安装了对应的java,node,maven,git等环境,然后运行jenkins时候下载插件总是报错,我下载的jenkins是 2.346.1 版本&…

用Python和OpenCV从零搭建一个完整的双目视觉系统(四)

本系列文章旨在系统性地阐述如何利用 Python 与 OpenCV 库,从零开始构建一个完整的双目立体视觉系统。 本项目github地址:https://github.com/present-cjn/stereo-vision-python.git 在上一篇文章中,我们完成了相机标定这一最关键的基础步骤…

STM32-中断

中断分为两路:12345用于产生中断;678产生事件外设为NVIC设计流程:使能外设中断设置中断优先级分组初始化结构体编写中断服务函数初始化结构体:typedef struct {uint8_t NVIC_IRQChannel; 指定要使能或禁用的中断通道例如: TIM3_I…

Shader面试题100道之(61-80)

Shader面试题(第61-80题) 以下是第61到第80道Shader相关的面试题及答案: 61. 什么是UV展开?它在Shader中有什么作用? UV展开是将3D模型表面映射到2D纹理空间的过程,用于定义纹理如何贴合模型。在Shader中&a…

C#基础:Winform桌面开发中窗体之间的数据传递

1.主窗体using System; using System.Windows.Forms;public partial class MainForm : Form {public MainForm(){InitializeComponent();}// 打开二级窗体private void btnOpenSecondaryForm_Click(object sender, EventArgs e){// 创建二级窗体并订阅事件SecondaryForm second…

工程改Mvvm

导入CommunityToolKit vs2017只能导入7 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input;namespace WpfApp1.vi…

【HarmonyOS Next之旅】DevEco Studio使用指南(四十二) -> 动态修改编译配置

目录 1 -> 通过hook以及插件上下文实现动态配置 2 -> 在hvigorfile.ts中通过overrides关键字导出动态配置 3 -> 通过hook以及插件上下文动态配置构建配置 3.1 -> 修改每个hvigorNode中的build-profile.json5 3.2 -> 修改module.json5中的配置信息 3.3 -&g…

Android View事件分发机制详解

Android 的 View 事件分发机制是处理用户触摸(Touch)事件的核心流程,它决定了触摸事件如何从系统传递到具体的 View 并被消费。理解这个机制对于处理复杂的触摸交互、解决滑动冲突至关重要。 核心思想:责任链模式 事件分发遵循一个…

【CMake】自定义package并通过find_package找到

在一些场景下我们需要编写一些库,并希望其他程序可以找到这些库并引用。 CMake采用package这个概念来解决这个问题。 关于CMake的find_package文章有很多,但这些文章的内容大多不直观讲了一堆讲不到点子上,让人看了一头雾水。因此我想通过本文…

【MATLAB例程】AOA与TDOA混合定位例程,适用于二维环境、3个锚点的定位|附代码下载链接

本 MATLAB 程序实现了基于 Angle of Arrival (AOA) 与 Time Difference of Arrival (TDOA) 的二维定位方法,通过自适应融合与最小二乘优化,实现对未知目标的高精度估计。本例中固定使用了 3 个基站(锚点),算法框架支持…

磐维数据库panweidb集中式集群配置VIP【添加、删除和修改】

0 说明 panweidb集中式集群为了防止主备切换后应用连接无法切换到新主库,需要配置vip,应用可以只通过该ip与数据库连接,不用感知数据库在哪个节点上。 panweidb中配置 VIP主要依赖 CM 组件的 VIP 仲裁功能,通过回调脚本在主备切换…

python的保险业务管理与数据分析系统

前端开发框架:vue.js 数据库 mysql 版本不限 后端语言框架支持: 1 java(SSM/springboot)-idea/eclipse 2.NodejsVue.js -vscode 3.python(flask/django)–pycharm/vscode 4.php(thinkphp/laravel)-hbuilderx 数据库工具:Navicat/SQLyog等都可以 保险行业…

R语言如何接入实时行情接口

目录 1. 安装必要的R包 2. 导入库 3. 连接WebSocket 4. 处理连接成功后的操作 5. 处理接收到的消息 6. 处理连接关闭和错误 7. 发送心跳数据 8. 自动重连机制 9. 启动连接和重连 总结 在数据分析和金融研究中,实时行情数据的获取至关重要,但市…

Redis数据安全性分析

Redis高可用与数据安全机制深度解析前置知识:Redis基础安装与使用(主从复制、哨兵集群、Cluster集群搭建)一、Redis性能压测工具 工具名称:redis-benchmark核心作用:快速基准测试Redis性能使用场景:评估不同…

差分和前缀和

差分和前缀和的原理、用法和区别。前缀和(Prefix Sum)核心思想:预处理数组的前缀和,快速回答「区间和查询」 适用场景:数组静态(更新少、查询多),需要频繁计算任意区间的和1. 定义与…

C++并发编程-12. 用内存顺序实现内存模型

前情回顾 前文我们介绍了六种内存顺序,以及三种内存模型,本文通过代码示例讲解六种内存顺序使用方法,并实现相应的内存模型。全局一致性模型同步模型(获取和释放)松散模型memory_order_seq_cst memory_order_seq_cst代表全局一致性顺序&#…

AI测试革命:从智能缺陷检测到自愈式测试框架的工业实践

AI测试革命:从智能缺陷检测到自愈式测试框架的工业实践 希望对大家有用! 目录AI测试革命:从智能缺陷检测到自愈式测试框架的工业实践希望对大家有用!一、传统测试之殇:工业质检的切肤之痛二、智能缺陷检测系统架构1. …