当前位置: 首页 > news >正文

Linux之中断子系统-中断控制器的中断函数gic_handle_irq分析(5)

1.概述

在前面文章中,已经分析汇编函数, 最终调用的是handle_arch_irq或arch_irq_handler_default函数。以zynq7k为例,其采用的是GIC pl390中断控制器,gic初始化的时候调用set_handle_irq函数,将handle_arch_irq函数指针指向了 gic_handle_irq 。因此这里以zynq7为例,介绍Linux内核对uart0的中断处理过程。
 

2.GIC中断入口函数

底层irq_handler调用gic_handle_irq处理中断,从函数名可以看出,此时的中断处理和具体的中断控制器有关,arm平台上中断控制器一般都为gic。传入的参数为struct pt_regs *regs,指向了保存中断发生时刻的寄存器信息地址。首先读取中断响应寄存器ICCIAR,获取硬件中断号及产生SGI中断的CPU ID,根据硬件中断号,判断中断类型。当读取了ICCIAR寄存器后,表示此CPU响应了中断,在此cpu处理完该中断之前,gic中断控制器不会再向此cpu发送任何中断。PPI中断和SPI中断调用handle_domain_irq处理,SGI中断调用handle_IPI处理。当然,SGI中断在SMP系统中才有效,在UP系统中无效,不做处理。 从下面的代码可以看出,整个中断处理逻辑是在一个死循环中,只要能从ICCIAR寄存器中读出有效的硬件中断号,就会一直进行中断处理,也就是说,只要中断一直产生,则中断服务函数gic_handle_irq会一直运行,不会退出。这正是Linux内核设计巧妙的地方,进入中断处理程序后,会处理所有pending或者active and pending状态的中断,直到没有中断产生,中断处理函数才退出,避免频繁进入和退出中断处理程序导致的性能下降。
 

    [drivers/irqchip/irq-gic.c]static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly;gic_handle_irqstruct gic_chip_data *gic = &gic_data[0]  // 获取gic设备结构体指针->gic_data_cpu_base  // 获取GIC CPU interface的基地址空间do {// 读取中断响应寄存器ICCIAR,读取后就清除了gic中的中断,gic中对应的中断状态由pending变为acting// ICCIAR的[bit9-0]为硬件中断ID,SPI和PPI中断用到,[bit12-10]产生中断的CPU的ID,SGI中断用到irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);irqnr = irqstat & GICC_IAR_INT_ID_MASK;  // 获取ICCIAR的[bit9-0],即硬件中断号if (likely(irqnr > 15 && irqnr < 1020)) {  // PPI和SPI中断走此流程// 如果支持priority drop(降低优先级)and deactivation operations(中断状态变化)分离,// 则先写ICCEOIR寄存器,中断完成后再写ICCDIR寄存器,表示中断处理完成,zynq7不支持if (static_key_true(&supports_deactivate))writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);handle_domain_irq(gic->domain, irqnr, regs);->__handle_domain_irqcontinue;}if (irqnr < 16) {  // SGI中断走此流程writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);if (static_key_true(&supports_deactivate))writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);#ifdef CONFIG_SMP  // SMP系统中,SGI中断才真正有意义/** Ensure any shared data written by the CPU sending* the IPI is read after we've read the ACK register* on the GIC.** Pairs with the write barrier in gic_raise_softirq*/smp_rmb();handle_IPI(irqnr, regs);  // SGI中断处理函数,内核中将软件产生的中断叫IPI中断#endifcontinue;}break;  // 直到没有处于pending或者active and pending状态的中断,才跳出循坏,退出中断处理程序} while (1)

gic_handle_irq函数调用handle_domain_irq处理PPI和SPI中断,首先根据硬件中断号找到软件中断号,根据软件中断号找到对应的中断描述符irq_desc,调用中断描述符中的通用中断处理函数handle_irq,zynq7k平台的通用中断处理函数handle_irq指向了handle_fasteoi_irq函数。__handle_domain_irq开始调用了irq_enter,用来增加preempt_count成员里HARDIRQ域的值,HARDIRQ域的值大于0,则表示此进程处于硬件中断上下文中,否则表示此进程不处于硬件中断上下文,__handle_domain_irq退出时调用irq_enter,递减preempt_count成员里HARDIRQ域的值,并判断当前上下文是否处于硬件中断和是否有软中断pending,如当前上下文不处于硬件中断并且有软中断pending,则处理软件中断。

    handle_domain_irq->__handle_domain_irq->irq_enter  // 进入中断上下文->__irq_enter// 增加当前进程struct thread_info中的preempt_count成员里HARDIRQ域的值// HARDIRQ域用于判断当前进程是否处于硬件中断上下文->preempt_count_add(HARDIRQ_OFFSET)->irq_find_mapping  // 根据中断控制的irq_domain和硬件中断号,获取软件中断号// 如果硬件中断号小于直接映射的最大中断号,则直接比较dom
http://www.dtcms.com/a/603287.html

相关文章:

  • 社交网站开发平台建工在线
  • Agentic AI TASK02 Reflection Design and Pattern
  • 撰写网站专题活动策划方案网站备案域名购买
  • 2014 吉林省赛题解 | CCUT应用OJ题解——F[X] + X = N
  • 如何做网站使用手册两个网站如何使用一个虚拟主机
  • 【云运维】Kubernetes 安装(基于Containerd+Calico)
  • 芜湖高端网站建设网站推广 济南
  • 公共部门网站建设维护网站挂黑链
  • wordpress怎么做的wifi优化大师下载
  • 免费婚庆网站模板嵌入式网站开发培训
  • 网站关键词先后开发公司安全管理组织机构图
  • 网站建设域名什么意思wordpress插件点不开
  • wordpress怎样建立多站点手机百度账号登录个人中心
  • 2025-11-12[第三大的数、将x减到0的最小操作数]
  • 基层建设刊物网站建筑工程网签备案合同
  • 强化学习基础概念与核心算法全解析
  • 解释型与编译型编程语言的区别 | 深入了解两者的工作原理与优劣
  • 人工智能网站应怎么做长春市长春网站建设哪家好
  • 建宣传网站北京营销策划公司有哪些
  • 网站系统开发毕业设计网站建设ppt百度文库
  • 2.2 前向传播与反向传播:深度学习的核心机制全解析
  • 山东省建设厅官方网站怎么样如何创建网站?
  • UrealEngine-5.2.1源码-AbilitySystemComponent.h
  • FPGA教程系列-Vivado中FIFO的简单仿真分析
  • 网站开发需要什么工具公司介绍怎么写范本
  • 网站建设责任书广东省建设厅官方网站网址
  • WebView 远程调试全指南,跨端真机调试的完整解决方案
  • wordpress企业网站 教程wordpress站点标题
  • 网站建设的职责dedecms 金融类网站模板
  • STM32的电子钟功能实现