PCI中断处理

2023-05-16

首先在获得PCI配置空间资源的时候,就要获得中断资源,根据CM_PARTIAL_RESOURCE_DESCRIPTOR 结构的 Type 域来区分需要获得什么样的中断资源的时候,如果Type类型为:CmResourceTypeInterrupt,此时需要将中断资源从CM_PARTIAL_RESOURCE_DESCRIPTOR中取出:

irql = (KIRQL) resource->u.Interrupt.Level;              //中断级别

                            vector = resource->u.Interrupt.Vector;                     // 中断向量

                            affinity = resource->u.Interrupt.Affinity;

                            mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED)

                                     ? Latched : LevelSensitive;

                            irqshare = resource->ShareDisposition == CmResourceShareShared;

                            gotinterrupt = TRUE;

 

获取以上这些信心之后我们就可以注册中断,通过IoConnectInterrupt()函数来实现:

函数定义如下:

IoConnectInterrupt

OUT PKINTERRUPT *InterruptObject,//指向驱动程序提供的中断对象存储地址,该参数随后

//要传递给KeSynchronizeExecution。

OUT PKSERVICE_ROUTINE ServiceRoutine,//中断服务例程的入口

IN PVOID ServiceContext,//指向驱动指定的即将传递给ISR的参数,ServiceContext必须在

//常驻内存中,可以是驱动程序创建的设备驱动的设备扩展,也可

//以是驱动创建的控制对象的控制拓展,还可以是设备驱动分配的

//非分页内存。

IN PKSPIN_LOCK SpinLock OPTIONAL,//指向已经初始化的自旋所,驱动程序负责自旋所的存

//储,并且该自旋所将用来同步被驱动程序其它例程共

//享的数据的访问,该参数在ISR处理多个中断向量或

//者驱动程序包含不止一个ISR时需要设置,否则,驱

//动程序不需要为中断自旋所分配存储空间,参数设置

//为NULL。

IN ULONG Vector,                //输入获取的中断向量

IN KIRQL Irql,                    //输入获取的中断优先级DIRQL

IN KIRQL SynchronizeIrql,         //指明ISR执行所在的DIRQL,当ISR需要处理多个中断

//向量或者驱动程序有多个ISR的时候,该值选择全部中

//断资源的u.Interrupt.Level中的最高值,否则和上面的

//Irql变量相等。

IN KINTERRUPT_MODE InterruptMode,//电平触发或者边沿触发

IN BOOLEAN ShareVector,           //指明中断向量是否是可共享的。

IN KAFFINITY ProcessorEnableMask,//指定一个KAFFINITY值,用来说明设备中断可以在什

//么样的处理器平台上发生。

IN BOOLEAN FloatingSave          //指明是否需要保存设备中断时的浮点堆栈,在X86平

//台下,该值必须是FALSE。

);

实际使用时:

status = IoConnectInterrupt(&pdx->InterruptObject, (PKSERVICE_ROUTINE) ISRInterrupt,

                   (PVOID) pdx, NULL, vector, irql, irql, mode, irqshare, affinity, FALSE);

第二个参数为我们自定义的中断服务例程,当驱动通过这个函数接收中断,之后调用相应的DPC(deferred procedure calls,延迟过程调用)处理函数,DPC的使用主要是为了提高处理效率。但是首先要注册DPC处理函数,通过:

VOID KeInitializeDpc(

  __out     PRKDPC Dpc,

  __in      PKDEFERRED_ROUTINE DeferredRoutine,

  __in_opt  PVOID DeferredContext

);

来实现注册DPC处理函数。

实际应用:

KeInitializeDpc(&pdx->fdo->Dpc,DPCForISR,NULL);

 

BOOLEAN ISRInterrupt(PKINTERRUPT InterruptObject, PDEVICE_EXTENSION pdx)

{                                                               

         //中断响应,通知硬件该中断已经处理,不用再发该中断

         WRITE_REGISTER_ULONG((PULONG) &pdx->pHBARegs->IntrMask,0x00000001);

         pdx->inthw_cnt++;

         KeInsertQueueDpc(&pdx->fdo->Dpc,pdx->fdo,pdx->fdo->CurrentIrp );

         return TRUE;

}

在该函数中,将中断请求插入到中断处理队列中,交由DPC来处理

BOOLEAN KeInsertQueueDpc(

  __inout   PRKDPC Dpc,

  __in_opt  PVOID SystemArgument1,

  __in_opt  PVOID SystemArgument2

);

 

DPC的标准格式为:

KDEFERRED_ROUTINE CustomDpc;

 

VOID CustomDpc(

  __in      struct _KDPC *Dpc,

  __in_opt  PVOID DeferredContext,

  __in_opt  PVOID SystemArgument1,

  __in_opt  PVOID SystemArgument2

)

{ ... }

其中参数(注意来源):

Dpc [in]

Caller-supplied pointer to a KDPC structure, which represents the DPC object that is associated with this CustomDpc routine.

DeferredContext [in, optional]

Caller-supplied pointer to driver-defined context information that was specified in a previous call to KeInitializeDpc.

SystemArgument1 [in, optional]

Caller-supplied pointer to driver-supplied information that was specified in a previous call to KeInsertQueueDpc.

SystemArgument2 [in, optional]

Caller-supplied pointer to driver-supplied information that was specified in a previous call to KeInsertQueueDpc.

 

 

 

这里DPC可以这样设计:

VOID DPCForISR(IN PKDPC Dpc,IN PVOID Context,IN  PVOID fdo,IN PVOID pIrp)

{

         PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)

((PDEVICE_OBJECT)fdo)->DeviceExtension;

        

         KeAcquireSpinLock(&pdx->spinLock,&pdx->oldIrql);

//Int_stat 寄存器由硬件填写的

         int_status = READ_REGISTER_ULONG((PULONG) &pdx->pHBARegs->Int_stat);

         KdPrint(("interrupt!int status is 0x%0x\n",int_status));

         while(int_status) //循环处理中断,直到处理完

         {

                  

                   if(int_status >= INT_RECV_0 && int_status <= INT_RECV_23)

                   {

                            RecvTask(pdx,int_status-1);

                            pdx->recint_cnt[int_status-1]++;

                   }

                   if(int_status >= INT_LINK0_BUILD && int_status <= INT_LINK3_BUILD)

                   {

                            pdx->rx_fc_desc_buf_virt[int_status-25]->link_state=1;

                            pdx->bldint_cnt[int_status-25]++;

                            KdPrint(("Build!int status is 0x%0x\n",int_status));

                   }

                  

                   if(int_status >= INT_LINK0_BREAK && int_status <= INT_LINK3_BREAK)

                   {

                            pdx->rx_fc_desc_buf_virt[int_status-29]->link_state=0;

                            pdx->brkint_cnt[int_status-29]++;

                   }

                   pdx->intsw_cnt++;

                   int_status = READ_REGISTER_ULONG((PULONG) &pdx->pHBARegs->Int_stat);

                   KdPrint(("interrupt!int status is 0x%0x\n",int_status));

         }

        

         return ;             

}

在DPC中完成具体的操作,这样中断处理就结束了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PCI中断处理 的相关文章

  • SR850出现fault in slot ALL PCI error on system ThinkSystem SR850报错

    SR850出现fault in slot ALL PCI error on system ThinkSystem SR850报错 一 报错信息显示二 判断故障并修复 一 报错信息显示 服务器型号为lenovo SR850 xff0c XCC
  • PCI-E 1x, 4x, 8x, 16x 接口定义

    1 PCI E插槽及金手指实物图 xff08 1 xff09 PCI E插槽 从上至下依次为PCI E 4X PCI E 16X PCI E 1X xff08 2 xff09 PCI E金手指 PCI E 1X金手指PCI E 4X金手指P
  • 计算机组成原理2(PCI总线结构框图)

    文章目录 一 以存储器为中心的双总线结构框图二 PCI总线结构 一 以存储器为中心的双总线结构框图 双总线介绍 xff1a 该双总线结构在单总线的基础上开辟出了一条CPU与主存之间的总线 xff0c 称为存储总线 xff1b 这组总线速度高
  • 解决HTTPS证书安全检测时提示 PCI DSS 不合规问题

    解决HTTPS证书安全检测时提示 PCI DSS 不合规问题 今天在进行HTTPS证书安全检测时 xff0c 提示PCI DSS不合规 经查询得知是因为SSL配置时启用了TLS1 0导致的 关于 PCI DSS 自2018年6月30日起 x
  • pci和pcie的区别

    原文地址 xff1a https blog csdn net u013253075 article details 80835489 最近在学习驱动开发过程中涉及到PCI相关知识 xff0c 在网上看了很多文章 xff0c 良莠不齐 xff
  • 深入PCI与PCIe

    转载于老狼 xff1a https zhuanlan zhihu com p 26172972 https zhuanlan zhihu com p 26244141 PCI总线和设备树是X86硬件体系内很重要的组成部分 xff0c 几乎所
  • PCI-E 1x, 4x, 8x, 16x 接口定义

    1 PCI E插槽及金手指实物图 xff08 1 xff09 PCI E插槽 从上至下依次为PCI E 4X PCI E 16X PCI E 1X xff08 2 xff09 PCI E金手指 PCI E 1X金手指 PCI E 4X金手指
  • 中断处理handler不能sleep

    1 进入中断处理程序 gt 2 保存关键上下文 gt 3 开中断 xff08 sti指令 xff09 gt 4 进入中断处理程序的handler gt 5 关中 里面很多说法不是很同意 个人认为中断处理handler不能sleep原因应该不
  • Exynos_4412——中断处理(中断学习结尾篇)

    目录 一 ARM的异常处理机制 1 1异常概念 1 2异常处理机制 1 3ARM异常源 1 4异常模式 1 5ARM异常响应 1 6异常向量表 1 7异常返回 1 8IRQ异常举例 二 工程模板代码结构 三 中断处理框架搭建 四 中断处理程
  • Linux中断处理的“下半部”机制

    前言 中断分为硬件中断 xff0c 软件中断 中断的处理原则主要有两个 xff1a 一个是不能嵌套 xff0c 另外一个是越快越好 在Linux中 xff0c 分为中断处理采用 上半部 和 下半部 处理机制 一 中断处理 下半部 机制 中断
  • 【PCIe】1: PCIe 硬件时序初始化过程

    目录 1 前言 2 PCIe理论带宽 3 PCIe连接器引脚定义 4 关键信号描述 4 1 PERST 4 2 REFCLK 和REFCLK 信号
  • KVM重定向PCI

    应用场景 将服务器上的USB控制器 重定向到KVM中 一 修改KVM的配置文件 1 查看KVM的xml配置文件 KVM的配置文件存放在 etc libvirt qemu目录下 使用vi进行编辑 下面的这个KVM是重定向了一个PIC控制器 添
  • 【WiFi】wifi芯片架构与原理说明

    目录 1 概述 2 芯片架构 3 工作原理 4 总结 1 概述 WiFi芯片是一种用于无线网络通信的集成电路 它负责将数据转换为无线信号并进行传输 下面是关于WiFi芯片架构和原理的简要说明 2 芯片架构 芯片架构 WiFi芯片通常由以下几
  • 如何为可缓存 PCIe BAR 进行 mmap

    我正在尝试编写一个自定义驱动程序mmap PCIe BAR 的函数 目标是使该 BAR 可缓存在处理器缓存中 我知道这不是实现最高带宽的最佳方法 并且写入顺序是不可预测的 本例中也不是问题 这类似于中所描述的如何阻止 MMAP 缓存值 处理
  • macOS DriverKit:制作 PCI dext 来替换内置驱动程序

    我正在尝试在 DriverKit 中编写一个用户空间 PCI 驱动程序 用于教育 研究目的 我找到了一个来自 WorthDoingBadly 的示例其中包含 PCI 设备 dext 的样板代码 我已删除了漏洞利用代码 我已将其修改为通过以下
  • 写入端口 0cf8h 失败并出现段错误

    我有一个 e2 2000 型号的 AMD 处理器 这是 0fh 系列 根据 family 0fh BKDG 我有以下代码来读取设备和供应商 ID ReadPCIConfiguration movq 0x80000100 rax movq 0
  • 谁以及何时分配 PCI/PCIe 设备 BAR 基地址?

    我正在寻找内核如何进行 PCI PCIe 枚举和 BAR 分配 我以为内核会在启动时分配BAR的PCI基地址 但是当我尝试pci Earlydump 在内核初始PCI子系统之前 查看BAR的值时 我发现所有基地址都已经分配了 这是否意味着
  • 在多 GPU 系统中,如何将 OpenCL 设备与给定 PCI 供应商、设备和总线 ID 的特定 GPU 相匹配?

    我希望能够在由 PCI ID 标识的多 GPU 系统上将 OpenCL 设备与系统中的 GPU 进行匹配 例如 如果我的系统具有多个 GPU 可能来自不同的供应商 我可以通过枚举 PCI 总线来列出设备 这为我提供了 PCI 供应商 设备和
  • 在Linux中,有没有办法找出哪个PCI卡插入哪个PCI插槽?

    在Linux中 有没有办法找出哪个PCI卡插入哪个PCI插槽 sys bus pci devices 包含许多不是卡的设备 桥 CPU 通道等 我无法在设备目录中找到有关插槽卡映射的任何信息 您可以使用 dmidecode t slot 查
  • 我应该如何以非 root 身份读取 Linux 上的 Intel PCI 非核心性能计数器?

    我想要一个库 允许对 Linux 可执行文件的关键部分进行 自我分析 就像人们可以使用一个部分计时一样获取当日时间 http linux die net man 2 gettimeofday or RDTSC http www strchr

随机推荐

  • GPS RTK测量定位原理

    转自 xff1a https baijiahao baidu com s id 61 1603136753092877848 amp wfr 61 spider amp for 61 pc 手机定位是什么原理 xff1f 实时动态工程测量是
  • STM32学习笔记 - 串口的初始设置

    STM32学习笔记 串口的初始设置 1 声明结构体变量 GPIO InitTypeDef GPIO InitStructure GPIO InitTypeDef是一个结构体变量 xff0c 包括GPIO Pin xff08 u16类型 xf
  • STL 容器区别:vector、list、deque、set、map的底层实现

    文章转自 xff1a http blog csdn net lmh12506 article details 8445025 1 set和map 比较 setmap共同点都是无序的保存元素 xff0c 只是通过它提供的借口对里面的元素进行访
  • c++程序编译过程及相关概念

    编译 把源文件中的源代码翻译成机器语言 xff0c 保存到目标文件中 如果编译通过 xff0c 就会把CPP转换成OBJ文件 编译单元 xff1a 每个cpp就是一个编译单元 xff0c 每个编译单元相互之间是独立且相互不知的 一个编译单元
  • 单片机堆栈理解

    栈Stack xff1a 存储程序中函数内部变量 xff0c 参数 xff0c 被系统直接管理 xff0c 如果函数内部参数比较多 xff0c 可加大栈容量 堆Heap xff1a 程序员主动使用 xff0c malloc函数进行申请 xf
  • 超声换能器的结构

    超声换能器是超声系统的一个重要部件 xff0c 不论是哪一种类型的超声换能器 xff0c 其基本结构都是由压电材料 电极 声匹配层 声透镜 背衬和柔性电路板等组成 声透镜 Acoustic Lens xff1a 声透镜的形状通常是凸的 xf
  • QT 开发环境 第一个安卓程序 Hello world

    参考了很多文章 xff0c 这篇文章感觉是最好 xff0c 安装文章中的版本没有问题 文章链接 xff1a Qt5 12 1 for Android配置 简书 我最后卡在生成APK的时候 xff0c 出现 androiddeployqt e
  • 51单片机串口通讯接收一串字符串

    在51单片机中 xff0c 我们使用上下位机时 xff0c 我们通常会发送一串字符串 xff0c 将它作为信号发给单片机处理 因为串口通信时 xff0c 发送信息是以一个个字符的形式发送过来的 xff0c 所以接收的就是一个个字符 xff0
  • SQL统计查询

    病人表数据 检查表数据 1 统计年龄 1 1统计病人表中一段时间范围内的年龄病人数量 xff08 仅查询数据 xff09 select f Age count from workstationdb t patient INNER JOIN
  • installsheild 2020 安装过程中自动执行exe程序

    有时根据安装包的安装情况 xff0c 会在安装开始 xff0c 或安装过程中 xff0c 或安装结束后运行指定的exe程序 1 xff09 如果是在安装结束 xff0c 即点击安装的最后一个界面的 完成 按钮 xff0c 步骤参考下图 2
  • 详解VMWARE安装WINCE6.0(1)

    通过在网上查找大量资料终天把虚拟机中运行WINCE环境搭建起来 xff0c 首先感谢网上的诸多高手 xff0c 不过网上的资料大都不是很详细 xff0c 下面我算是一个总结吧 xff0c 方便以大家后学习 1 安装工具 xff08 1 xf
  • VS2005中控件不能添加变量(add variable)解决方法总结

    有时VS2005中右击添加变量 xff08 add variable xff09 变成灰色时 xff0c 会发现不能添加变量 经过在网上搜索总结如下 1 先clean xff0c 再重新build 2 将控制的ID重新命名 xff0c 再试
  • 在VB中调用C/C++语言编写的dll,数组参数的传递

    动态链接库 xff08 dll xff09 的好处就不多说了 xff0c 这里就把如何在VB中调用VC写的dll函数的方法介绍一下 xff0c 供有需要的朋友们参考 xff0c 同时也免得自己以后忘了 初次接触DLL的用户经常会遇到一个问题
  • 将C++转换成VB,C#语言小工具介绍

    在网上看到很多网友在 NET程序中调用Win32 API xff0c 或者调用自己的VC DLL里面提供的函数的时候 xff0c 总是被生成正确的C函数在C 中的正确声明而困扰 xff0c 而生成C 43 43 中结构体在C 中的声明 天
  • malloc,free在二级指针(指针的指针)的应用

    二维指针指针应该用for循环初始化 结束用for循环逐个释放 1 初始化 xff1a int pp 61 int malloc 12 sizeof int for int i 61 0 i lt 12 i 43 43 p i 61 int
  • MFC radio button互斥选择的重要几点

    MFC中的radio控件的互斥功能很常用 xff0c 一般在MFC资源中一个一个按顺序增加radio控件时不会有问题 但如果修改以前的代码 xff0c 需要重新增加几个radion时需要注意以下几点 1 新增加的radio的ID与旧的一定要
  • CListCtrl自动排序及添加排序箭头

    应客户要求 xff0c 在点击CListCtrl列表每列标题时进行排序 xff0c 类似于WINDOWS资源管理器的效果 首先在资源中添加LVN COLUMNCLICK消息 xff0c 生成OnLvnColumnclickListInfo函
  • 从零开始学习FFT(快速傅里叶变换) 这也是我学习dft算法的心得,谢谢各位

    本文是从最基础的知识开始讲解 xff0c 力求用最通俗易懂的文字将问题将的通俗易懂 xff0c 大神勿喷 xff0c 多多指教啊 xff0c 虽然说是从零学习 FFT xff0c 但是基本的数学知识还是要有的 xff0c sin xff0c
  • ZED相机python API配置

    之前安装了ZED SDK xff0c 在官网下载了CUDA10 2版本的ZEDSDK3 8 现在用python API对ZED相机进行二次开发 由于之前安装的python版本是3 10 xff0c 运行ZED SDK中的get python
  • PCI中断处理

    首先在获得PCI配置空间资源的时候 xff0c 就要获得中断资源 xff0c 根据CM PARTIAL RESOURCE DESCRIPTOR 结构的 Type 域来区分需要获得什么样的中断资源的时候 xff0c 如果Type类型为 xff