在Linux Kernel中有没有定义和实现FIQ向量【转】
转自:https://blog.csdn.net/weixin_42135087/article/details/120232824
👉👉👉 个人博客笔记导读目录(全部) 👈👈👈
.
说明:
在默认情况下,本文讲述的都是ARMV8-aarch64架构,linux kernel 5.14
先说答案:NO,或者说定义了FIQ向量,但底层实现就是调用了panic。也就是说在Linux Kernel是无法注册和处理FIQ中断的
在Linux Kernel的异常向量表中定义了FIQ的入口,那么看下FIQ进行了哪些处理呢?我们从el1_fiq开始分析.
el1_fiq其实就是调用handle_arch_fiq指向的函数
(linux/arch/arm64/kernel/entry.S)
SYM_CODE_START_LOCAL_NOALIGN(el1_fiq)
kernel_entry 1
el1_interrupt_handler handle_arch_fiq
kernel_exit 1
SYM_CODE_END(el1_fiq)
1
2
3
4
5
6
7
(linux/arch/arm64/kernel/entry.S)
.macro el1_interrupt_handler, handler:req
enable_da
mov x0, sp
bl enter_el1_irq_or_nmi
irq_handler \handler // 这里跳转到 handle_arch_fiq
......
如果系统没有调用set_handle_fiq()重新设置FIQ handler,那么handle_arch_irq将指向默认值default_handle_fiq
(注:其实在Linux Kernel中,在我们一般的配置中,不会调用set_handle_fiq,所以handle_arch_irq将指向的是默认值default_handle_fiq,即只要进入了FIQ向量入口,那么将会调用panic()函数)
(linux/arch/arm64/kernel/irq.c)
void (*handle_arch_irq)(struct pt_regs *) __ro_after_init = default_handle_irq;
void (*handle_arch_fiq)(struct pt_regs *) __ro_after_init = default_handle_fiq; // 这里定义了FIQ的默认值
int __init set_handle_fiq(void (*handle_fiq)(struct pt_regs *))
{
if (handle_arch_fiq != default_handle_fiq)
return -EBUSY;
handle_arch_fiq = handle_fiq; // 这里重新定义FIQ handler
pr_info("Root FIQ handler: %ps\n", handle_fiq);
return 0;
}
default_handle_fiq的实现,就是调用panic函数
(linux/arch/arm64/kernel/irq.c)
static void default_handle_fiq(struct pt_regs *regs)
{
panic("FIQ taken without a root FIQ handler\n");
}
为何会说"在Linux Kernel中,在我们一般的配置中,不会调用set_handle_fiq" 呢?
因为我们看到在Apple Interrupt Controller (AIC)控制的驱动程序中,是调用了set_handle_fiq的,也就是重新设置了FIQ Handler。
(linux/drivers/irqchip/irq-apple-aic.c)
set_handle_irq(aic_handle_irq);
set_handle_fiq(aic_handle_fiq);
1
2
3
4
5
《ARMv8/ARMv9架构学习系列课程》全系列,共计51节课,超15h的视频课程
————————————————
版权声明:本文为CSDN博主「代码改变世界ctw」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42135087/article/details/120232824