I have a standalone app running at EL3 in OCM on an A53 processor. The code boots from flash. I load an elf image into RAM and need to transition to its entry point running at EL1.
I try and make the transition via the following code:
/*****************************************************************************/ /** * @file asm_switch_to_EL1.s * * This file contains the code tat switches from EL3 to EL1 for the Cortex A53 processor * * <pre> * MODIFICATION HISTORY: * * Ver Who Date Changes * ----- ------- -------- --------------------------------------------------- * 1.00 kcm 11/26/19 Initial version * * </pre> * * @note * * None. * ******************************************************************************/ .globl switch_to_EL1 // *************************************** // SCTLR_EL1, System Control Register (EL1), Page 2654 of AArch64-Reference-Manual. // *************************************** #define SCTLR_RESERVED (3 << 28) | (3 << 22) | (1 << 20) | (1 << 11) #define SCTLR_EE_LITTLE_ENDIAN (0 << 25) #define SCTLR_EOE_LITTLE_ENDIAN (0 << 24) #define SCTLR_I_CACHE_DISABLED (0 << 12) #define SCTLR_D_CACHE_DISABLED (0 << 2) #define SCTLR_MMU_DISABLED (0 << 0) #define SCTLR_MMU_ENABLED (1 << 0) #define SCTLR_VALUE_MMU_DISABLED (SCTLR_RESERVED | SCTLR_EE_LITTLE_ENDIAN | SCTLR_I_CACHE_DISABLED | SCTLR_D_CACHE_DISABLED | SCTLR_MMU_DISABLED) // *************************************** // HCR_EL2, Hypervisor Configuration Register (EL2), Page 2487 of AArch64-Reference-Manual. // *************************************** #define HCR_RW (1 << 31) #define HCR_VALUE HCR_RW // *************************************** // SCR_EL3, Secure Configuration Register (EL3), Page 2648 of AArch64-Reference-Manual. // *************************************** #define SCR_RESERVED (3 << 4) #define SCR_RW (1 << 10) #define SCR_NS (1 << 0) #define SCR_VALUE (SCR_RESERVED | SCR_RW | SCR_NS) // *************************************** // SPSR_EL3, Saved Program Status Register (EL3) Page 389 of AArch64-Reference-Manual. // *************************************** #define SPSR_MASK_ALL (7 << 6) #define SPSR_EL1h (5 << 0) #define SPSR_VALUE (SPSR_MASK_ALL | SPSR_EL1h) switch_to_EL1: ldr x1, =SCTLR_VALUE_MMU_DISABLED msr sctlr_el1, x1 ldr x1, =HCR_VALUE msr hcr_el2, x1 ldr x1, =SCR_VALUE msr scr_el3, x1 ldr x1, =SPSR_VALUE msr spsr_el3, x1 msr elr_el3, x0 eret .end
If I try and debug this using the JTAG debugger on a Xylinx ZCU111 module, the debugger seems to get lost when I try and execute the ERET instruction.
I have discussed this with a Xylinx engineer and he suggested I post to this forum.
He also suggested I
My guess is that might need to setup the vbar_el1 register since I am returning from an exception.
Any thoughts or help on this would be appreciated.
VBAR is not needed when returning from an exception. But haveing valid vector tables helps you to debug. At least place an endless loop on every vector. This way the debugger should not loose control.