summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2012-01-04 18:07:21 +0100
committerThomas Martitz <kugel@rockbox.org>2012-01-22 18:46:44 +0100
commit991ae1e39553172a7dd6cd8c634aebfce892e261 (patch)
tree672a4583af663def399c4fefdbad060605397fbc
parenteaa83bd64775b87e943d345e2810deed44408776 (diff)
downloadrockbox-991ae1e39553172a7dd6cd8c634aebfce892e261.tar.gz
rockbox-991ae1e39553172a7dd6cd8c634aebfce892e261.zip
Create fimrware/asm directory for assembly optimized stuff.
This dir is suitable for stuff that doesn't fit the target tree, e.g. because it also builds on hosted or otherwise. It also has a generic subfolder for fallback C implementations so that not all archs need to provide asm files. SOURCES should only contain "foo.c" where foo.c includes the specific <arch>/foo.c files from the subdirs using the preprocessor. This way automatic selection of asm versions or generic C verion is possible. For the start, the thread support files are moved, since ASM threads can be used on hosted platforms as well. Since core_sleep() remains platform specific it's moved to the corresponding system.h headers. Change-Id: Iebff272f3407a6eaafeb7656ceb0ae9eca3f7cb9
-rw-r--r--firmware/asm/arm/thread.c (renamed from firmware/target/hosted/thread-arm.c)33
-rw-r--r--firmware/asm/arm/thread.h36
-rw-r--r--firmware/asm/m68k/thread.c (renamed from firmware/target/coldfire/thread-coldfire.c)10
-rw-r--r--firmware/asm/m68k/thread.h31
-rw-r--r--firmware/asm/mips/thread-mips32.c (renamed from firmware/target/mips/thread-mips32.c)22
-rw-r--r--firmware/asm/mips/thread.c6
-rw-r--r--firmware/asm/mips/thread.h31
-rw-r--r--firmware/asm/sh/thread.c (renamed from firmware/target/sh/thread-sh.c)13
-rw-r--r--firmware/asm/sh/thread.h30
-rw-r--r--firmware/asm/thread-unix.c (renamed from firmware/target/hosted/thread-unix.c)9
-rw-r--r--firmware/asm/thread-win32.c (renamed from firmware/target/hosted/thread-win32.c)9
-rw-r--r--firmware/asm/thread.c21
-rw-r--r--firmware/asm/thread.h57
-rw-r--r--firmware/export/thread.h68
-rw-r--r--firmware/target/arm/system-arm.h27
-rw-r--r--firmware/target/arm/thread-arm.c121
-rw-r--r--firmware/target/coldfire/system-target.h10
-rw-r--r--firmware/target/hosted/android/system-target.h5
-rw-r--r--firmware/target/hosted/sdl/system-sdl.h9
-rw-r--r--firmware/target/hosted/system-hosted.h37
-rw-r--r--firmware/target/hosted/ypr0/system-target.h5
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h24
-rw-r--r--firmware/target/sh/system-target.h14
-rw-r--r--firmware/thread.c19
24 files changed, 352 insertions, 295 deletions
diff --git a/firmware/target/hosted/thread-arm.c b/firmware/asm/arm/thread.c
index 8815f063d7..fd443f2873 100644
--- a/firmware/target/hosted/thread-arm.c
+++ b/firmware/asm/arm/thread.c
@@ -8,7 +8,6 @@
* $Id$
*
* Copyright (C) 2005 by Thom Johansen
- * Copyright (C) 2010 by Thomas Martitz (Android-suitable core_sleep())
*
* Generic ARM threading support
*
@@ -22,8 +21,6 @@
*
****************************************************************************/
-#include <system.h>
-
/*---------------------------------------------------------------------------
* Start the thread running and terminate it if it returns
*---------------------------------------------------------------------------
@@ -36,10 +33,18 @@ static void __attribute__((naked)) USED_ATTR start_thread(void)
"ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */
"mov r1, #0 \n" /* Mark thread as running */
"str r1, [r0, #40] \n"
+#if NUM_CORES > 1
+ "ldr r0, =commit_discard_idcache \n" /* Invalidate this core's cache. */
+ "mov lr, pc \n" /* This could be the first entry into */
+ "bx r0 \n" /* plugin or codec code for this core. */
+#endif
"mov lr, pc \n" /* Call thread function */
"bx r4 \n"
); /* No clobber list - new thread doesn't care */
thread_exit();
+#if 0
+ asm volatile (".ltorg"); /* Dump constant pool */
+#endif
}
/* For startup, place context pointer in r4 slot, start_thread pointer in r5
@@ -74,26 +79,16 @@ static inline void load_context(const void* addr)
"cmp r0, #0 \n" /* Check for NULL */
/* If not already running, jump to start */
+#if ARM_ARCH == 4 && defined(USE_THUMB)
+ "ldmneia %0, { r0, r12 } \n"
+ "bxne r12 \n"
+#else
"ldmneia %0, { r0, pc } \n"
+#endif
+
"ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
: : "r" (addr) : "r0" /* only! */
);
}
-/*
- * this core sleep suspends the OS thread rockbox runs under, which greatly
- * reduces cpu usage (~100% to <10%)
- *
- * it returns when when the tick timer is called, other interrupt-like
- * events occur
- *
- * wait_for_interrupt is implemented in kernel-<platform>.c
- **/
-
-static inline void core_sleep(void)
-{
- enable_irq();
- wait_for_interrupt();
-}
-
diff --git a/firmware/asm/arm/thread.h b/firmware/asm/arm/thread.h
new file mode 100644
index 0000000000..ec9bbcb3cd
--- /dev/null
+++ b/firmware/asm/arm/thread.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Ulf Ralberg
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+
+struct regs
+{
+ uint32_t r[8]; /* 0-28 - Registers r4-r11 */
+ uint32_t sp; /* 32 - Stack pointer (r13) */
+ uint32_t lr; /* 36 - r14 (lr) */
+ uint32_t start; /* 40 - Thread start address, or NULL when started */
+};
+
+#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
+ #define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
+#else
+ #define DEFAULT_STACK_SIZE 0x400 /* Bytes */
+#endif
diff --git a/firmware/target/coldfire/thread-coldfire.c b/firmware/asm/m68k/thread.c
index e59a9390ba..7df89001d7 100644
--- a/firmware/target/coldfire/thread-coldfire.c
+++ b/firmware/asm/m68k/thread.c
@@ -87,16 +87,6 @@ static inline void load_context(const void* addr)
}
/*---------------------------------------------------------------------------
- * Put core in a power-saving state if waking list wasn't repopulated.
- *---------------------------------------------------------------------------
- */
-static inline void core_sleep(void)
-{
- /* Supervisor mode, interrupts enabled upon wakeup */
- asm volatile ("stop #0x2000");
-};
-
-/*---------------------------------------------------------------------------
* Call this from asm to make sure the sp is pointing to the
* correct place before the context is saved.
*---------------------------------------------------------------------------
diff --git a/firmware/asm/m68k/thread.h b/firmware/asm/m68k/thread.h
new file mode 100644
index 0000000000..9bdbed0c3e
--- /dev/null
+++ b/firmware/asm/m68k/thread.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Ulf Ralberg
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+struct regs
+{
+ uint32_t macsr; /* 0 - EMAC status register */
+ uint32_t d[6]; /* 4-24 - d2-d7 */
+ uint32_t a[5]; /* 28-44 - a2-a6 */
+ uint32_t sp; /* 48 - Stack pointer (a7) */
+ uint32_t start; /* 52 - Thread start address, or NULL when started */
+};
+
+#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
diff --git a/firmware/target/mips/thread-mips32.c b/firmware/asm/mips/thread-mips32.c
index ba90c8965b..e754df7e29 100644
--- a/firmware/target/mips/thread-mips32.c
+++ b/firmware/asm/mips/thread-mips32.c
@@ -109,25 +109,3 @@ static inline void load_context(const void* addr)
);
}
-/*---------------------------------------------------------------------------
- * Put core in a power-saving state.
- *---------------------------------------------------------------------------
- */
-static inline void core_sleep(void)
-{
-#if CONFIG_CPU == JZ4732
- __cpm_idle_mode();
-#endif
- asm volatile(".set mips32r2 \n"
- "mfc0 $8, $12 \n" /* mfc t0, $12 */
- "move $9, $8 \n" /* move t1, t0 */
- "la $10, 0x8000000 \n" /* la t2, 0x8000000 */
- "or $8, $8, $10 \n" /* Enable reduced power mode */
- "mtc0 $8, $12 \n" /* mtc t0, $12 */
- "wait \n"
- "mtc0 $9, $12 \n" /* mtc t1, $12 */
- ".set mips0 \n"
- ::: "t0", "t1", "t2"
- );
- enable_irq();
-}
diff --git a/firmware/asm/mips/thread.c b/firmware/asm/mips/thread.c
new file mode 100644
index 0000000000..37480da10a
--- /dev/null
+++ b/firmware/asm/mips/thread.c
@@ -0,0 +1,6 @@
+#if CPU_MIPS == 32
+ #include "thread-mips32.c"
+#else
+ #error Missing thread impl
+#endif
+
diff --git a/firmware/asm/mips/thread.h b/firmware/asm/mips/thread.h
new file mode 100644
index 0000000000..ac37560a68
--- /dev/null
+++ b/firmware/asm/mips/thread.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Ulf Ralberg
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+struct regs
+{
+ uint32_t r[9]; /* 0-32 - Registers s0-s7, fp */
+ uint32_t sp; /* 36 - Stack pointer */
+ uint32_t ra; /* 40 - Return address */
+ uint32_t start; /* 44 - Thread start address, or NULL when started */
+};
+
+#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
+
diff --git a/firmware/target/sh/thread-sh.c b/firmware/asm/sh/thread.c
index 0f844f204b..e63470c4a1 100644
--- a/firmware/target/sh/thread-sh.c
+++ b/firmware/asm/sh/thread.c
@@ -93,17 +93,4 @@ static inline void load_context(const void* addr)
);
}
-/*---------------------------------------------------------------------------
- * Put core in a power-saving state.
- *---------------------------------------------------------------------------
- */
-static inline void core_sleep(void)
-{
- asm volatile (
- "and.b #0x7f, @(r0, gbr) \n" /* Clear SBY (bit 7) in SBYCR */
- "mov #0, r1 \n" /* Enable interrupts */
- "ldc r1, sr \n" /* Following instruction cannot be interrupted */
- "sleep \n" /* Execute standby */
- : : "z"(&SBYCR-GBR) : "r1");
-}
diff --git a/firmware/asm/sh/thread.h b/firmware/asm/sh/thread.h
new file mode 100644
index 0000000000..aa5fe519c6
--- /dev/null
+++ b/firmware/asm/sh/thread.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Ulf Ralberg
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+struct regs
+{
+ uint32_t r[7]; /* 0-24 - Registers r8 thru r14 */
+ uint32_t sp; /* 28 - Stack pointer (r15) */
+ uint32_t pr; /* 32 - Procedure register */
+ uint32_t start; /* 36 - Thread start address, or NULL when started */
+};
+
+#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
diff --git a/firmware/target/hosted/thread-unix.c b/firmware/asm/thread-unix.c
index 79310e0600..3c5e7c96ee 100644
--- a/firmware/target/hosted/thread-unix.c
+++ b/firmware/asm/thread-unix.c
@@ -305,12 +305,3 @@ static inline void load_context(const void* addr)
}
swap_context(target_context, r->uc);
}
-
-/*
- * play nice with the host and sleep while waiting for the tick */
-extern void wait_for_interrupt(void);
-static inline void core_sleep(void)
-{
- enable_irq();
- wait_for_interrupt();
-}
diff --git a/firmware/target/hosted/thread-win32.c b/firmware/asm/thread-win32.c
index a60198494a..9125819ade 100644
--- a/firmware/target/hosted/thread-win32.c
+++ b/firmware/asm/thread-win32.c
@@ -74,12 +74,3 @@ static inline void load_context(const void* addr)
}
SwitchToFiber(context->uc);
}
-
-/*
- * play nice with the host and sleep while waiting for the tick */
-static inline void core_sleep(void)
-{
- enable_irq();
- wait_for_interrupt();
-}
-
diff --git a/firmware/asm/thread.c b/firmware/asm/thread.c
new file mode 100644
index 0000000000..49e71d73af
--- /dev/null
+++ b/firmware/asm/thread.c
@@ -0,0 +1,21 @@
+#if defined(CPU_ARM)
+ #include "arm/thread.c"
+#elif defined(CPU_COLDFIRE)
+ #include "m68k/thread.c"
+#elif CONFIG_CPU == SH7034
+ #include "sh/thread.c"
+#elif defined(CPU_MIPS)
+ #include "mips/thread.c"
+#else
+
+/* generic thread.c */
+
+#if defined(HAVE_WIN32_FIBER_THREADS)
+ #include "thread-win32.c"
+#elif defined(HAVE_SIGALTSTACK_THREADS)
+ #include "thread-unix.c"
+#else
+ #error Missing thread impl
+#endif
+
+#endif
diff --git a/firmware/asm/thread.h b/firmware/asm/thread.h
new file mode 100644
index 0000000000..9bdff3881e
--- /dev/null
+++ b/firmware/asm/thread.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Ulf Ralberg
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef __ASM_THREAD_H__
+#define __ASM_THREAD_H__
+#include "config.h"
+
+#if defined(CPU_ARM)
+ #include "arm/thread.h"
+#elif defined(CPU_COLDFIRE)
+ #include "m68k/thread.h"
+#elif CONFIG_CPU == SH7034
+ #include "sh/thread.h"
+#elif defined(CPU_MIPS)
+ #include "mips/thread.h"
+#else
+
+/* generic thread.h */
+
+struct regs
+{
+ void (*start)(void); /* thread's entry point, or NULL when started */
+ void* uc; /* host thread handle */
+ uintptr_t sp; /* Stack pointer, unused */
+ size_t stack_size; /* stack size, not always used */
+ uintptr_t stack; /* pointer to start of the stack buffer */
+};
+
+#ifdef HAVE_SIGALTSTACK_THREADS
+ #include <signal.h>
+ /* MINSIGSTKSZ for the OS to deliver the signal + 0x3000 for us */
+ #define DEFAULT_STACK_SIZE (MINSIGSTKSZ+0x3000) /* Bytes */
+#elif defined(HAVE_WIN32_FIBER_THREADS)
+ #define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
+#endif
+
+#endif /* __ASM_THREAD_H__ */
+
+#endif
diff --git a/firmware/export/thread.h b/firmware/export/thread.h
index da06557f9c..aaf9f4bf45 100644
--- a/firmware/export/thread.h
+++ b/firmware/export/thread.h
@@ -18,6 +18,7 @@
* KIND, either express or implied.
*
****************************************************************************/
+
#ifndef THREAD_H
#define THREAD_H
@@ -93,66 +94,8 @@
* maybe more expensive C lib functions?
*
* simulator (possibly) doesn't simulate stack usage anyway but well ... */
-#ifdef HAVE_SIGALTSTACK_THREADS
-#include <signal.h>
-/* MINSIGSTKSZ for the OS to deliver the signal + 0x3000 for us */
-#define DEFAULT_STACK_SIZE (MINSIGSTKSZ+0x3000) /* Bytes */
-#elif (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(HAVE_WIN32_FIBER_THREADS)
-#define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
-#else /* native threads, sdl threads */
-#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
-#endif
-
-
-#if defined(ASSEMBLER_THREADS)
-/* Need to keep structures inside the header file because debug_menu
- * needs them. */
-#ifdef CPU_COLDFIRE
-struct regs
-{
- uint32_t macsr; /* 0 - EMAC status register */
- uint32_t d[6]; /* 4-24 - d2-d7 */
- uint32_t a[5]; /* 28-44 - a2-a6 */
- uint32_t sp; /* 48 - Stack pointer (a7) */
- uint32_t start; /* 52 - Thread start address, or NULL when started */
-};
-#elif CONFIG_CPU == SH7034
-struct regs
-{
- uint32_t r[7]; /* 0-24 - Registers r8 thru r14 */
- uint32_t sp; /* 28 - Stack pointer (r15) */
- uint32_t pr; /* 32 - Procedure register */
- uint32_t start; /* 36 - Thread start address, or NULL when started */
-};
-#elif defined(CPU_ARM)
-struct regs
-{
- uint32_t r[8]; /* 0-28 - Registers r4-r11 */
- uint32_t sp; /* 32 - Stack pointer (r13) */
- uint32_t lr; /* 36 - r14 (lr) */
- uint32_t start; /* 40 - Thread start address, or NULL when started */
-};
-#elif defined(CPU_MIPS)
-struct regs
-{
- uint32_t r[9]; /* 0-32 - Registers s0-s7, fp */
- uint32_t sp; /* 36 - Stack pointer */
- uint32_t ra; /* 40 - Return address */
- uint32_t start; /* 44 - Thread start address, or NULL when started */
-};
-#endif /* CONFIG_CPU */
-#elif (CONFIG_PLATFORM & PLATFORM_HOSTED) || defined(__PCTOOL__)
-#ifndef HAVE_SDL_THREADS
-struct regs
-{
- void (*start)(void); /* thread's entry point, or NULL when started */
- void* uc; /* host thread handle */
- uintptr_t sp; /* Stack pointer, unused */
- size_t stack_size; /* stack size, not always used */
- uintptr_t stack; /* pointer to start of the stack buffer */
-};
-#else /* SDL threads */
+#ifdef HAVE_SDL_THREADS
struct regs
{
void *t; /* OS thread */
@@ -160,8 +103,11 @@ struct regs
void *s; /* Semaphore for blocking and wakeup */
void (*start)(void); /* Start function */
};
-#endif
-#endif /* PLATFORM_NATIVE */
+
+#define DEFAULT_STACK_SIZE 0x100 /* tiny, ignored anyway */
+#else
+#include "asm/thread.h"
+#endif /* HAVE_SDL_THREADS */
#ifdef CPU_PP
#ifdef HAVE_CORELOCK_OBJECT
diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h
index ffce77a176..719ec82f1b 100644
--- a/firmware/target/arm/system-arm.h
+++ b/firmware/target/arm/system-arm.h
@@ -347,4 +347,31 @@ static inline uint32_t swaw32_hw(uint32_t value)
}
+#if defined(CPU_TCC780X) || defined(CPU_TCC77X) /* Single core only for now */ \
+|| CONFIG_CPU == IMX31L || CONFIG_CPU == DM320 || CONFIG_CPU == AS3525 \
+|| CONFIG_CPU == S3C2440 || CONFIG_CPU == S5L8701 || CONFIG_CPU == AS3525v2 \
+|| CONFIG_CPU == S5L8702
+/* Use the generic ARMv4/v5/v6 wait for IRQ */
+static inline void core_sleep(void)
+{
+ asm volatile (
+ "mcr p15, 0, %0, c7, c0, 4 \n" /* Wait for interrupt */
+#if CONFIG_CPU == IMX31L
+ "nop\n nop\n nop\n nop\n nop\n" /* Clean out the pipes */
+#endif
+ : : "r"(0)
+ );
+ enable_irq();
+}
+#else
+/* Skip this if special code is required and implemented */
+#if !(defined(CPU_PP)) && CONFIG_CPU != RK27XX && CONFIG_CPU != IMX233
+static inline void core_sleep(void)
+{
+ /* TODO: core_sleep not implemented, battery life will be decreased */
+ enable_irq();
+}
+#endif /* CPU_PP */
+#endif
+
#endif /* SYSTEM_ARM_H */
diff --git a/firmware/target/arm/thread-arm.c b/firmware/target/arm/thread-arm.c
deleted file mode 100644
index 88dac2542a..0000000000
--- a/firmware/target/arm/thread-arm.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2005 by Thom Johansen
- *
- * Generic ARM threading support
- *
- * This program 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 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-/*---------------------------------------------------------------------------
- * Start the thread running and terminate it if it returns
- *---------------------------------------------------------------------------
- */
-static void __attribute__((naked)) USED_ATTR start_thread(void)
-{
- /* r0 = context */
- asm volatile (
- "ldr sp, [r0, #32] \n" /* Load initial sp */
- "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */
- "mov r1, #0 \n" /* Mark thread as running */
- "str r1, [r0, #40] \n"
-#if NUM_CORES > 1
- "ldr r0, =commit_discard_idcache \n" /* Invalidate this core's cache. */
- "mov lr, pc \n" /* This could be the first entry into */
- "bx r0 \n" /* plugin or codec code for this core. */
-#endif
- "mov lr, pc \n" /* Call thread function */
- "bx r4 \n"
- ); /* No clobber list - new thread doesn't care */
- thread_exit();
-#if 0
- asm volatile (".ltorg"); /* Dump constant pool */
-#endif
-}
-
-/* For startup, place context pointer in r4 slot, start_thread pointer in r5
- * slot, and thread function pointer in context.start. See load_context for
- * what happens when thread is initially going to run. */
-#define THREAD_STARTUP_INIT(core, thread, function) \
- ({ (thread)->context.r[0] = (uint32_t)&(thread)->context, \
- (thread)->context.r[1] = (uint32_t)start_thread, \
- (thread)->context.start = (uint32_t)function; })
-
-
-/*---------------------------------------------------------------------------
- * Store non-volatile context.
- *---------------------------------------------------------------------------
- */
-static inline void store_context(void* addr)
-{
- asm volatile(
- "stmia %0, { r4-r11, sp, lr } \n"
- : : "r" (addr)
- );
-}
-
-/*---------------------------------------------------------------------------
- * Load non-volatile context.
- *---------------------------------------------------------------------------
- */
-static inline void load_context(const void* addr)
-{
- asm volatile(
- "ldr r0, [%0, #40] \n" /* Load start pointer */
- "cmp r0, #0 \n" /* Check for NULL */
-
- /* If not already running, jump to start */
-#if ARM_ARCH == 4 && defined(USE_THUMB)
- "ldmneia %0, { r0, r12 } \n"
- "bxne r12 \n"
-#else
- "ldmneia %0, { r0, pc } \n"
-#endif
-
- "ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
- : : "r" (addr) : "r0" /* only! */
- );
-}
-
-#if defined(CPU_TCC780X) || defined(CPU_TCC77X) /* Single core only for now */ \
-|| CONFIG_CPU == IMX31L || CONFIG_CPU == DM320 || CONFIG_CPU == AS3525 \
-|| CONFIG_CPU == S3C2440 || CONFIG_CPU == S5L8701 || CONFIG_CPU == AS3525v2 \
-|| CONFIG_CPU == S5L8702
-/* Use the generic ARMv4/v5/v6 wait for IRQ */
-static inline void core_sleep(void)
-{
- asm volatile (
- "mcr p15, 0, %0, c7, c0, 4 \n" /* Wait for interrupt */
-#if CONFIG_CPU == IMX31L
- "nop\n nop\n nop\n nop\n nop\n" /* Clean out the pipes */
-#endif
- : : "r"(0)
- );
- enable_irq();
-}
-#else
-/* Skip this if special code is required and implemented */
-#if !(defined(CPU_PP)) && CONFIG_CPU != RK27XX && CONFIG_CPU != IMX233
-static inline void core_sleep(void)
-{
- /* TODO: core_sleep not implemented, battery life will be decreased */
- enable_irq();
-}
-#endif /* CPU_PP */
-#endif
-
-
diff --git a/firmware/target/coldfire/system-target.h b/firmware/target/coldfire/system-target.h
index 74767c4583..5c810eb9b1 100644
--- a/firmware/target/coldfire/system-target.h
+++ b/firmware/target/coldfire/system-target.h
@@ -223,4 +223,14 @@ void commit_discard_idcache(void);
static inline void commit_discard_dcache(void) {}
static inline void commit_dcache(void) {}
+/*---------------------------------------------------------------------------
+ * Put core in a power-saving state if waking list wasn't repopulated.
+ *---------------------------------------------------------------------------
+ */
+static inline void core_sleep(void)
+{
+ /* Supervisor mode, interrupts enabled upon wakeup */
+ asm volatile ("stop #0x2000");
+};
+
#endif /* SYSTEM_TARGET_H */
diff --git a/firmware/target/hosted/android/system-target.h b/firmware/target/hosted/android/system-target.h
index aba7e6d6c0..fd81b6661e 100644
--- a/firmware/target/hosted/android/system-target.h
+++ b/firmware/target/hosted/android/system-target.h
@@ -23,10 +23,7 @@
#define __SYSTEM_TARGET_H__
#include "kernel-unix.h"
-
-static inline void commit_dcache(void) {}
-static inline void commit_discard_dcache(void) {}
-static inline void commit_discard_idcache(void) {}
+#include "system-hosted.h"
/* don't pull in jni.h for every user of this file, it should be only needed
* within the target tree (if at all)
diff --git a/firmware/target/hosted/sdl/system-sdl.h b/firmware/target/hosted/sdl/system-sdl.h
index d607e5e0a6..a20cbe5fac 100644
--- a/firmware/target/hosted/sdl/system-sdl.h
+++ b/firmware/target/hosted/sdl/system-sdl.h
@@ -41,6 +41,8 @@ int set_irq_level(int level);
#define restore_irq(level) \
((void)set_irq_level(level))
+#include "system-hosted.h"
+
void sim_enter_irq_handler(void);
void sim_exit_irq_handler(void);
void sim_kernel_shutdown(void);
@@ -48,17 +50,10 @@ void sys_poweroff(void);
void sys_handle_argv(int argc, char *argv[]);
void gui_message_loop(void);
void sim_do_exit(void) NORETURN_ATTR;
-#ifndef HAVE_SDL_THREADS
-void wait_for_interrupt(void);
-#endif
extern bool background; /* True if the background image is enabled */
extern bool showremote;
extern int display_zoom;
extern long start_tick;
-static inline void commit_dcache(void) {}
-static inline void commit_discard_dcache(void) {}
-static inline void commit_discard_idcache(void) {}
-
#endif /* _SYSTEM_SDL_H_ */
diff --git a/firmware/target/hosted/system-hosted.h b/firmware/target/hosted/system-hosted.h
new file mode 100644
index 0000000000..e60803fde0
--- /dev/null
+++ b/firmware/target/hosted/system-hosted.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 by Thomas Martitz
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef __SYSTEM_HOSTED_H__
+#define __SYSTEM_HOSTED_H__
+
+#include "system.h"
+
+static inline void commit_dcache(void) {}
+static inline void commit_discard_dcache(void) {}
+static inline void commit_discard_idcache(void) {}
+
+static inline void core_sleep(void)
+{
+ enable_irq();
+ wait_for_interrupt();
+}
+
+#endif
diff --git a/firmware/target/hosted/ypr0/system-target.h b/firmware/target/hosted/ypr0/system-target.h
index efd235282e..1ef8b9aeda 100644
--- a/firmware/target/hosted/ypr0/system-target.h
+++ b/firmware/target/hosted/ypr0/system-target.h
@@ -22,10 +22,7 @@
#define __SYSTEM_TARGET_H__
#include "kernel-unix.h"
-
-static inline void commit_dcache(void) {}
-static inline void commit_discard_dcache(void) {}
-static inline void commit_discard_idcache(void) {}
+#include "system-hosted.h"
#define NEED_GENERIC_BYTESWAPS
#endif /* __SYSTEM_TARGET_H__ */
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index caf1733158..1c2e7d7173 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -97,4 +97,28 @@ void dma_disable(void);
#define DMA_IRQ(n) (IRQ_DMA_0 + (n))
#define GPIO_IRQ(n) (IRQ_GPIO_0 + (n))
+/*---------------------------------------------------------------------------
+ * Put core in a power-saving state.
+ *---------------------------------------------------------------------------
+ */
+static inline void core_sleep(void)
+{
+#if CONFIG_CPU == JZ4732
+ __cpm_idle_mode();
+#endif
+ asm volatile(".set mips32r2 \n"
+ "mfc0 $8, $12 \n" /* mfc t0, $12 */
+ "move $9, $8 \n" /* move t1, t0 */
+ "la $10, 0x8000000 \n" /* la t2, 0x8000000 */
+ "or $8, $8, $10 \n" /* Enable reduced power mode */
+ "mtc0 $8, $12 \n" /* mtc t0, $12 */
+ "wait \n"
+ "mtc0 $9, $12 \n" /* mtc t1, $12 */
+ ".set mips0 \n"
+ ::: "t0", "t1", "t2"
+ );
+ enable_irq();
+}
+
+
#endif /* __SYSTEM_TARGET_H_ */
diff --git a/firmware/target/sh/system-target.h b/firmware/target/sh/system-target.h
index 5db9cc071f..a62a024823 100644
--- a/firmware/target/sh/system-target.h
+++ b/firmware/target/sh/system-target.h
@@ -137,4 +137,18 @@ static inline void commit_dcache(void) {}
static inline void commit_discard_dcache(void) {}
static inline void commit_discard_idcache(void) {}
+/*---------------------------------------------------------------------------
+ * Put core in a power-saving state.
+ *---------------------------------------------------------------------------
+ */
+static inline void core_sleep(void)
+{
+ asm volatile (
+ "and.b #0x7f, @(r0, gbr) \n" /* Clear SBY (bit 7) in SBYCR */
+ "mov #0, r1 \n" /* Enable interrupts */
+ "ldc r1, sr \n" /* Following instruction cannot be interrupted */
+ "sleep \n" /* Execute standby */
+ : : "z"(&SBYCR-GBR) : "r1");
+}
+
#endif /* SYSTEM_TARGET_H */
diff --git a/firmware/thread.c b/firmware/thread.c
index 732675abf8..5e543c558a 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -178,25 +178,12 @@ void switch_thread(void)
* Processor/OS-specific section - include necessary core support
*/
-#if defined(HAVE_WIN32_FIBER_THREADS)
-#include "thread-win32.c"
-#elif defined(HAVE_SIGALTSTACK_THREADS)
-#include "thread-unix.c"
-#elif defined(CPU_ARM)
-#include "thread-arm.c"
+
+#include "asm/thread.c"
+
#if defined (CPU_PP)
#include "thread-pp.c"
#endif /* CPU_PP */
-#elif defined(CPU_COLDFIRE)
-#include "thread-coldfire.c"
-#elif CONFIG_CPU == SH7034
-#include "thread-sh.c"
-#elif defined(CPU_MIPS) && CPU_MIPS == 32
-#include "thread-mips32.c"
-#else
-/* Wouldn't compile anyway */
-#error Processor not implemented.
-#endif /* CONFIG_CPU == */
#ifndef IF_NO_SKIP_YIELD
#define IF_NO_SKIP_YIELD(...)