diff --git a/arch/arm/core/aarch64/Kconfig b/arch/arm/core/aarch64/Kconfig index 7ee65a2ef66..0b94a549715 100644 --- a/arch/arm/core/aarch64/Kconfig +++ b/arch/arm/core/aarch64/Kconfig @@ -24,6 +24,13 @@ config CPU_CORTEX_A53 help This option signifies the use of a Cortex-A53 CPU +config SWITCH_TO_EL1 + bool "Switch to EL1 at boot" + default y + help + This option indicates that we want to switch to EL1 at boot. Only + switching to EL1 from EL3 is supported. + config NUM_IRQS int diff --git a/arch/arm/core/aarch64/reset.S b/arch/arm/core/aarch64/reset.S index 4b48885b16a..4b510295ed4 100644 --- a/arch/arm/core/aarch64/reset.S +++ b/arch/arm/core/aarch64/reset.S @@ -42,6 +42,32 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__reset) GTEXT(__start) SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) +#ifdef CONFIG_SWITCH_TO_EL1 + switch_el x1, 3f, 2f, 1f +3: + /* Disable MMU and async exceptions routing to EL1 */ + msr sctlr_el1, xzr + + /* 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 EL1 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: + /* Boot from EL2 not supported */ + bl . +1: +#endif /* Setup vector table */ adr x0, _vector_table