OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 3:56 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: AArch64 (Cortex-A53) - Switch to EL1 from EL2
PostPosted: Sun Jan 17, 2021 3:41 pm 
Offline

Joined: Tue Jan 28, 2020 12:11 am
Posts: 7
Location: Graz - Austria
Hi,

I have some troubles from switching from EL2 to EL1. No idea what's going wrong.
Used this documentation from the ARM website.

Current startup code:
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_el2_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
    mrs x0, HCR_EL2
    orr x0, x0, #(1<<31)
    msr HCR_EL2, x0
    mov x0, xzr
    orr x0, x0, #(7 << 6)
    orr x0, x0, #(1 << 2)
    orr x0, x0, #(1 << 0)
    msr SPSR_EL2, x0
    ldr x0, =__el1
    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, 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 the code from label __elx to __el1, the subsequent commands will be executed.
What's the correct way to switch to lower exception levels on AArch64?

I'm using U-Boot as bootloader on a PINE64 ROCK64 board.

_________________
Code:
/* Beware of bugs in the above code;
I have only proved it correct, not tried it. */

Original quote by Donald E. Knuth


Top
 Profile  
 
 Post subject: Re: AArch64 (Cortex-A53) - Switch to EL1 from EL2
PostPosted: Sun Jan 17, 2021 5:45 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
krjdev wrote:
I'm using U-Boot as bootloader
Are you sure that U-Boot doesn't set up EL1 for you?
krjdev wrote:
What's the correct way to switch to lower exception levels on AArch64?
I can't say what's wrong with your code, it looks ok to me (haven't dig deep though). Try to set up VBAR with a simple handler that dumps the reason and position of the exception. That way you can debug what's wrong.

About the correct way,
* take a look at the ARM Trusted Firmware, or
* see how the RaspberryPi firmware does it,
* and finally here's how I do it in my boot loader (tested and known to work, does EL3 -> EL1 as well as EL2 -> EL1 transition because qemu and real RPi does not start on the same EL level).

Hope these help.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: AArch64 (Cortex-A53) - Switch to EL1 from EL2
PostPosted: Sun Jan 17, 2021 6:58 pm 
Offline

Joined: Tue Jan 28, 2020 12:11 am
Posts: 7
Location: Graz - Austria
bzt wrote:
krjdev wrote:
I'm using U-Boot as bootloader
Are you sure that U-Boot doesn't set up EL1 for you?

Currently I read out CurrentEL also in the C function init and print the value via UART. And it returns EL2, but not sure if U-Boot set the HCR_EL2.NV bit.
Although I understand the documentation from CurrentEL, if the HCR_EL.NV flag is set, CurrentEL always returning EL2 at EL1.
bzt wrote:
I can't say what's wrong with your code, it looks ok to me (haven't dig deep though). Try to set up VBAR with a simple handler that dumps the reason and position of the exception. That way you can debug what's wrong.

I have setup the vector table (and exception handlers) for EL2 and EL1. But seems the CPU hangs. I doesn't execute the C function init (Currently it only outputs the current EL)
bzt wrote:
About the correct way,
* take a look at the ARM Trusted Firmware, or
* see how the RaspberryPi firmware does it,
* and finally here's how I do it in my boot loader (tested and known to work, does EL3 -> EL1 as well as EL2 -> EL1 transition because qemu and real RPi does not start on the same EL level).

Hope these help.

Cheers,
bzt

Okay, thanks for the information.

_________________
Code:
/* Beware of bugs in the above code;
I have only proved it correct, not tried it. */

Original quote by Donald E. Knuth


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 228 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group