轉自: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