如何解决尝试切换到较低的异常级别时,AArch64 执行在 ERET 后停止
出于教育目的,我已经启动了 AArch64 的裸机应用程序。当我不将异常级别更改为较低级别时,它工作正常。但是当我想尝试将异常级别从 EL2
更改为 EL1
时,cpu 似乎在 ERET
指令之后挂起。
我当前的启动代码:
#include <asm.h>
IMPORT_ASM(_cpu_el3_vec_tbl_set)
IMPORT_ASM(_cpu_el2_vec_tbl_set)
IMPORT_ASM(_cpu_el1_vec_tbl_set)
IMPORT_C(init)
IMPORT_C(main)
.text
ENTRY(_start)
mrs x0,MPIDR_EL1
and x0,x0,#0x3
cmp x0,#0
beq __elx
__wfe_cpu1_3:
wfe
b __wfe_cpu1_3
__elx:
__el3:
mrs x0,CurrentEL
and x0,#0xC
asr x0,#2
cmp x0,#3
bne __el2
__el3_stack:
ldr x0,=_stack_el3_e
mov sp,x0
__el3_vector:
bl _cpu_el3_vec_tbl_set
msr SCTLR_EL2,xzr
msr HCR_EL2,xzr
mrs x0,SCR_EL3
orr x0,#(1<<10)
orr x0,#(1<<0)
msr SCR_EL3,x0
mov x0,#0b01001
msr SPSR_EL3,x0
adr x0,__el2
msr ELR_EL3,x0
eret
__el2:
mrs x0,#2
bne __el1
__el2_stack:
ldr x0,=_stack_el2_e
mov sp,x0
__el2_vector:
bl _cpu_el2_vec_tbl_set
msr SCTLR_EL1,xzr
mov x0,xzr
orr x0,#(1 << 31)
msr HCR_EL2,x0
/*orr x0,#(7 << 6) */
adr x0,__el1
mov x1,xzr
orr x1,x1,#(1 << 2)
orr x1,#(1 << 0)
msr SPSR_EL2,x1
msr ELR_EL2,x0
eret
__el1:
__el1_stack:
ldr x0,=_stack_el1_e
mov sp,x0
__el1_vector:
bl _cpu_el1_vec_tbl_set
ldr x0,=_bss_s
ldr x1,=_bss_e
sub x1,x0
mov x2,#0x0
cbz x1,__init
__bss:
strb w2,[x0],#1
sub x1,#1
cbnz x1,__bss
__init:
bl init
__main:
bl main
__main_wfe:
wfe
b __main_wfe
.end
当我注释掉标签 __elx
到 __el1
之间的部分时,它会起作用(C 函数 init
和 main
将被执行)。我还尝试在 init
指令之前和之后放置 ERET
(目前只包含一个函数,它通过 UART 打印出当前异常级别)。结果是,永远不会执行 init
之后的 ERET
调用。
不知道这里出了什么问题。
编辑:
我还创建了一个带有 EL2
和 EL1
处理程序的向量表。但不幸的是不会抛出异常。
更新:
好的,将输入 EL1
。但是在 EL1
中运行时,我的 C 代码的某些部分有一些奇怪的问题:
首先:EL1
中的 C 代码执行速度(主观上)比 EL2
中慢。
第二:
C 代码中的某些部分(我的 sprintf
实现)没有被调用。这里的奇怪之处在于 sprintf
,它在 EL2
中没有问题。
HCR_EL2
和/或 SCTLR_EL1
的配置可能有误吗?
目前我用零初始化 HCR_EL2
和 SCTLR_EL1
,并在 RW
中设置 HCR_EL2
位(AArch64 状态)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。