aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/ports/GCC/PPC/chcore.c14
-rw-r--r--os/ports/GCC/PPC/chcore.h23
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
@@ -342,6 +342,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 <b>directly</b> 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.
*
* @param[in] spr special register number
@@ -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
}