代码分析
分析完el2_setup的注释和代码段的位置之后,我们正式开始学习el2_setup的实现
SYM_FUNC_START(el2_setup)
msr SPsel, #1 // We want to use SP_EL{1,2}
mrs x0, CurrentEL
cmp x0, #CurrentEL_EL2
b.eq 1f
mov_q x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
msr sctlr_el1, x0
mov w0, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1
isb
ret
1: mov_q x0, (SCTLR_EL2_RES1 | ENDIAN_SET_EL2)
msr sctlr_el2, x0
异常等级
第二行需要参考ARM64的芯片手册,SPsel的值为0表示在任何异常等级下,都选择SP_EL0作为堆栈寄存器;
值为1表示选择异常等级对应的SP_ELX作为堆栈寄存器,X表示当前的异常等级。举例如下:
如果在 EL2 执行 msr SPsel, #1,则后续的 SP 会指向 SP_EL2(而不是 SP_EL0)。
如果在 EL1 执行 msr SPsel, #1,则 SP 会指向 SP_EL1(而不是 SP_EL0)。
第三行表示将当前的异常等级存入到x0寄存器。
CurrentEL_EL2 是个宏定义,定义如下
/* Current Exception Level values, as contained in CurrentEL */
#define CurrentEL_EL1 (1 << 2)
#define CurrentEL_EL2 (2 << 2)
第四行表示将当前的异常等级与EL2比较。
第五行表示如果当前的等级就是EL2则跳转到标签为1的代码去执行;
否则如果不相等,也就是说,如果当前的

最低0.47元/天 解锁文章
1260

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



