timanu90
Posts: 52
Joined: Sat Dec 24, 2016 11:54 am

aarch64 el1 secure & el1 non-secure

Thu Sep 14, 2017 12:49 pm

Hi guys today I am leaving here 2 pieces of code to drop rpi3 in 64 bit mode from el3 to el1 secure and el1 non secure, in the hope that it will be usefull for someone.

Code: Select all

drop_el1_secure:

    /* Try drop from el3 to el1 secure */

    /*=============================================================*/
    /*      Enable FP/SIMD at EL1                                  */
    /*=============================================================*/
    mov	x0, #3 << 20
    msr	cpacr_el1, x0           /* Enable FP/SIMD at EL1 */

    /*=============================================================*/
    /*      Initialize sctlr_el1                                   */
    /*=============================================================*/
    mov x0, xzr
    mov	x0, #(1 << 29)          /* Checking http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500d/CIHDIEBD.html */
    mov	x0, #(1 << 28)          /* Bits 29,28,23,22,20,11 should be 1 (res1 on documentation) */
    mov	x0, #(1 << 23)
    mov	x0, #(1 << 22)
    mov	x0, #(1 << 20)
    mov	x0, #(1 << 11)
    msr	sctlr_el1, x0

    /*=============================================================*/
    /*      Initialize scr_el3                                     */
    /*=============================================================*/
    mrs x0, scr_el3
    orr x0, x0, #(1<<10)        /* Lower EL is 64bits */
    msr scr_el3, x0

    /*=============================================================*/
    /*      Initialize spsr_el3                                    */
    /*=============================================================*/
    mov x0, xzr
    mov x0, #0b00101            /* EL1 */
    orr x0, x0, #(1 << 8)       /* Enable SError and External Abort. */
    orr x0, x0, #(1 << 7)       /* IRQ interrupt Process state mask. */
    orr x0, x0, #(1 << 6)       /* FIQ interrupt Process state mask. */
    msr spsr_el3, x0

    /*=============================================================*/
    /*      Initialize elr_el3                                     */
    /*=============================================================*/
    adr x0, el1_secure
    msr elr_el3, x0

    eret

el1_secure:

    bl call_kernel_main

Code: Select all

drop_el1_non_secure:

    /* Drop from el3 to el2 non secure. */

    /*=============================================================*/
    /*      Initialize sctlr_el2 & hcr_el2                         */
    /*=============================================================*/
    msr sctlr_el2, xzr
    mrs x0, hcr_el2
    orr x0, x0, #(1<<19)            /* SMC instruction executed in Non-secure EL1 is trapped to EL2 */
    msr hcr_el2, x0

    /*=============================================================*/
    /*      Initialize scr_el3                                     */
    /*=============================================================*/
    mrs x0, scr_el3
    orr x0, x0, #(1<<10)            /* RW EL2 Execution state is AArch64. */
    orr x0, x0, #(1<<0)             /* NS EL1 is Non-secure world.        */
    msr scr_el3, x0

    /*=============================================================*/
    /*      Initialize spsr_el3                                    */
    /*=============================================================*/
    mov x0, #0b01001                /* DAIF=0000                               */
    msr spsr_el3, x0                /* M[4:0]=01001 EL2h must match SCR_EL3.RW */

    /*=============================================================*/
    /*      Initialize elr_el3                                     */
    /*=============================================================*/
    adr x0, el2_entry               /* el2_entry points to the first instruction */
    msr elr_el3, x0
    eret

el2_entry:

    /* Drop from el2 to el1 non secure. */

    /*=============================================================*/
    /*      Enable FP/SIMD at EL1                                  */
    /*=============================================================*/
    mov	x0, #3 << 20
    msr	cpacr_el1, x0               /* Enable FP/SIMD at EL1. */

    /*=============================================================*/
    /*      Initialize sctlr_el1                                   */
    /*=============================================================*/
    mov x0, xzr
    mov	x0, #(1 << 29)              /* Checking http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500d/CIHDIEBD.html */
    mov	x0, #(1 << 28)              /* Bits 29,28,23,22,20,11 should be 1 (res1 on documentation) */
    mov	x0, #(1 << 23)
    mov	x0, #(1 << 22)
    mov	x0, #(1 << 20)
    mov	x0, #(1 << 11)
    msr	sctlr_el1, x0

    /*=============================================================*/
    /*      Initialize hcr_el2                                     */
    /*=============================================================*/
    mrs x0, hcr_el2
    orr x0, x0, #(1<<31)            /* RW=1 EL1 Execution state is AArch64. */
    msr hcr_el2, x0

    /*=============================================================*/
    /*      Initialize spsr_el2                                    */
    /*=============================================================*/
    mov x0, xzr
    mov x0, #0b00101                /* EL1 */
    orr x0, x0, #(1 << 8)           /* Enable SError and External Abort. */
    orr x0, x0, #(1 << 7)           /* IRQ interrupt Process state mask. */
    orr x0, x0, #(1 << 6)           /* FIQ interrupt Process state mask. */
    msr spsr_el2, x0

    /*=============================================================*/
    /*      Initialize elr_el2                                     */
    /*=============================================================*/
    adr x0, el1_non_secure
    msr elr_el2, x0

    eret

el1_non_secure:

    bl call_kernel_main
If someone is interested in how the code was tested or any other thing just ask.

Cheers
Tiago

User avatar
Paeryn
Posts: 1612
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: aarch64 el1 secure & el1 non-secure

Thu Sep 14, 2017 1:19 pm

timanu90 wrote:
Thu Sep 14, 2017 12:49 pm

Code: Select all

    /*=============================================================*/
    /*      Initialize sctlr_el1                                   */
    /*=============================================================*/
    mov x0, xzr
    mov	x0, #(1 << 29)          /* Checking http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500d/CIHDIEBD.html */
    mov	x0, #(1 << 28)          /* Bits 29,28,23,22,20,11 should be 1 (res1 on documentation) */
    mov	x0, #(1 << 23)
    mov	x0, #(1 << 22)
    mov	x0, #(1 << 20)
    mov	x0, #(1 << 11)
    msr	sctlr_el1, x0
Did you mean to use ORR rather than consecutive MOV instructions, otherwise you only have 1 bit set (1 << 11) in x0 at the end rather than having the 6 bits set.
She who travels light — forgot something.

timanu90
Posts: 52
Joined: Sat Dec 24, 2016 11:54 am

Re: aarch64 el1 secure & el1 non-secure

Thu Sep 14, 2017 1:23 pm

You are right. Bug fixed. Thank you.

Return to “Bare metal”

Who is online

Users browsing this forum: No registered users and 5 guests