GIC驱动程序分析

一、一级中断控制器处理流程

对于irq_desc,内核有两种分配方法:

  1. 一次分配完所有iqr_desc
  2. 按需分配(用到某个中断才分配它的irq_desc

现在的内核基本使用第二种方法。
在这里插入图片描述

  • 假设GIC可以向CPU发出16 ~ 1019号中断,这些数字被称为hwirq。0 ~ 15用于Process之间通信,比较特殊
  • 假设要使用UART模块,它发出的中断连接到GIC的32号中断,分配的irq_desc序号为16
  • GIC domain中会记录(32,16)
  • 那么注册中断时就是:request_irq(16, ...),把处理程序注册进irqaction
  • 发生UART中断时
    • 程序从GIC中读取寄存器知道发生了32号中断,通过GIC irq_domain可以知道virq为16
    • 调用irq_desc[16]中的handlerA函数,它的作用是调用action链表中用户注册的函数

二、多级中断控制器处理流程

在这里插入图片描述

  • 假设GPIO模块下有4个引脚,都可以产生中断,都连接到GIC的33号中断
  • GPIO也可以看作一个中断控制器,对于它的4个中断
  • 对于GPIO模块中0 ~ 3这四个hwirq,一般都会一下子分配四个irq_desc
  • 假设这4个irq_desc的序号为100 ~ 103,在GPIO domain中记录(0, 100) (1,101) (2,102) (3,103)
  • 对于KEY,注册中断时就是:request_irq(102, ...)
  • 按下KEY时:
    • 程序从GIC中读取寄存器知道发生了33号中断,通过GIC irq_domain可以知道virq为16
    • 调用irq_desc[16]中的handleB函数
      • handleB读取GPIO寄存器,确定是GPIO里2号引脚发生中断
      • 通过GPIO irq_domain可以知道virq为102
      • 调用irq_desc[102]中的handleA函数,它的作用是调用action链表中用户注册的函数

程序先是通过request_irq注册处理函数,和分配虚拟中断号,使得硬件中断号和虚拟中断号产生联系,并存储在irq_domain中。
当硬件触发时,CPU通过硬件中断号,判断哪个中断触发了,通过关联的软件中断号,找到对应的处理函数。
处理函数时,需要把对应的中断屏蔽住,处理完后再恢复。

有时候另一些情况时,像GPIO会有多个中断号,那么每个不同的中断号也会有不同的软件中断号,对应的处理函数也不一样。

三、GIC中的重要函数和结构体

沿着中断的处理流程,GIC涉及这4个重要部分:

  • CPU从异常向量表中调用handle_arch_irq,这个函数指针是由GIC驱动设置的
    • GIC才知道怎么判断发生的是那个GIC中断
  • 从GIC获取hwirq后,要转换为virq:需要有GIC Domain
  • 调用irq_desc[virq].handle_irq函数:这也应该由GIC驱动提供
  • 处理中断时,要屏蔽中断、清除中断等:这些函数保存在irq_chip里,由GIC驱动提供

从硬件上看,GIC功能:

  • 可以使能、屏蔽中断
  • 发生中断时,可以从GIC里判断是哪个中断

在内核里,使用gic_chip_data结构体表示GIC,gic_chip_data里有:

  • irq_chip:中断使能、屏蔽、清除,放在irq_chip中的各个函数里实现
// drivers/irqchip/irq-gic.c
static const struct irq_chip gic_chip = {
    .irq_mask       = gic_mask_irq,
    .irq_unmask     = gic_unmask_irq,
    .irq_eoi        = gic_eoi_irq,
    .irq_set_type       = gic_set_type,
    .irq_get_irqchip_state  = gic_irq_get_irqchip_state,
    .irq_set_irqchip_state  = gic_irq_set_irqchip_state,
    .flags          = IRQCHIP_SET_TYPE_MASKED |
                  IRQCHIP_SKIP_SET_WAKE |
                  IRQCHIP_MASK_ON_SUSPEND,
};

  • irq_domain
    • 申请中断
      • 在设备树里指定hwirq、flag,可以使用irq_domain的函数来解析设备树
      • 根据hwirq可以分配virq,把(hwirq, virq)存入irq_domain
    • 发生中断时,从GIC读取hwirq,可以通过irq_domain找到virq,再找到处理函数
      所以GIC用gic_chip_data来表示,gic_chip_data中重要的成员是:irq_chipirq_domain
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

习惯就好zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值