From 24469eee457801a9fe66f6dc77a74c05c50fdbaf Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 13 Feb 2013 11:43:14 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5176 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ports/GCC/PPC/chcore.c | 14 +++++++++----- os/ports/GCC/PPC/chcore.h | 23 ++++++++++++++++++++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/os/ports/GCC/PPC/chcore.c b/os/ports/GCC/PPC/chcore.c index 8403e0171..c3170c6cf 100644 --- a/os/ports/GCC/PPC/chcore.c +++ b/os/ports/GCC/PPC/chcore.c @@ -67,11 +67,11 @@ void port_halt(void) { * @param[in] ntp the thread to be switched in * @param[in] otp the thread to be switched out */ -void port_switch(Thread *ntp, Thread *otp) { - - (void)otp; - (void)ntp; +__attribute__((naked)) +void port_dummy1(void) { + asm (".global _port_switch"); + asm ("_port_switch:"); asm ("subi %sp, %sp, 80"); /* Size of the intctx structure. */ asm ("mflr %r0"); asm ("stw %r0, 84(%sp)"); /* LR into the caller frame. */ @@ -88,6 +88,7 @@ void port_switch(Thread *ntp, Thread *otp) { asm ("lwz %r0, 84(%sp)"); /* LR from the caller frame. */ asm ("mtlr %r0"); asm ("addi %sp, %sp, 80"); /* Size of the intctx structure. */ + asm ("blr"); } /** @@ -95,8 +96,11 @@ void port_switch(Thread *ntp, Thread *otp) { * @details If the work function returns @p chThdExit() is automatically * invoked. */ -void _port_thread_start(void) { +__attribute__((naked)) +void port_dummy2(void) { + asm (".global _port_thread_start"); + asm ("_port_thread_start:"); chSysUnlock(); asm ("mr %r3, %r31"); /* Thread parameter. */ asm ("mtctr %r30"); diff --git a/os/ports/GCC/PPC/chcore.h b/os/ports/GCC/PPC/chcore.h index c64737c67..0f78b3b9b 100644 --- a/os/ports/GCC/PPC/chcore.h +++ b/os/ports/GCC/PPC/chcore.h @@ -341,6 +341,27 @@ struct context { */ #define port_enable() asm volatile ("wrteei 1" : : : "memory") +/** + * @brief Performs a context switch between two threads. + * @details This is the most critical code in any port, this function + * is responsible for the context switch between 2 threads. + * @note The implementation of this code affects directly the context + * switch performance so optimize here as much as you can. + * + * @param[in] ntp the thread to be switched in + * @param[in] otp the thread to be switched out + */ +#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) +#define port_switch(ntp, otp) _port_switch(ntp, otp) +#else +#define port_switch(ntp, otp) { \ + register struct intctx *sp asm ("%r1"); \ + if ((stkalign_t *)(sp - 1) < otp->p_stklimit) \ + chDbgPanic("stack overflow"); \ + _port_switch(ntp, otp); \ +} +#endif + /** * @brief Writes to a special register. * @@ -369,7 +390,7 @@ extern "C" { #endif void port_init(void); void port_halt(void); - void port_switch(Thread *ntp, Thread *otp); + void _port_switch(Thread *ntp, Thread *otp); void _port_thread_start(void); #ifdef __cplusplus } -- cgit v1.2.3