Interrupt Pipeline系列文章大纲-CSDN博客
2.4.1 el0_sync代码框架
沿着vectors->kernel_ventry 0,irq ->el0_sync进行分析。首先读取ESR_EL1寄存器,向右移位ESR_ELx_EC_SHIFT(26)得到异常发生的原因(Bit 31~26),然后跳转到相应的分支继续处理。整个过程,类似于C语言中的switch case语句。
在entry.S中,引入I-pipe patch之后,el0_sync自身及其跳转的分支,都没有代码变化。唯一值得注意的是,所有的分支最终都是调用ret_to_user返回到用户层。
/* * EL0 mode handlers. */ .align 6 el0_sync: kernel_entry 0 mrs x25, esr_el1 // read the syndrome register lsr x24, x25, #ESR_ELx_EC_SHIFT // exception class cmp x24, #ESR_ELx_EC_SVC64 // SVC in 64-bit state b.eq el0_svc cmp x24, #ESR_ELx_EC_DABT_LOW // data abort in EL0 b.eq el0_da cmp x24, #ESR_ELx_EC_IABT_LOW // instruction abort in EL0 b.eq el0_ia cmp x24, #ESR_ELx_EC_FP_ASIMD // FP/ASIMD access b.eq el0_fpsimd_acc cmp x24, #ESR_ELx_EC_SVE // SVE access b.eq el0_sve_acc cmp x24, #ESR_ELx_EC_FP_EXC64 // FP/ASIMD exception b.eq el0_fpsimd_exc cmp x24, #ESR_ELx_EC_SYS64 // configurable trap b.eq el0_sys cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception b.eq el0_sp_pc cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception b.eq el0_sp_pc cmp x24, #ESR_ELx_EC_UNKNOWN // unknown exception in EL0 b.eq el0_undef cmp x24, #ESR_ELx_EC_BREAKPT_LOW // debug exception in EL0 b.ge el0_dbg b el0_inv |
2.4.2 返回用户空间
1 | ret_to_user: | ||
2 | #ifdef CONFIG_IPIPE | ||
3 | disable_daif | ||
4 | ldr | x0, [tsk, #TSK_TI_IPIPE] | |
5 | tst | x0, #_TIP_HEAD | |
6 | b.eq | ret_to_user_noirq | |
7 | kernel_exit 0 | ||
8 | #endif |
第3行,关闭daif共4个中断屏蔽标识
第4~5行,检查TSK_TI_IPIPE中是否设置了_TIP_HEAD标记。TSK_TI_IPIPE定义在arch/arm64/kernel/asm-offsets.c;_TIP_HEAD定义在arch/arm64/include/asm/thread_info.h。根据注释,它代表进程运行在HEAD域。
DEFINE(TSK_TI_IPIPE, offsetof(struct task_struct, thread_info.ipipe_flags));
第6行,如果TSK_TI_IPIPE中没有设置_TIP_HEAD标记,第14行tst指令(相当于ands)结果为0,则Z标志位为1,b.eq判断条件成立。说明当前进程处于ROOT域,跳转到ret_to_user_noirq。此后的流程与2.3.5.2小节流程相同。
第7行,如果TSK_TI_IPIPE中设置_了TIP_HEAD标记,第14行tst指令(相当于ands)结果为1,则Z标志位为0,b.eq判断条件不成立。说明当前进程处于HEAD域即Xenomai实时进程,直接通过kernel_exit 0返回用户层。
点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-CSDN博客
原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!