diff --git a/arch/arm/core/exc_exit.S b/arch/arm/core/exc_exit.S index 051f8ea506c..f1af77e6256 100644 --- a/arch/arm/core/exc_exit.S +++ b/arch/arm/core/exc_exit.S @@ -72,6 +72,7 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_int_exit) SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_exc_exit) #if defined(CONFIG_CPU_CORTEX_R) + /* r0 contains the caller mode */ push {r0, lr} #endif @@ -116,11 +117,17 @@ _EXIT_EXC: #if defined(CONFIG_CPU_CORTEX_M) bx lr #elif defined(CONFIG_CPU_CORTEX_R) - /* - * r0-r3 are either the values from the thread before it was switched out - * or they are the args to _new_thread for a new thread - */ + /* Restore the caller mode to r0 */ pop {r0, lr} + + /* + * Restore r0-r3, r12 and lr stored into the process stack by the mode + * entry function. These registers are saved by _isr_wrapper for IRQ mode + * and z_arm_svc for SVC mode. + * + * r0-r3 are either the values from the thread before it was switched out + * or they are the args to _new_thread for a new thread. + */ push {r4, r5} cmp r0, #RET_FROM_SVC diff --git a/arch/arm/core/swap_helper.S b/arch/arm/core/swap_helper.S index 4fa0a329080..c6bd30038a8 100644 --- a/arch/arm/core/swap_helper.S +++ b/arch/arm/core/swap_helper.S @@ -39,6 +39,10 @@ GDATA(_kernel) * When PendSV is pended, the decision that a context switch must happen has * already been taken. In other words, when z_arm_pendsv() runs, we *know* we * have to swap *something*. + * + * For Cortex-R, PendSV exception is not supported by the architecture and this + * function is directly called either by _IntExit in case of preemption, or + * z_arm_svc in case of cooperative switching. */ SECTION_FUNC(TEXT, z_arm_pendsv) @@ -328,7 +332,10 @@ _thread_irq_disabled: #endif #endif /* CONFIG_TRACING */ - /* exc return */ + /* + * Cortex-M: return from PendSV exception + * Cortex-R: return to the caller (_IntExit or z_arm_svc) + */ bx lr #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) @@ -514,13 +521,25 @@ valid_syscall_id: /* return from SVC to the modified LR - z_arm_do_syscall */ bx lr -#endif +#endif /* CONFIG_USERSPACE */ #elif defined(CONFIG_ARMV7_R) + +/** + * + * @brief Service call handler + * + * The service call (svc) is used in the following occasions: + * - Cooperative context switching + * - IRQ offloading + * - Kernel run-time exceptions + * + * @return N/A + */ SECTION_FUNC(TEXT, z_arm_svc) /* * Switch to system mode to store r0-r3 to the process stack pointer. - * Save r12 and the lr as we will be swapping in another process and + * Save r12 and the lr as we could be swapping in another process and * returning to a different location. */ push {r4, r5}