Linux kernel 中断子系统之gic介绍

http://www.wowotech.net/irq_subsystem/interrupt_subsystem_architecture.html

https://www.bilibili.com/video/BV1bD4y127dg?from=search&seid=11165508187878472473 

BiliBili作者博客https://blog.csdn.net/weixin_42135087/category_9540436.html

https://blog.csdn.net/sunsissy/article/details/73791470

https://zhuanlan.zhihu.com/p/363129733

 

依据BiliBili视频整理的GIC中断笔记

general interrupt controller

GIC中断控制器的分类:gicv1(已弃用),gicv2,gicv3,gicv4.

比如RK3288的中断控制器gic-v400,就是支持gicv2架构版本

rk3288.dtsi

    gic: interrupt-controller@ffc01000 {
        compatible = "arm,gic-400";
        interrupt-controller;
        #interrupt-cells = <3>;
        #address-cells = <0>;

        reg = <0x0 0xffc01000 0x0 0x1000>,
              <0x0 0xffc02000 0x0 0x2000>,
              <0x0 0xffc04000 0x0 0x2000>,
              <0x0 0xffc06000 0x0 0x2000>;
        interrupts = <GIC_PPI 9 0xf04>;
    };

 

gic的的核心功能,就是对soc中外设的中断源的管理,并且提供给软件,配置以及控制这些中断源.

如果没有GIC,那么外部的所有中断都需要直接连线到CPU,又gic,中断先到gic,处理后再到CPU,

1.当对应的中断源有效时,GIC根据该中断源的配置,决定是否将该中断信号,发生给cpu,如果有多个中断源有效,那么gic还会锦绣仲裁.选择最高优先级中断,发送给CPU.

2.当CPU接受到gic发送的中断,通过读取gic的寄存器,就可以知道,中断源的来源来自哪里,从而可以做相应的处理.

3.当CPU处理完中断之后,会告诉GIC,其实就是访问gic的寄存器,该中断处理完毕.gic接受到该信息后,就将该中断源取消.避免又重新发送该中断给cpu以及允许中断抢占.

 

ARM-Core访问gic寄存器的两种方式:

1.memory-mapped的方式:SOC在设计的时候,预留了一块区域给gic,ARM-CORE通过读写该地址来读写gic寄存器.

2.通过系统寄存器的方式:通过MSR/MRS来进行读写

gicv2的所有寄存器都是适用memory-map方式.

 

从gicv2架构图,可以,gic中的中断类型有:

SGI:软件中断,0~15(一般0-7给REF,8~15给TEE),相当于IPI,CPU core之间中断,通过向ICDSGIR寄存器写入SGI中断号/CPU ID,来产生一个软件中断.

PPI:私有外设中断,16~31,发送给特定CPU,每个CPU连接5个私有中断,

SPI:共享外设中断,32~1019,可以多个CPU或者core处理,不限定特定CPU,由各种IO控制器和存储器控制器产生,如             GPIO/DMA/定时器等.

虚拟中断:用于支持虚拟机

中断类型:边沿触发&电平触发

Group分组:

group0:安全中断,由nFIQ驱动

group1:非安全中断,由nFIQ驱动

gicv2的旁路/bypass功能:

GICV2支持中断旁路模式,也就是GPIO外部的FIQ,IRQ直接接到core的FIQ,IRQ上,相当于gic是不使能的.

GICV2资产bypass功能,gic不起作用,core的中断管脚,直接由soc的其他部门信号驱动.

 

Linux内核中断管理:

以SPI中断为例:

当中断产生后,中断信号传送给gic,gic组件进行管理和仲裁,然后再将中断信息 发送给响应的CPU,CPU随后进行FIQ IRQ 异常程序.然后跳到irq_handler->gic_handle_irq()

 

中断底半部实现

tasklet:执行在软中断上下文中(不可睡眠和调度)

           在中断函数里调用tasklet_schedule(),会在适当的时候执行my_tasklet_func

工作队列:执行在内核线程上下文(可以睡眠和调度)

软中断(softirq):定时器/网络/块设备/RCU等

thread_irq:request_thread_irq()

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值