diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-03-19 00:16:27 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-03-19 00:16:27 +0000 |
commit | da460d18fab3e9e8c864aae340ef4867d90483d6 (patch) | |
tree | 9e6d4ed7b2c9df8ce74d65a5ddc00114477adca9 /nuttx/arch/arm/src/armv7-m | |
parent | c3998d2feead04441a90dcd45c6a35f8477b7fd6 (diff) | |
download | px4-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.S | 20 |
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 */ |