在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

posted @ 2022-07-21 15:33  Sky&Zhang  阅读(165)  评论(0编辑  收藏  举报