diff --git a/os/ports/GCC/MSP430/chcore.c b/os/ports/GCC/MSP430/chcore.c
deleted file mode 100644
index 33a162cf5..000000000
--- a/os/ports/GCC/MSP430/chcore.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
- 2011,2012 Giovanni Di Sirio.
-
- This file is part of ChibiOS/RT.
-
- ChibiOS/RT is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/RT is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-/**
- * @file MSP430/chcore.c
- * @brief MSP430 architecture port code.
- *
- * @addtogroup MSP430_CORE
- * @{
- */
-
-#include "ch.h"
-
-/**
- * @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.
- * @note The function is declared as a weak symbol, it is possible to
- * redefine it in your application code.
- *
- * @param[in] ntp the thread to be switched in
- * @param[in] otp the thread to be switched out
- */
-#if !defined(__DOXYGEN__)
-__attribute__((naked, weak))
-#endif
-void port_switch(Thread *ntp, Thread *otp) {
- register struct intctx *sp asm("r1");
-
- asm volatile ("push r11 \n\t" \
- "push r10 \n\t" \
- "push r9 \n\t" \
- "push r8 \n\t" \
- "push r7 \n\t" \
- "push r6 \n\t" \
- "push r5 \n\t" \
- "push r4" : : : "memory");
- otp->p_ctx.sp = sp;
- sp = ntp->p_ctx.sp;
- asm volatile ("pop r4 \n\t" \
- "pop r5 \n\t" \
- "pop r6 \n\t" \
- "pop r7 \n\t" \
- "pop r8 \n\t" \
- "pop r9 \n\t" \
- "pop r10 \n\t" \
- "pop r11 \n\t" \
- "ret" : : "r" (sp) : "memory");
-}
-
-/**
- * @brief Halts the system.
- * @details This function is invoked by the operating system when an
- * unrecoverable error is detected (for example because a programming
- * error in the application code that triggers an assertion while in
- * debug mode).
- * @note The function is declared as a weak symbol, it is possible to
- * redefine it in your application code.
- */
-#if !defined(__DOXYGEN__)
-__attribute__((weak))
-#endif
-void port_halt(void) {
-
- port_disable();
- while (TRUE) {
- }
-}
-
-/**
- * @brief Start a thread by invoking its work function.
- * @details If the work function returns @p chThdExit() is automatically
- * invoked.
- */
-void _port_thread_start(void) {
-
- chSysUnlock();
- asm volatile ("mov r11, r15 \n\t" \
- "call r10 \n\t" \
- "call #chThdExit");
-}
-
-/** @} */
diff --git a/os/ports/GCC/MSP430/chcore.h b/os/ports/GCC/MSP430/chcore.h
index 10e18d9a6..5254c07bb 100644
--- a/os/ports/GCC/MSP430/chcore.h
+++ b/os/ports/GCC/MSP430/chcore.h
@@ -290,11 +290,21 @@ struct context {
#define port_wait_for_interrupt()
#endif
+/**
+ * @brief Wrapper of the assembler @p _port_switch() function.
+ */
+#define port_switch(ntp, otp) _port_switch(ntp, otp)
+
+/**
+ * @brief Wrapper of the assembler @p _port_halt() function.
+ */
+#define port_halt() _port_halt()
+
#ifdef __cplusplus
extern "C" {
#endif
- void port_switch(Thread *ntp, Thread *otp);
- void port_halt(void);
+ void _port_switch(Thread *ntp, Thread *otp);
+ void _port_halt(void);
void _port_thread_start(void);
#ifdef __cplusplus
}
diff --git a/os/ports/GCC/MSP430/chcoreasm.s b/os/ports/GCC/MSP430/chcoreasm.s
new file mode 100644
index 000000000..99c8744fd
--- /dev/null
+++ b/os/ports/GCC/MSP430/chcoreasm.s
@@ -0,0 +1,58 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+ .text
+ .p2align 1, 0
+ .weak _port_switch
+_port_switch:
+ push r11
+ push r10
+ push r9
+ push r8
+ push r7
+ push r6
+ push r5
+ push r4
+ mov r1, 6(r14)
+ mov 6(r15), r1
+ pop r4
+ pop r5
+ pop r6
+ pop r7
+ pop r8
+ pop r9
+ pop r10
+ pop r11
+ ret
+
+ .p2align 1, 0
+ .weak _port_thread_start
+_port_thread_start:
+ eint
+ mov r11, r15
+ call r10
+ call #chThdExit
+ ; Falls into _port_halt
+
+ .p2align 1, 0
+ .weak _port_halt
+_port_halt:
+ dint
+.L1: jmp .L1
diff --git a/os/ports/GCC/MSP430/port.mk b/os/ports/GCC/MSP430/port.mk
index 60b3f8add..8291fa9d9 100644
--- a/os/ports/GCC/MSP430/port.mk
+++ b/os/ports/GCC/MSP430/port.mk
@@ -1,6 +1,6 @@
# List of the ChibiOS/RT MSP430 port files.
-PORTSRC = ${CHIBIOS}/os/ports/GCC/MSP430/chcore.c
+PORTSRC =
-PORTASM =
+PORTASM = ${CHIBIOS}/os/ports/GCC/MSP430/chcoreasm.s
PORTINC = ${CHIBIOS}/os/ports/GCC/MSP430
diff --git a/readme.txt b/readme.txt
index e9ff9c40a..6236a800a 100644
--- a/readme.txt
+++ b/readme.txt
@@ -88,6 +88,8 @@
3591317)(backported to 2.4.3).
- FIX: Fixed errors in STM32F0xx UART driver (bug 3589412)(backported
to 2.4.3).
+- FIX: Fixed MSP430 port_switch code for MSPGCC issue (bug 3587633)(backported
+ to 2.4.3).
- FIX: Fixed workaround for errata in STM32F4-A devices (bug 3586425)
(backported to 2.4.3).
- FIX: Fixed error in palWritePad() macro (bug 3586230)(backported to 2.2.10