summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs/lib/codeclib.c4
-rw-r--r--firmware/thread.c11
2 files changed, 14 insertions, 1 deletions
diff --git a/apps/codecs/lib/codeclib.c b/apps/codecs/lib/codeclib.c
index 329b0e2..5af4e01 100644
--- a/apps/codecs/lib/codeclib.c
+++ b/apps/codecs/lib/codeclib.c
@@ -163,7 +163,9 @@ const uint8_t bs_clz_tab[256] ICONST_ATTR = {
#ifdef RB_PROFILE
void __cyg_profile_func_enter(void *this_fn, void *call_site) {
-#ifdef CPU_COLDFIRE
+/* This workaround is required for coldfire gcc 3.4 but is broken for 4.4
+ and 4.5, but for those the other way works. */
+#if defined(CPU_COLDFIRE) && defined(__GNUC__) && __GNUC__ < 4
(void)call_site;
ci->profile_func_enter(this_fn, __builtin_return_address(1));
#else
diff --git a/firmware/thread.c b/firmware/thread.c
index 655af1a..91fe81b 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -1149,8 +1149,19 @@ void switch_thread(void)
}
#ifdef RB_PROFILE
+#ifdef CPU_COLDFIRE
+ /* Call this from asm to make sure the sp is pointing to the
+ correct place before the context is saved */
+ uint16_t id = thread->id & THREAD_ID_SLOT_MASK;
+ asm volatile ("move.l %[id], -(%%sp)\n\t"
+ "jsr profile_thread_stopped\n\t"
+ "addq.l #4, %%sp\n\t"
+ :: [id] "r" (id)
+ : "cc", "memory");
+#else
profile_thread_stopped(thread->id & THREAD_ID_SLOT_MASK);
#endif
+#endif
/* Begin task switching by saving our current context so that we can
* restore the state of the current thread later to the point prior