diff --git a/ChangeLog b/ChangeLog index b10f742cc1a..5713a1e8768 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4375,3 +4375,8 @@ * arch/arm/src/armv7-h/ram_vectors.h, up_ramvec_*.c, arch/arm/src/*/*_irq.c, and Make.defs: Add support for modifiable interrupt vectors in RAM (2013-03-18). + * arch/arm/src/armv7-m/up_exception.S, sam3u/sam3u_vectors.S, and + lpc17xx/lpc17_vectors.S: In exception handling with CONFIG_NUTTX_KERNEL, + need to explicity set and cleare the privilege bit in the CONTROL + register on return. I assumed this would be handled automatically + by the EXC_RETURN. Silly me (2013-03-18). diff --git a/arch/arm/src/armv7-m/up_exception.S b/arch/arm/src/armv7-m/up_exception.S index 35d9231871f..df7a7ad2997 100644 --- a/arch/arm/src/armv7-m/up_exception.S +++ b/arch/arm/src/armv7-m/up_exception.S @@ -201,10 +201,30 @@ exception_common: /* The EXC_RETURN value tells us whether we are returning on the MSP or PSP */ +#ifdef CONFIG_NUTTX_KERNEL + /* 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 + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 3f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 4f +3: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +4: + 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 */ +#endif /* Restore the interrupt state */ diff --git a/arch/arm/src/lpc17xx/lpc17_vectors.S b/arch/arm/src/lpc17xx/lpc17_vectors.S index eca382b1b1c..9575e1f3ec1 100644 --- a/arch/arm/src/lpc17xx/lpc17_vectors.S +++ b/arch/arm/src/lpc17xx/lpc17_vectors.S @@ -43,6 +43,7 @@ #include #include "chip.h" +#include "exc_return.h" /************************************************************************************************ * Preprocessor Definitions @@ -209,7 +210,7 @@ lpc17_common: #ifdef CONFIG_NUTTX_KERNEL /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 - * (handler mode) if the state is on the MSP. It can only be on the PSP if + * (handler mode) if the stack is on the MSP. It can only be on the PSP if * EXC_RETURN is 0xfffffffd (unprivileged thread) */ @@ -351,16 +352,25 @@ lpc17_common: * r4-r11 = restored register values */ 2: + #ifdef CONFIG_NUTTX_KERNEL /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 - * (handler mode) if the state is on the MSP. It can only be on the PSP if + * (handler mode) if the stack is on the MSP. It can only be on the PSP if * EXC_RETURN is 0xfffffffd (unprivileged thread) */ - adds r0, r14, #3 /* If R14=0xfffffffd, then r0 == 0 */ - ite ne /* Next two instructions are condition */ - msrne msp, r1 /* R1=The main stack pointer */ - msreq psp, r1 /* R1=The process stack pointer */ + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 3f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 4f +3: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +4: + msr control, r2 /* Save the updated control register */ #else msr msp, r1 /* Recover the return MSP value */ diff --git a/arch/arm/src/sam3u/sam3u_vectors.S b/arch/arm/src/sam3u/sam3u_vectors.S index eba6edd3ae0..baaeb54b957 100644 --- a/arch/arm/src/sam3u/sam3u_vectors.S +++ b/arch/arm/src/sam3u/sam3u_vectors.S @@ -42,6 +42,8 @@ #include +#include "exc_return.h" + /************************************************************************************************ * Preprocessor Definitions ************************************************************************************************/ @@ -236,7 +238,7 @@ sam3u_common: #ifdef CONFIG_NUTTX_KERNEL /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 - * (handler mode) if the state is on the MSP. It can only be on the PSP if + * (handler mode) if the stack is on the MSP. It can only be on the PSP if * EXC_RETURN is 0xfffffffd (unprivileged thread) */ @@ -378,16 +380,25 @@ sam3u_common: * r4-r11 = restored register values */ 2: + #ifdef CONFIG_NUTTX_KERNEL /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 - * (handler mode) if the state is on the MSP. It can only be on the PSP if + * (handler mode) if the stack is on the MSP. It can only be on the PSP if * EXC_RETURN is 0xfffffffd (unprivileged thread) */ - adds r0, r14, #3 /* If R14=0xfffffffd, then r0 == 0 */ - ite ne /* Next two instructions are condition */ - msrne msp, r1 /* R1=The main stack pointer */ - msreq psp, r1 /* R1=The process stack pointer */ + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 3f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 4f +3: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +4: + msr control, r2 /* Save the updated control register */ #else msr msp, r1 /* Recover the return MSP value */