From 30c73db82fbd034b89094dd58f069be43c1734d2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Mar 2011 09:43:12 +0000 Subject: More Cortex-M0 GCC port improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2801 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ports/GCC/ARMCMx/chcore_v6m.c | 27 +++++++++++++++++++++++++++ os/ports/GCC/ARMCMx/chcore_v6m.h | 22 ++-------------------- 2 files changed, 29 insertions(+), 20 deletions(-) (limited to 'os') diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c index 5004b2256..f132697d5 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.c +++ b/os/ports/GCC/ARMCMx/chcore_v6m.c @@ -127,6 +127,33 @@ void port_switch(Thread *ntp, Thread *otp) { POP_CONTEXT(r13); } +/** + * @brief IRQ epilogue code. + * + * @param[in] lr value of the @p LR register on ISR entry + */ +void _port_irq_epilogue(regarm_t lr) { + + if (lr != (regarm_t)0xFFFFFFF1) { + port_lock_from_isr(); + if (chSchIsRescRequiredExI()) { + register struct extctx *ctxp; + + /* Adding an artificial exception return context, there is no need to + populate it fully.*/ + asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory"); + ctxp--; + asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory"); + ctxp->pc = _port_switch_from_isr; + ctxp->xpsr = (regarm_t)0x01000000; + /* Note, returning without unlocking is intentional, this is done in + order to keep the rest of the context switching atomic.*/ + return; + } + port_unlock_from_isr(); + } +} + /** * @brief Start a thread by invoking its work function. * @details If the work function returns @p chThdExit() is automatically diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index 4e156f4c4..4cfd7de8a 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -113,26 +113,7 @@ struct intctx { * @details This macro must be inserted at the end of all IRQ handlers * enabled to invoke system APIs. */ -#define PORT_IRQ_EPILOGUE() { \ - if (_saved_lr != (regarm_t)0xFFFFFFF1) { \ - port_lock_from_isr(); \ - if (chSchIsRescRequiredExI()) { \ - register struct extctx *ctxp; \ - \ - /* Adding an artificial exception return context, there is no need to \ - populate it fully.*/ \ - asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory"); \ - ctxp--; \ - asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory"); \ - ctxp->pc = _port_switch_from_isr; \ - ctxp->xpsr = (regarm_t)0x01000000; \ - /* Note, returning without unlocking is intentional, this is done in \ - order to keep the rest of the context switching atomic.*/ \ - return; \ - } \ - port_unlock_from_isr(); \ - } \ -} +#define PORT_IRQ_EPILOGUE() _port_irq_epilogue(_saved_lr) /** * @brief IRQ handler function declaration. @@ -223,6 +204,7 @@ extern "C" { #endif void port_halt(void); void port_switch(Thread *ntp, Thread *otp); + void _port_irq_epilogue(regarm_t lr); void _port_switch_from_isr(void); void _port_thread_start(void); #ifdef __cplusplus -- cgit v1.2.3