本文的目的在在于介绍中断控制器的注册过程及中断的处理,从软件系统的角度理解级联中断控制器。
背景:Arm64处理器、Linux-4.14内核
目录
1.内核中关于中断控制器的宏定义
在介绍中断控制器的注册前先介绍内核中关于中断控制器几个宏定义:
1.1 IRQCHIP_DECLARE 宏
用于实现中断控制器的of_device_id结构,该数据结构会在__irqchip_of_table内核代码段。
#define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
#define OF_DECLARE_2(table, name, compat, fn) \
_OF_DECLARE(table, name, compat, fn, of_init_fn_2)
#if defined(CONFIG_OF) && !defined(MODULE)
#define _OF_DECLARE(table, name, compat, fn, fn_type) \
static const struct of_device_id __of_table_##name \
__used __section(__##table##_of_table) \
__aligned(__alignof__(struct of_device_id)) \
= { .compatible = compat, \
.data = (fn == (fn_type)NULL) ? fn : fn }
#else
#define _OF_DECLARE(table, name, compat, fn, fn_type) \
static const struct of_device_id __of_table_##name \
__attribute__((unused)) \
= { .compatible = compat, \
.data = (fn == (fn_type)NULL) ? fn : fn }
#endif
1.2 IRQCHIP_OF_MATCH_TABLE宏
因为CONFIG_IRQCHIP有定义,所以宏的意义为定义了变量__irqchip_of_table、并指定了该变量在内核代码段的空间,其起始地址__irqchip_of_table段的开始、结束地址为__irqchip_of_table_end段起始地址。
#define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip)
#define OF_TABLE(cfg, name) __OF_TABLE(IS_ENABLED(cfg), name)
#define __OF_TABLE(cfg, name) ___OF_TABLE(cfg, name)
#define ___OF_TABLE(cfg, name) _OF_TABLE_##cfg(name)
#define _OF_TABLE_1(name) \
. = ALIGN(8); \
__##name##_of_table = .; \
KEEP(*(__##name##_of_table)) \
KEEP(*(__##name##_of_table_end))
1.3 irqchip相关变量
/* 路径 Drivers/irqchip/irqchip.c */
/* irqchip_of_match_end 为__irqchip_of_table_end段地址,
irqchip_of_match_end 表示 __irqchip_of_table数组结构的结束 */
static const struct of_device_id irqchip_of_match_end __used __section(__irqchip_of_table_end);
extern struct of_device_id __irqchip_of_table[];
__irqchip_of_table 数组中存放了通过IRQCHIP_DECLARE定义的个中断控制器的of_device_id结构数据。通过__irqchip_of_table 和 irqchip_of_match_end 变量可以知道系统中的所有的控制器的of_device_id结构数据。
因为__irqchip_of_table section在init data段,所以该段的数据内核完成init后其也会被释放,故__irqchip_of_table、irqchip_of_match_end 变量也在只在系统初始化完成前有意义。
2.中断控制器设备注册
2.1 root interrupt controller
通过上文《处理器中的级联中断控制器-优快云博客》可知该系统的根中断控制器为gicv3,gicv3通过IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init)宏实现了of_device_id结构__of_table_gic_v3变量的定义,该变量链接到__irqchip_of_table 数据段、系统通过__irqchip_of_table 数组来访问__irqchip_of_table 数据段、进而间接的实现了__of_table_gic_v3->gic_of_init的访问。
2.1.1 系统初始化GICV3中断控制器的流程
![]()
如图内核在启动过程中会通过of_irq_init函数来调用gicv3的初始化函数,of_irq_init函数是在内核初始化irqchip时被调用。
of_irq_init函数解析如下,该函数会调用通过IRQCHIP_DECLEAR宏或类似宏定义的与系统device node相匹配的中断控制器的初始化函数,完成中断控制器的初始化动作。
/**
* of_irq_init 函数用来在设备树中查找与matches数组匹配的中断控制器,并对该中断控制器进行初始化
* @matches:是指向内核__irqchip_of_table数据段的数组,该数组中包含代码中通过
* IRQCHIP_DECLEARE宏定义的所有中断控制器的of_device_id结构数据(不是所有的中断

本文详细介绍了Linux-4.14内核中的中断控制器注册过程,特别是GICV3的初始化,包括中断控制器设备的注册、中断级联关系的代码实现以及中断处理函数的执行流程。
最低0.47元/天 解锁文章
344

被折叠的 条评论
为什么被折叠?



