diff --git a/arch/arm/src/armv6-m/arm_exception.S b/arch/arm/src/armv6-m/arm_exception.S index c438bf595ee..224ecdd5351 100644 --- a/arch/arm/src/armv6-m/arm_exception.S +++ b/arch/arm/src/armv6-m/arm_exception.S @@ -167,10 +167,7 @@ exception_common: */ #if CONFIG_ARCH_INTERRUPTSTACK > 3 - setintstack r7, r6 /* SP = IRQ stack top */ - push {r1} /* Save the MSP on the interrupt stack */ - bl arm_doirq /* R0=IRQ, R1=register save area on stack */ - pop {r1} /* Recover R1=main stack pointer */ + setintstack r7, r6 /* SP = IRQ stack top */ #else /* If the interrupt stack is disabled, reserve xcpcontext to ensure * that signal processing can have a separate xcpcontext to handle @@ -183,64 +180,30 @@ exception_common: * also the sp should be restore after arm_doirq() */ - sub r1, r1, #XCPTCONTEXT_SIZE /* Reserve signal context */ - - msr msp, r1 /* We are using the main stack pointer */ - - add r1, r1, #XCPTCONTEXT_SIZE /* Restore signal context */ + mov r2, r1 /* Reserve signal context */ + sub r2, r2, #XCPTCONTEXT_SIZE + msr msp, r2 /* We are using the main stack pointer */ +#endif bl arm_doirq /* R0=IRQ, R1=register save area on stack */ - mrs r1, msp /* Recover R1=main stack pointer */ -#endif - /* On return from arm_doirq, R0 will hold a pointer to register context - * array to use for the interrupt return. If that return value is the same - * as current stack pointer, then things are relatively easy. - */ - - cmp r0, r1 /* Context switch? */ - beq 3f /* Branch if no context switch */ - - /* We are returning with a pending context switch. This case is different - * because in this case, the register save structure does not lie on the - * stack but, rather within a TCB structure. We'll have to copy some - * values to the stack. - */ - - /* Copy the hardware-saved context to the new stack */ - - mov r2, #SW_XCPT_SIZE /* R2=Size of software-saved portion of the context array */ - add r1, r0, r2 /* R1=Address of HW save area in reg array */ - ldr r2, [r0, #(4*REG_SP)] /* R2=Value of SP before the interrupt */ - sub r2, #HW_XCPT_SIZE /* R2=Address of HW save area on the return stack */ - ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */ - stmia r2!, {r4-r7} /* Copy four registers to the return stack */ - ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */ - stmia r2!, {r4-r7} /* Copy four registers to the return stack */ - - /* Restore the register contents */ - - mov r1, r0 - -3: - /* We are returning with no context switch. We simply need to "unwind" - * the same stack frame that we created at entry. + * array to use for the interrupt return. */ /* Recover R8-R11 and EXEC_RETURN (5 registers) */ mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */ - add r0, r1, r2 /* R0=Address of R8 storage */ + add r1, r0, r2 /* R1=Address of R8 storage */ #ifdef CONFIG_BUILD_PROTECTED - ldmia r0!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/ + ldmia r1!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/ mov r8, r2 /* Move to position in high registers */ mov r9, r3 mov r10, r4 mov r11, r5 mov r14, r6 /* EXEC_RETURN */ #else - ldmia r0!, {r2-r5} /* Recover R8-R11 and R14 (5 registers)*/ + ldmia r1!, {r2-r5} /* Recover R8-R11 (4 registers)*/ mov r8, r2 /* Move to position in high registers */ mov r9, r3 mov r10, r4 @@ -251,7 +214,7 @@ exception_common: * the stack pointer as it was on entry to the exception handler. */ - ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */ + ldmia r0!, {r2-r7} /* Recover R4-R7 + 2 temp values */ mov r1, #HW_XCPT_SIZE /* R1=Size of hardware-saved portion of the context array */ sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */ @@ -262,14 +225,14 @@ exception_common: #ifdef CONFIG_BUILD_PROTECTED mov r0, r14 /* Copy high register to low register */ lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */ - bmi 5f /* Test bit 31 */ + bmi 3f /* Test bit 31 */ msr msp, r1 /* R1=The main stack pointer */ - b 6f + b 4f -5: +3: msr psp, r1 /* R1=The process stack pointer */ -6: +4: #else msr msp, r1 /* R1=The main stack pointer */ ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */ diff --git a/arch/arm/src/armv7-m/gnu/arm_exception.S b/arch/arm/src/armv7-m/gnu/arm_exception.S index 8836f40308c..be6cc94d9da 100644 --- a/arch/arm/src/armv7-m/gnu/arm_exception.S +++ b/arch/arm/src/armv7-m/gnu/arm_exception.S @@ -188,10 +188,6 @@ exception_common: mov r1, sp - /* Also save the top of the stack in a preserved register */ - - mov r4, sp - #if CONFIG_ARCH_INTERRUPTSTACK > 7 /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use * a special special interrupt stack pointer. The way that this is done @@ -199,9 +195,12 @@ exception_common: */ setintstack r2, r3 /* SP = IRQ stack top */ - - bl arm_doirq /* R0=IRQ, R1=register save (msp) */ #else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + /* If the interrupt stack is disabled, reserve xcpcontext to ensure * that signal processing can have a separate xcpcontext to handle * signal context (reference: arm_schedulesigaction.c): @@ -213,77 +212,22 @@ exception_common: * also the sp should be restore after arm_doirq() */ - sub r4, r4, #XCPTCONTEXT_SIZE /* Reserve signal context */ - - /* Otherwise, we will re-use the interrupted thread's stack. That may - * mean using either MSP or PSP stack for interrupt level processing (in - * kernel mode). - */ - - bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + sub r2, r1, #XCPTCONTEXT_SIZE /* Reserve signal context */ + bic r2, r2, #7 /* Get the stack pointer with 8-byte alignment */ mov sp, r2 /* Instantiate the aligned stack */ +#endif bl arm_doirq /* R0=IRQ, R1=register save (msp) */ - /* If the interrupt stack is disabled, restore the signal context */ - - add r4, r4, #XCPTCONTEXT_SIZE /* Restore signal context */ -#endif - - mov r1, r4 /* Recover R1=main stack pointer */ - /* On return from arm_doirq, R0 will hold a pointer to register context - * array to use for the interrupt return. If that return value is the same - * as current stack pointer, then things are relatively easy. + * array to use for the interrupt return. */ - cmp r0, r1 /* Context switch? */ - beq 2f /* Branch if no context switch */ - - /* We are returning with a pending context switch. This case is different - * because in this case, the register save structure does not lie on the - * stack but, rather within a TCB structure. We'll have to copy some - * values to the stack. - */ - - /* Copy the hardware-saved context to the stack, and restore the software - * saved context directly. - * - * XXX In the normal case, it appears that this entire operation is unnecessary; - * context switch time would be improved if we could work out when the stack - * is dirty and avoid the work... - */ - - add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ - ldmia r1!, {r4-r11} /* Fetch eight registers in HW save area */ -#ifdef CONFIG_ARCH_FPU - vldmia r1!, {s0-s15} /* Fetch sixteen FP registers in HW save area */ - ldmia r1, {r2-r3} /* Fetch FPSCR and Reserved in HW save area */ -#endif - ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ -#ifdef CONFIG_ARCH_FPU - stmdb r1!, {r2-r3} /* Store FPSCR and Reserved on the return stack */ - vstmdb r1!, {s0-s15} /* Store sixteen FP registers on the return stack */ -#endif - stmdb r1!, {r4-r11} /* Store eight registers on the return stack */ ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ #ifdef CONFIG_ARCH_FPU - vldmia r0, {s16-s31} /* Recover S16-S31 */ + vldmia r0!, {s16-s31} /* Recover S16-S31 */ #endif - b 3f /* Re-join common logic */ - -2: - /* We are returning with no context switch. We simply need to "unwind" - * the same stack frame that we created at entry. - */ - - ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ -#ifdef CONFIG_ARCH_FPU - vldmia r1!, {s16-s31} /* Recover S16-S31 */ -#endif - -3: /* The EXC_RETURN value tells us whether we are returning on the MSP or PSP */ @@ -295,21 +239,21 @@ exception_common: mrs r2, control /* R2=Contents of the control register */ tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ - beq 4f /* Branch if privileged */ + beq 2f /* Branch if privileged */ orr r2, r2, #1 /* Unprivileged mode */ - msr psp, r1 /* R1=The process stack pointer */ - b 5f -4: + msr psp, r0 /* R0=The process stack pointer */ + b 3f +2: bic r2, r2, #1 /* Privileged mode */ - msr msp, r1 /* R1=The main stack pointer */ -5: + msr msp, r0 /* R0=The main stack pointer */ +3: msr control, r2 /* Save the updated control register */ #else tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ ite eq /* Next two instructions conditional */ - msreq msp, r1 /* R1=The main stack pointer */ - msrne psp, r1 /* R1=The process stack pointer */ + msreq msp, r0 /* R0=The main stack pointer */ + msrne psp, r0 /* R0=The process stack pointer */ #endif /* Restore the interrupt state */ diff --git a/arch/arm/src/armv7-m/gnu/arm_lazyexception.S b/arch/arm/src/armv7-m/gnu/arm_lazyexception.S index 9cf57816ca1..29b88f638b1 100644 --- a/arch/arm/src/armv7-m/gnu/arm_lazyexception.S +++ b/arch/arm/src/armv7-m/gnu/arm_lazyexception.S @@ -193,9 +193,12 @@ exception_common: */ setintstack r2, r3 /* SP = IRQ stack top */ - - bl arm_doirq /* R0=IRQ, R1=register save (msp) */ #else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + /* If the interrupt stack is disabled, reserve xcpcontext to ensure * that signal processing can have a separate xcpcontext to handle * signal context (reference: arm_schedulesigaction.c): @@ -207,31 +210,19 @@ exception_common: * also the sp should be restore after arm_doirq() */ - sub r4, r4, #XCPTCONTEXT_SIZE /* Reserve signal context */ - - /* Otherwise, we will re-use the interrupted thread's stack. That may - * mean using either MSP or PSP stack for interrupt level processing (in - * kernel mode). - */ - - bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + sub r2, r4, #XCPTCONTEXT_SIZE /* Reserve signal context */ + bic r2, r2, #7 /* Get the stack pointer with 8-byte alignment */ mov sp, r2 /* Instantiate the aligned stack */ - - bl arm_doirq /* R0=IRQ, R1=register save (msp) */ - - /* If the interrupt stack is disabled, restore the signal context */ - - add r4, r4, #XCPTCONTEXT_SIZE /* Restore signal context */ #endif - mov r1, r4 /* Recover R1=main stack pointer */ + bl arm_doirq /* R0=IRQ, R1=register save (msp) */ /* On return from arm_doirq, R0 will hold a pointer to register context * array to use for the interrupt return. If that return value is the same * as current stack pointer, then things are relatively easy. */ - cmp r0, r1 /* Context switch? */ + cmp r0, r4 /* Context switch? */ beq 2f /* Branch if no context switch */ /* We are returning with a pending context switch. @@ -253,56 +244,30 @@ exception_common: bl arm_restorefpu /* Restore the FPU registers */ #endif - /* We are returning with a pending context switch. This case is different - * because in this case, the register save structure does not lie in the - * stack but, rather, within a TCB structure. We'll have to copy some - * values to the stack. - */ - - add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ - ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ - ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ - stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ -#ifdef CONFIG_BUILD_PROTECTED - ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ -#else - ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ -#endif - b 3f /* Re-join common logic */ - - /* We are returning with no context switch. We simply need to "unwind" - * the same stack frame that we created - * - * Here: - * r1 = Address of the return stack (same as r0) - */ - 2: #ifdef CONFIG_BUILD_PROTECTED - ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ + ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ #else - ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ + ldmia r0!, {r2-r11} /* Recover R4-R11 + 2 temp values */ #endif #ifdef CONFIG_ARCH_FPU /* Skip over the block of memory reserved for floating pointer register - * save. Then R1 is the address of the HW save area + * save. Then R0 is the address of the HW save area */ - add r1, #(4*SW_FPU_REGS) + add r0, #(4*SW_FPU_REGS) #endif /* Set up to return from the exception * * Here: - * r1 = Address on the target thread's stack position at the start of + * r0 = Address on the target thread's stack position at the start of * the registers saved by hardware * r3 = primask or basepri * r4-r11 = restored register values */ -3: - #ifdef CONFIG_BUILD_PROTECTED /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 * (handler mode) if the stack is on the MSP. It can only be on the PSP if @@ -311,18 +276,18 @@ exception_common: mrs r2, control /* R2=Contents of the control register */ tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ - beq 4f /* Branch if privileged */ + beq 3f /* Branch if privileged */ orr r2, r2, #1 /* Unprivileged mode */ - msr psp, r1 /* R1=The process stack pointer */ - b 5f -4: + msr psp, r0 /* R0=The process stack pointer */ + b 4f +3: bic r2, r2, #1 /* Privileged mode */ - msr msp, r1 /* R1=The main stack pointer */ -5: + msr msp, r0 /* R0=The main stack pointer */ +4: msr control, r2 /* Save the updated control register */ #else - msr msp, r1 /* Recover the return MSP value */ + msr msp, r0 /* Recover the return MSP value */ /* Preload r14 with the special return value first (so that the return * actually occurs with interrupts still disabled). diff --git a/arch/arm/src/armv8-m/arm_exception.S b/arch/arm/src/armv8-m/arm_exception.S index aa812802205..042b3609aaa 100644 --- a/arch/arm/src/armv8-m/arm_exception.S +++ b/arch/arm/src/armv8-m/arm_exception.S @@ -204,10 +204,6 @@ exception_common: mov r1, sp - /* Also save the top of the stack in a preserved register */ - - mov r4, sp - #if CONFIG_ARCH_INTERRUPTSTACK > 7 /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use * a special special interrupt stack pointer. The way that this is done @@ -215,9 +211,12 @@ exception_common: */ setintstack r2, r3 /* SP = IRQ stack top */ - - bl arm_doirq /* R0=IRQ, R1=register save (msp) */ #else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + /* If the interrupt stack is disabled, reserve xcpcontext to ensure * that signal processing can have a separate xcpcontext to handle * signal context (reference: arm_schedulesigaction.c): @@ -229,85 +228,26 @@ exception_common: * also the sp should be restore after arm_doirq() */ - sub r4, r4, #XCPTCONTEXT_SIZE /* Reserve signal context */ - - /* Otherwise, we will re-use the interrupted thread's stack. That may - * mean using either MSP or PSP stack for interrupt level processing (in - * kernel mode). - */ - - bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + sub r2, r1, #XCPTCONTEXT_SIZE /* Reserve signal context */ + bic r2, r2, #7 /* Get the stack pointer with 8-byte alignment */ mov sp, r2 /* Instantiate the aligned stack */ +#endif bl arm_doirq /* R0=IRQ, R1=register save (msp) */ - /* If the interrupt stack is disabled, restore the signal context */ - - add r4, r4, #XCPTCONTEXT_SIZE /* Restore signal context */ -#endif - - mov r1, r4 /* Recover R1=main stack pointer */ - /* On return from arm_doirq, R0 will hold a pointer to register context - * array to use for the interrupt return. If that return value is the same - * as current stack pointer, then things are relatively easy. + * array to use for the interrupt return. */ - cmp r0, r1 /* Context switch? */ - beq 2f /* Branch if no context switch */ - - /* We are returning with a pending context switch. This case is different - * because in this case, the register save structure does not lie on the - * stack but, rather within a TCB structure. We'll have to copy some - * values to the stack. - */ - - /* Copy the hardware-saved context to the stack, and restore the software - * saved context directly. - * - * XXX In the normal case, it appears that this entire operation is unnecessary; - * context switch time would be improved if we could work out when the stack - * is dirty and avoid the work... - */ - - add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ - ldmia r1!, {r4-r11} /* Fetch eight registers in HW save area */ -#ifdef CONFIG_ARCH_FPU - vldmia r1!, {s0-s15} /* Fetch sixteen FP registers in HW save area */ - ldmia r1, {r2-r3} /* Fetch FPSCR and Reserved in HW save area */ -#endif - ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ -#ifdef CONFIG_ARCH_FPU - stmdb r1!, {r2-r3} /* Store FPSCR and Reserved on the return stack */ - vstmdb r1!, {s0-s15} /* Store sixteen FP registers on the return stack */ -#endif - stmdb r1!, {r4-r11} /* Store eight registers on the return stack */ ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ #ifdef CONFIG_ARCH_FPU vldmia r0!, {s16-s31} /* Recover S16-S31 */ #endif #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - ldmia r0, {r0} /* Get psplim/msplim */ + ldmia r0!, {r1} /* Get psplim/msplim */ #endif - b 3f /* Re-join common logic */ - -2: - /* We are returning with no context switch. We simply need to "unwind" - * the same stack frame that we created at entry. - */ - - ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ -#ifdef CONFIG_ARCH_FPU - vldmia r1!, {s16-s31} /* Recover S16-S31 */ -#endif - -#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - ldmia r1!, {r0} /* Get psplim/msplim */ -#endif - -3: /* The EXC_RETURN value tells us whether we are returning on the MSP or PSP */ @@ -319,33 +259,33 @@ exception_common: mrs r2, control /* R2=Contents of the control register */ tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ - beq 4f /* Branch if privileged */ + beq 2f /* Branch if privileged */ orr r2, r2, #1 /* Unprivileged mode */ #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - msr psplim, r0 + msr psplim, r1 #endif - msr psp, r1 /* R1=The process stack pointer */ - b 5f -4: + msr psp, r0 /* R0=The process stack pointer */ + b 3f +2: bic r2, r2, #1 /* Privileged mode */ #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - msr msplim, r0 + msr msplim, r1 #endif - msr msp, r1 /* R1=The main stack pointer */ -5: + msr msp, r0 /* R0=The main stack pointer */ +3: msr control, r2 /* Save the updated control register */ #else tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE itete eq - msreq msplim, r0 - msrne psplim, r0 + msreq msplim, r1 + msrne psplim, r1 #else ite eq /* Next two instructions conditional */ #endif - msreq msp, r1 /* R1=The main stack pointer */ - msrne psp, r1 /* R1=The process stack pointer */ + msreq msp, r0 /* R0=The main stack pointer */ + msrne psp, r0 /* R0=The process stack pointer */ #endif /* Restore the interrupt state */ diff --git a/arch/arm/src/armv8-m/arm_lazyexception.S b/arch/arm/src/armv8-m/arm_lazyexception.S index d70e2bd8af7..cc9b994925a 100644 --- a/arch/arm/src/armv8-m/arm_lazyexception.S +++ b/arch/arm/src/armv8-m/arm_lazyexception.S @@ -210,9 +210,12 @@ exception_common: */ setintstack r2, r3 /* SP = IRQ stack top */ - - bl arm_doirq /* R0=IRQ, R1=register save (msp) */ #else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + /* If the interrupt stack is disabled, reserve xcpcontext to ensure * that signal processing can have a separate xcpcontext to handle * signal context (reference: arm_schedulesigaction.c): @@ -224,31 +227,18 @@ exception_common: * also the sp should be restore after arm_doirq() */ - sub r4, r4, #XCPTCONTEXT_SIZE /* Reserve signal context */ - - /* Otherwise, we will re-use the interrupted thread's stack. That may - * mean using either MSP or PSP stack for interrupt level processing (in - * kernel mode). - */ - - bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + sub r2, r4, #XCPTCONTEXT_SIZE /* Reserve signal context */ + bic r2, r2, #7 /* Get the stack pointer with 8-byte alignment */ mov sp, r2 /* Instantiate the aligned stack */ +#endif bl arm_doirq /* R0=IRQ, R1=register save (msp) */ - /* If the interrupt stack is disabled, restore the signal context */ - - add r4, r4, #XCPTCONTEXT_SIZE /* Restore signal context */ -#endif - - mov r1, r4 /* Recover R1=main stack pointer */ - /* On return from arm_doirq, R0 will hold a pointer to register context - * array to use for the interrupt return. If that return value is the same - * as current stack pointer, then things are relatively easy. + * array to use for the interrupt return. */ - cmp r0, r1 /* Context switch? */ + cmp r0, r4 /* Context switch? */ beq 2f /* Branch if no context switch */ /* We are returning with a pending context switch. @@ -270,63 +260,34 @@ exception_common: bl arm_restorefpu /* Restore the FPU registers */ #endif - /* We are returning with a pending context switch. This case is different - * because in this case, the register save structure does not lie in the - * stack but, rather, within a TCB structure. We'll have to copy some - * values to the stack. - */ - - add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ - ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ - ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ - stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ +2: #ifdef CONFIG_BUILD_PROTECTED ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ #else ldmia r0!, {r2-r11} /* Recover R4-R11 + 2 temp values */ #endif -#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - ldmia r0, {r0} /* Get psplim/msplim*/ -#endif - b 3f /* Re-join common logic */ - - /* We are returning with no context switch. We simply need to "unwind" - * the same stack frame that we created - * - * Here: - * r1 = Address of the return stack (same as r0) - */ - -2: -#ifdef CONFIG_BUILD_PROTECTED - ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ -#else - ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ -#endif #ifdef CONFIG_ARCH_FPU /* Skip over the block of memory reserved for floating pointer register * save. Then R1 is the address of the HW save area */ - add r1, #(4*SW_FPU_REGS) + add r0, #(4*SW_FPU_REGS) #endif #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - ldmia r1!, {r0} /* Get psplim/msplim */ + ldmia r0!, {r1} /* Get psplim/msplim */ #endif /* Set up to return from the exception * * Here: - * r1 = Address on the target thread's stack position at the start of + * r0 = Address on the target thread's stack position at the start of * the registers saved by hardware * r3 = primask or basepri * r4-r11 = restored register values */ -3: - #ifdef CONFIG_BUILD_PROTECTED /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 * (handler mode) if the stack is on the MSP. It can only be on the PSP if @@ -335,27 +296,27 @@ exception_common: mrs r2, control /* R2=Contents of the control register */ tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ - beq 4f /* Branch if privileged */ + beq 3f /* Branch if privileged */ orr r2, r2, #1 /* Unprivileged mode */ #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - msr psplim, r0 + msr psplim, r1 #endif - msr psp, r1 /* R1=The process stack pointer */ - b 5f -4: + msr psp, r0 /* R1=The process stack pointer */ + b 4f +3: bic r2, r2, #1 /* Privileged mode */ #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - msr msplim, r0 + msr msplim, r1 #endif - msr msp, r1 /* R1=The main stack pointer */ -5: + msr msp, r0 /* R1=The main stack pointer */ +4: msr control, r2 /* Save the updated control register */ #else #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE - msr msplim, r0 + msr msplim, r1 #endif - msr msp, r1 /* Recover the return MSP value */ + msr msp, r0 /* Recover the return MSP value */ /* Preload r14 with the special return value first (so that the return * actually occurs with interrupts still disabled).