summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/armv7-m
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-19 00:16:27 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-19 00:16:27 +0000
commitda460d18fab3e9e8c864aae340ef4867d90483d6 (patch)
tree9e6d4ed7b2c9df8ce74d65a5ddc00114477adca9 /nuttx/arch/arm/src/armv7-m
parentc3998d2feead04441a90dcd45c6a35f8477b7fd6 (diff)
downloadpx4-nuttx-da460d18fab3e9e8c864aae340ef4867d90483d6.tar.gz
px4-nuttx-da460d18fab3e9e8c864aae340ef4867d90483d6.tar.bz2
px4-nuttx-da460d18fab3e9e8c864aae340ef4867d90483d6.zip
In KERNEL mode, need to explicitly set the privilege in the CONTROL register on return from exceptions
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5757 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src/armv7-m')
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_exception.S20
1 files changed, 20 insertions, 0 deletions
diff --git a/nuttx/arch/arm/src/armv7-m/up_exception.S b/nuttx/arch/arm/src/armv7-m/up_exception.S
index 35d923187..df7a7ad29 100644
--- a/nuttx/arch/arm/src/armv7-m/up_exception.S
+++ b/nuttx/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 */