From 978c2e800258dca15c30905c6bf1c6b0b7d772a0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 28 Dec 2011 08:56:04 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3668 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ports/GCC/ARMCMx/chcore.h | 18 ++++++++ os/ports/GCC/ARMCMx/chcore_v6m.c | 94 +++++++++++++++++++++------------------- os/ports/GCC/ARMCMx/chcore_v6m.h | 20 +-------- os/ports/GCC/ARMCMx/chcore_v7m.c | 1 - os/ports/GCC/ARMCMx/chcore_v7m.h | 20 +-------- 5 files changed, 71 insertions(+), 82 deletions(-) (limited to 'os') diff --git a/os/ports/GCC/ARMCMx/chcore.h b/os/ports/GCC/ARMCMx/chcore.h index 15cf9ac96..f8e34779f 100644 --- a/os/ports/GCC/ARMCMx/chcore.h +++ b/os/ports/GCC/ARMCMx/chcore.h @@ -205,6 +205,24 @@ struct intctx {}; #endif /* defined(__DOXYGEN__) */ + +/** + * @brief Excludes the default @p chSchIsPreemptionRequired()implementation. + */ +#define PORT_OPTIMIZED_ISPREEMPTIONREQUIRED + +#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__) +/** + * @brief Inlineable version of this kernel function. + */ +#define chSchIsPreemptionRequired() \ + (rlist.r_preempt ? firstprio(&rlist.r_queue) > currp->p_prio : \ + firstprio(&rlist.r_queue) >= currp->p_prio) +#else /* CH_TIME_QUANTUM == 0 */ +#define chSchIsPreemptionRequired() \ + (firstprio(&rlist.r_queue) > currp->p_prio) +#endif /* CH_TIME_QUANTUM == 0 */ + #endif /* _FROM_ASM_ */ #endif /* _CHCORE_H_ */ diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c index f154b9446..fa5b6b8c3 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.c +++ b/os/ports/GCC/ARMCMx/chcore_v6m.c @@ -87,6 +87,41 @@ void PendSVVector(void) { /* Port exported functions. */ /*===========================================================================*/ +/** + * @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) { + register struct extctx *ctxp; + + port_lock_from_isr(); + /* 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->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 = _port_switch_from_isr; + } + else { + /* Preemption not required, we just need to exit the exception + atomically.*/ + ctxp->pc = _port_exit_from_isr; + } + + /* Note, returning without unlocking is intentional, this is done in + order to keep the rest of the context switching atomic.*/ + } +} + /** * @brief Post-IRQ switch code. * @details The switch is performed in thread context then an NMI exception @@ -98,8 +133,8 @@ __attribute__((naked)) #endif void _port_switch_from_isr(void) { - if (chSchIsPreemptionRequired()) - chSchDoReschedule(); + chSchDoReschedule(); + asm volatile ("_port_exit_from_isr:" : : : "memory"); #if CORTEX_ALTERNATE_SWITCH SCB_ICSR = ICSR_PENDSVSET; port_unlock(); @@ -112,24 +147,6 @@ void _port_switch_from_isr(void) { ; } -#define PUSH_CONTEXT(sp) { \ - asm volatile ("push {r4, r5, r6, r7, lr} \n\t" \ - "mov r4, r8 \n\t" \ - "mov r5, r9 \n\t" \ - "mov r6, r10 \n\t" \ - "mov r7, r11 \n\t" \ - "push {r4, r5, r6, r7}" : : : "memory"); \ -} - -#define POP_CONTEXT(sp) { \ - asm volatile ("pop {r4, r5, r6, r7} \n\t" \ - "mov r8, r4 \n\t" \ - "mov r9, r5 \n\t" \ - "mov r10, r6 \n\t" \ - "mov r11, r7 \n\t" \ - "pop {r4, r5, r6, r7, pc}" : : "r" (sp) : "memory"); \ -} - /** * @brief Performs a context switch between two threads. * @details This is the most critical code in any port, this function @@ -146,35 +163,22 @@ __attribute__((naked)) void _port_switch(Thread *ntp, Thread *otp) { register struct intctx *r13 asm ("r13"); - PUSH_CONTEXT(r13); + asm volatile ("push {r4, r5, r6, r7, lr} \n\t" + "mov r4, r8 \n\t" + "mov r5, r9 \n\t" + "mov r6, r10 \n\t" + "mov r7, r11 \n\t" + "push {r4, r5, r6, r7}" : : : "memory"); otp->p_ctx.r13 = r13; r13 = ntp->p_ctx.r13; - 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) { - register struct extctx *ctxp; - - port_lock_from_isr(); - /* 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.*/ - } + asm volatile ("pop {r4, r5, r6, r7} \n\t" + "mov r8, r4 \n\t" + "mov r9, r5 \n\t" + "mov r10, r6 \n\t" + "mov r11, r7 \n\t" + "pop {r4, r5, r6, r7, pc}" : : "r" (sp) : "memory"); } /** diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index 34d1ee911..3e2e175bb 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -349,30 +349,14 @@ struct context { } #endif -/** - * @brief Excludes the default @p chSchIsPreemptionRequired()implementation. - */ -#define PORT_OPTIMIZED_ISPREEMPTIONREQUIRED - -#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__) -/** - * @brief Inlineable version of this kernel function. - */ -#define chSchIsPreemptionRequired() \ - (rlist.r_preempt ? firstprio(&rlist.r_queue) > currp->p_prio : \ - firstprio(&rlist.r_queue) >= currp->p_prio) -#else /* CH_TIME_QUANTUM == 0 */ -#define chSchIsPreemptionRequired() \ - (firstprio(&rlist.r_queue) > currp->p_prio) -#endif /* CH_TIME_QUANTUM == 0 */ - #ifdef __cplusplus 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_exit_from_isr(void); + void _port_switch(Thread *ntp, Thread *otp); void _port_thread_start(void); #ifdef __cplusplus } diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c index 30ba9c220..87f62dddc 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.c +++ b/os/ports/GCC/ARMCMx/chcore_v7m.c @@ -188,7 +188,6 @@ void _port_irq_epilogue(void) { else { /* Preemption not required, we just need to exit the exception atomically.*/ - void _port_exit_from_isr(void); ctxp->pc = _port_exit_from_isr; } diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h index 4ea70b8fb..56eca0d0e 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.h +++ b/os/ports/GCC/ARMCMx/chcore_v7m.h @@ -486,31 +486,15 @@ struct context { } #endif -/** - * @brief Excludes the default @p chSchIsPreemptionRequired()implementation. - */ -#define PORT_OPTIMIZED_ISPREEMPTIONREQUIRED - -#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__) -/** - * @brief Inlineable version of this kernel function. - */ -#define chSchIsPreemptionRequired() \ - (rlist.r_preempt ? firstprio(&rlist.r_queue) > currp->p_prio : \ - firstprio(&rlist.r_queue) >= currp->p_prio) -#else /* CH_TIME_QUANTUM == 0 */ -#define chSchIsPreemptionRequired() \ - (firstprio(&rlist.r_queue) > currp->p_prio) -#endif /* CH_TIME_QUANTUM == 0 */ - #ifdef __cplusplus extern "C" { #endif void port_halt(void); void _port_init(void); - void _port_switch(Thread *ntp, Thread *otp); void _port_irq_epilogue(void); void _port_switch_from_isr(void); + void _port_exit_from_isr(void); + void _port_switch(Thread *ntp, Thread *otp); void _port_thread_start(void); #if !CH_OPTIMIZE_SPEED void _port_lock(void); -- cgit v1.2.3