Hi,
I trying to switch from EL2 to EL1 on Cortex-A53. But it doesn't work.
Here is my current startup code:
#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, x0, #0xC asr x0, 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, x0, #(1<<10) orr x0, 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, CurrentEL and x0, x0, #0xC asr x0, x0, #2 cmp 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, x0, #(1 << 31) msr HCR_EL2, x0 /*orr x0, x0, #(7 << 6) */ adr x0, __el1 msr ELR_EL2, x0 mov x0, xzr orr x0, x0, #(1 << 2) orr x0, x0, #(1 << 0) msr SPSR_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, x1, x0 mov x2, #0x0 cbz x1, __init __bss: strb w2, [x0], #1 sub x1, x1, #1 cbnz x1, __bss __init: bl init __main: bl main __main_wfe: wfe b __main_wfe .end
When I comment out from label __elx to __el1 everything works (the C functions init and main are called).
I also setup a vector table and handlers for EL2 and EL1. But there is no exception.
I have no idea what's going wrong.
What's the correct way change to a lower exception level?
Now I used the initialization for SCTRL_EL1 from Linux.
But also not working. Still hangs.
mov x0, xzr orr x0, x0, #(1 << 11) orr x0, x0, #(1 << 20) orr x0, x0, #(1 << 22) orr x0, x0, #(1 << 28) orr x0, x0, #(1 << 29) msr SCTLR_EL1, x0