This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cortex-A53 switching from EL2 to EL1

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?

Parents
  • But shouldn't be these exceptions catched in VBAR_EL2? I also setup a vector table and handlers for EL2 (bl _cpu_el2_vec_tbl_set).

    The handler for EL2 are also called, when i force (quick and dirty) an exception.

    Have tried it. But without success.

    The current code:

    __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	SPsel, #1
        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
        mov x0, xzr
        orr x0, x0, #(1 << 31)
        msr HCR_EL2, x0
        adr x0, __el1
        mov x1, xzr
        orr x1, x1, #(3 << 6) /* Mask IRQ/FIQ */
        orr x1, x1, #(1 << 2)
        orr x1, x1, #(1 << 0)
        msr SPSR_EL2, x1
        msr ELR_EL2, x0
        eret
        
    __el1:

Reply
  • But shouldn't be these exceptions catched in VBAR_EL2? I also setup a vector table and handlers for EL2 (bl _cpu_el2_vec_tbl_set).

    The handler for EL2 are also called, when i force (quick and dirty) an exception.

    Have tried it. But without success.

    The current code:

    __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	SPsel, #1
        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
        mov x0, xzr
        orr x0, x0, #(1 << 31)
        msr HCR_EL2, x0
        adr x0, __el1
        mov x1, xzr
        orr x1, x1, #(3 << 6) /* Mask IRQ/FIQ */
        orr x1, x1, #(1 << 2)
        orr x1, x1, #(1 << 0)
        msr SPSR_EL2, x1
        msr ELR_EL2, x0
        eret
        
    __el1:

Children