blob: 3a97be8a6da211c362c55dba00ce2c3eb24dae25 [file] [log] [blame]
/*
* Copyright (c) 2019 Carlo Caione <ccaione@baylibre.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Reset handler
*
* Reset handler that prepares the system for running C code.
*/
#include <toolchain.h>
#include <linker/sections.h>
#include <arch/cpu.h>
#include "vector_table.h"
#include "macro_priv.inc"
_ASM_FILE_PROLOGUE
/*
* Platform may do platform specific init at EL3.
* The function implementation must preserve callee saved registers as per
* AArch64 ABI PCS.
*/
WTEXT(z_arch_el3_plat_init)
SECTION_FUNC(TEXT,z_arch_el3_plat_init)
ret
/*
* Reset vector
*
* Ran when the system comes out of reset. The processor is in thread mode with
* privileged level. At this point, neither SP_EL0 nor SP_ELx point to a valid
* area in SRAM.
*
* When these steps are completed, jump to z_arm64_prep_c(), which will finish
* setting up the system for running C code.
*/
GTEXT(__reset)
SECTION_SUBSEC_FUNC(TEXT,_reset_section,__reset)
GTEXT(__start)
SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start)
/* Setup vector table */
adr x19, _vector_table
switch_el x1, 3f, 2f, 1f
3:
/*
* Zephyr entry happened in EL3. Do EL3 specific init before
* dropping to lower EL.
*/
/* Initialize VBAR */
msr vbar_el3, x19
isb
/* Switch to SP_EL0 and setup the stack */
msr spsel, #0
ldr x0, =(z_interrupt_stacks)
add x0, x0, #(CONFIG_ISR_STACK_SIZE)
mov sp, x0
/* Initialize SCTLR_EL3 to reset value */
mov_imm x1, SCTLR_EL3_RES1
mrs x0, sctlr_el3
orr x0, x0, x1
msr sctlr_el3, x0
isb
/*
* Disable access traps to EL3 for CPACR, Trace, FP, ASIMD,
* SVE from lower EL.
*/
mov_imm x0, CPTR_EL3_RES_VAL
mov_imm x1, (CPTR_EL3_TTA | CPTR_EL3_TFP | CPTR_EL3_TCPAC)
bic x0, x0, x1
orr x0, x0, #(CPTR_EL3_EZ)
msr cptr_el3, x0
isb
/* Platform specific configurations needed in EL3 */
bl z_arch_el3_plat_init
/* Enable access control configuration from lower EL */
mrs x0, actlr_el3
orr x0, x0, #(ACTLR_EL3_L2ACTLR | ACTLR_EL3_L2ECTLR \
| ACTLR_EL3_L2CTLR)
orr x0, x0, #(ACTLR_EL3_CPUACTLR | ACTLR_EL3_CPUECTLR)
msr actlr_el3, x0
/* Initialize SCTLR_EL1 to reset value */
mov_imm x0, SCTLR_EL1_RES1
msr sctlr_el1, x0
/* Disable EA/IRQ/FIQ routing to EL3 and set EL1 to AArch64 */
mov x0, xzr
orr x0, x0, #(SCR_EL3_RW)
msr scr_el3, x0
/* On eret return to secure EL1h with DAIF masked */
mov x0, xzr
orr x0, x0, #(DAIF_MASK)
orr x0, x0, #(SPSR_EL3_TO_EL1)
orr x0, x0, #(SPSR_EL3_h)
msr spsr_el3, x0
adr x0, 1f
msr elr_el3, x0
eret
2:
/* Booting from EL2 is not supported */
b .
1:
/* Initialize VBAR */
msr vbar_el1, x19
isb
/* Switch to SP_EL0 and setup the stack */
msr spsel, #0
ldr x0, =(z_interrupt_stacks)
add x0, x0, #(CONFIG_ISR_STACK_SIZE)
mov sp, x0
/* Disable access trapping in EL1 for NEON/FP */
mov_imm x0, CPACR_EL1_FPEN_NOTRAP
msr cpacr_el1, x0
/* Enable the instruction cache and EL1 stack alignment check. */
mov_imm x1, (SCTLR_I | SCTLR_SA)
mrs x0, sctlr_el1
orr x0, x0, x1
msr sctlr_el1, x0
0:
isb
/* Enable the SError interrupt */
msr daifclr, #(DAIFSET_ABT)
bl z_arm64_prep_c