aboutsummaryrefslogtreecommitdiffstats
path: root/os/common/ports/ARMCMx
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2018-11-13 10:36:05 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2018-11-13 10:36:05 +0000
commit1d6d312d43a5cceda95705b3a04eb21a5c4cb310 (patch)
treec5befe034b02a1b1d2248d67576e2bf326d9f139 /os/common/ports/ARMCMx
parentd65f2107f899b99813f1cda9834112386ab4ef16 (diff)
downloadChibiOS-1d6d312d43a5cceda95705b3a04eb21a5c4cb310.tar.gz
ChibiOS-1d6d312d43a5cceda95705b3a04eb21a5c4cb310.tar.bz2
ChibiOS-1d6d312d43a5cceda95705b3a04eb21a5c4cb310.zip
Tentative fix for bug #985.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12416 110e8d01-0319-4d1e-a829-52ad28d1bb01
Diffstat (limited to 'os/common/ports/ARMCMx')
-rw-r--r--os/common/ports/ARMCMx/chcore_v6m.c32
-rw-r--r--os/common/ports/ARMCMx/chcore_v6m.h16
2 files changed, 17 insertions, 31 deletions
diff --git a/os/common/ports/ARMCMx/chcore_v6m.c b/os/common/ports/ARMCMx/chcore_v6m.c
index 62daff813..5e43cb01a 100644
--- a/os/common/ports/ARMCMx/chcore_v6m.c
+++ b/os/common/ports/ARMCMx/chcore_v6m.c
@@ -107,15 +107,16 @@ void PendSV_Handler(void) {
*
* @param[in] lr value of the @p LR register on ISR entry
*/
-void _port_irq_epilogue(regarm_t lr) {
+void _port_irq_epilogue(void) {
+ struct port_extctx *ctxp;
- if (lr != (regarm_t)0xFFFFFFF1U) {
- struct port_extctx *ctxp;
+ port_lock_from_isr();
- port_lock_from_isr();
-
- /* The extctx structure is pointed by the PSP register.*/
- ctxp = (struct port_extctx *)__get_PSP();
+ /* Checking if the artificial exception return context has already been
+ added.*/
+ ctxp = (struct port_extctx *)__get_PSP();
+ if ((ctxp->pc != (regarm_t)_port_switch_from_isr) &&
+ chSchIsPreemptionRequired()) {
/* Adding an artificial exception return context, there is no need to
populate it fully.*/
@@ -127,21 +128,16 @@ void _port_irq_epilogue(regarm_t lr) {
/* Setting up a fake XPSR register value.*/
ctxp->xpsr = (regarm_t)0x01000000;
- /* The exit sequence is different depending on if a preemption is
- required or not.*/
- if (chSchIsPreemptionRequired()) {
- /* Preemption is required we need to enforce a context switch.*/
- ctxp->pc = (regarm_t)_port_switch_from_isr;
- }
- else {
- /* Preemption not required, we just need to exit the exception
- atomically.*/
- ctxp->pc = (regarm_t)_port_exit_from_isr;
- }
+ /* Return address set to OS code, there context switch will be
+ performed.*/
+ ctxp->pc = (regarm_t)_port_switch_from_isr;
/* Note, returning without unlocking is intentional, this is done in
order to keep the rest of the context switch atomic.*/
+ return;
}
+
+ port_unlock_from_isr();
}
/** @} */
diff --git a/os/common/ports/ARMCMx/chcore_v6m.h b/os/common/ports/ARMCMx/chcore_v6m.h
index d895f84a8..3d640506b 100644
--- a/os/common/ports/ARMCMx/chcore_v6m.h
+++ b/os/common/ports/ARMCMx/chcore_v6m.h
@@ -246,23 +246,14 @@ struct port_intctx {
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
*/
-#if defined(__GNUC__) || defined(__DOXYGEN__)
-#define PORT_IRQ_PROLOGUE() \
- regarm_t _saved_lr = (regarm_t)__builtin_return_address(0)
-#elif defined(__ICCARM__)
-#define PORT_IRQ_PROLOGUE() \
- regarm_t _saved_lr = (regarm_t)__get_LR()
-#elif defined(__CC_ARM)
-#define PORT_IRQ_PROLOGUE() \
- regarm_t _saved_lr = (regarm_t)__return_address()
-#endif
+#define PORT_IRQ_PROLOGUE()
/**
* @brief IRQ epilogue code.
* @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
-#define PORT_IRQ_EPILOGUE() _port_irq_epilogue(_saved_lr)
+#define PORT_IRQ_EPILOGUE() _port_irq_epilogue()
/**
* @brief IRQ handler function declaration.
@@ -307,11 +298,10 @@ struct port_intctx {
#ifdef __cplusplus
extern "C" {
#endif
- void _port_irq_epilogue(regarm_t lr);
+ void _port_irq_epilogue(void);
void _port_switch(thread_t *ntp, thread_t *otp);
void _port_thread_start(void);
void _port_switch_from_isr(void);
- void _port_exit_from_isr(void);
#ifdef __cplusplus
}
#endif