summaryrefslogtreecommitdiff
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 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2005 by Thom Johansen 10 * Copyright (C) 2005 by Thom Johansen
11 * Copyright (C) 2010 by Thomas Martitz (Android-suitable core_sleep())
12 * 11 *
13 * Generic ARM threading support 12 * Generic ARM threading support
14 * 13 *
@@ -22,8 +21,6 @@
22 * 21 *
23 ****************************************************************************/ 22 ****************************************************************************/
24 23
25#include <system.h>
26
27/*--------------------------------------------------------------------------- 24/*---------------------------------------------------------------------------
28 * Start the thread running and terminate it if it returns 25 * Start the thread running and terminate it if it returns
29 *--------------------------------------------------------------------------- 26 *---------------------------------------------------------------------------
@@ -36,10 +33,18 @@ static void __attribute__((naked)) USED_ATTR start_thread(void)
36 "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */ 33 "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */
37 "mov r1, #0 \n" /* Mark thread as running */ 34 "mov r1, #0 \n" /* Mark thread as running */
38 "str r1, [r0, #40] \n" 35 "str r1, [r0, #40] \n"
36#if NUM_CORES > 1
37 "ldr r0, =commit_discard_idcache \n" /* Invalidate this core's cache. */
38 "mov lr, pc \n" /* This could be the first entry into */
39 "bx r0 \n" /* plugin or codec code for this core. */
40#endif
39 "mov lr, pc \n" /* Call thread function */ 41 "mov lr, pc \n" /* Call thread function */
40 "bx r4 \n" 42 "bx r4 \n"
41 ); /* No clobber list - new thread doesn't care */ 43 ); /* No clobber list - new thread doesn't care */
42 thread_exit(); 44 thread_exit();
45#if 0
46 asm volatile (".ltorg"); /* Dump constant pool */
47#endif
43} 48}
44 49
45/* For startup, place context pointer in r4 slot, start_thread pointer in r5 50/* 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)
74 "cmp r0, #0 \n" /* Check for NULL */ 79 "cmp r0, #0 \n" /* Check for NULL */
75 80
76 /* If not already running, jump to start */ 81 /* If not already running, jump to start */
82#if ARM_ARCH == 4 && defined(USE_THUMB)
83 "ldmneia %0, { r0, r12 } \n"
84 "bxne r12 \n"
85#else
77 "ldmneia %0, { r0, pc } \n" 86 "ldmneia %0, { r0, pc } \n"
87#endif
88
78 "ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */ 89 "ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
79 : : "r" (addr) : "r0" /* only! */ 90 : : "r" (addr) : "r0" /* only! */
80 ); 91 );
81} 92}
82 93
83/*
84 * this core sleep suspends the OS thread rockbox runs under, which greatly
85 * reduces cpu usage (~100% to <10%)
86 *
87 * it returns when when the tick timer is called, other interrupt-like
88 * events occur
89 *
90 * wait_for_interrupt is implemented in kernel-<platform>.c
91 **/
92
93static inline void core_sleep(void)
94{
95 enable_irq();
96 wait_for_interrupt();
97}
98
99 94
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Ulf Ralberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23
24struct regs
25{
26 uint32_t r[8]; /* 0-28 - Registers r4-r11 */
27 uint32_t sp; /* 32 - Stack pointer (r13) */
28 uint32_t lr; /* 36 - r14 (lr) */
29 uint32_t start; /* 40 - Thread start address, or NULL when started */
30};
31
32#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
33 #define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
34#else
35 #define DEFAULT_STACK_SIZE 0x400 /* Bytes */
36#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)
87} 87}
88 88
89/*--------------------------------------------------------------------------- 89/*---------------------------------------------------------------------------
90 * Put core in a power-saving state if waking list wasn't repopulated.
91 *---------------------------------------------------------------------------
92 */
93static inline void core_sleep(void)
94{
95 /* Supervisor mode, interrupts enabled upon wakeup */
96 asm volatile ("stop #0x2000");
97};
98
99/*---------------------------------------------------------------------------
100 * Call this from asm to make sure the sp is pointing to the 90 * Call this from asm to make sure the sp is pointing to the
101 * correct place before the context is saved. 91 * correct place before the context is saved.
102 *--------------------------------------------------------------------------- 92 *---------------------------------------------------------------------------
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Ulf Ralberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22struct regs
23{
24 uint32_t macsr; /* 0 - EMAC status register */
25 uint32_t d[6]; /* 4-24 - d2-d7 */
26 uint32_t a[5]; /* 28-44 - a2-a6 */
27 uint32_t sp; /* 48 - Stack pointer (a7) */
28 uint32_t start; /* 52 - Thread start address, or NULL when started */
29};
30
31#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)
109 ); 109 );
110} 110}
111 111
112/*---------------------------------------------------------------------------
113 * Put core in a power-saving state.
114 *---------------------------------------------------------------------------
115 */
116static inline void core_sleep(void)
117{
118#if CONFIG_CPU == JZ4732
119 __cpm_idle_mode();
120#endif
121 asm volatile(".set mips32r2 \n"
122 "mfc0 $8, $12 \n" /* mfc t0, $12 */
123 "move $9, $8 \n" /* move t1, t0 */
124 "la $10, 0x8000000 \n" /* la t2, 0x8000000 */
125 "or $8, $8, $10 \n" /* Enable reduced power mode */
126 "mtc0 $8, $12 \n" /* mtc t0, $12 */
127 "wait \n"
128 "mtc0 $9, $12 \n" /* mtc t1, $12 */
129 ".set mips0 \n"
130 ::: "t0", "t1", "t2"
131 );
132 enable_irq();
133}
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 @@
1#if CPU_MIPS == 32
2 #include "thread-mips32.c"
3#else
4 #error Missing thread impl
5#endif
6
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Ulf Ralberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22struct regs
23{
24 uint32_t r[9]; /* 0-32 - Registers s0-s7, fp */
25 uint32_t sp; /* 36 - Stack pointer */
26 uint32_t ra; /* 40 - Return address */
27 uint32_t start; /* 44 - Thread start address, or NULL when started */
28};
29
30#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
31
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)
93 ); 93 );
94} 94}
95 95
96/*---------------------------------------------------------------------------
97 * Put core in a power-saving state.
98 *---------------------------------------------------------------------------
99 */
100static inline void core_sleep(void)
101{
102 asm volatile (
103 "and.b #0x7f, @(r0, gbr) \n" /* Clear SBY (bit 7) in SBYCR */
104 "mov #0, r1 \n" /* Enable interrupts */
105 "ldc r1, sr \n" /* Following instruction cannot be interrupted */
106 "sleep \n" /* Execute standby */
107 : : "z"(&SBYCR-GBR) : "r1");
108}
109 96
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Ulf Ralberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22struct regs
23{
24 uint32_t r[7]; /* 0-24 - Registers r8 thru r14 */
25 uint32_t sp; /* 28 - Stack pointer (r15) */
26 uint32_t pr; /* 32 - Procedure register */
27 uint32_t start; /* 36 - Thread start address, or NULL when started */
28};
29
30#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)
305 } 305 }
306 swap_context(target_context, r->uc); 306 swap_context(target_context, r->uc);
307} 307}
308
309/*
310 * play nice with the host and sleep while waiting for the tick */
311extern void wait_for_interrupt(void);
312static inline void core_sleep(void)
313{
314 enable_irq();
315 wait_for_interrupt();
316}
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)
74 } 74 }
75 SwitchToFiber(context->uc); 75 SwitchToFiber(context->uc);
76} 76}
77
78/*
79 * play nice with the host and sleep while waiting for the tick */
80static inline void core_sleep(void)
81{
82 enable_irq();
83 wait_for_interrupt();
84}
85
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 @@
1#if defined(CPU_ARM)
2 #include "arm/thread.c"
3#elif defined(CPU_COLDFIRE)
4 #include "m68k/thread.c"
5#elif CONFIG_CPU == SH7034
6 #include "sh/thread.c"
7#elif defined(CPU_MIPS)
8 #include "mips/thread.c"
9#else
10
11/* generic thread.c */
12
13#if defined(HAVE_WIN32_FIBER_THREADS)
14 #include "thread-win32.c"
15#elif defined(HAVE_SIGALTSTACK_THREADS)
16 #include "thread-unix.c"
17#else
18 #error Missing thread impl
19#endif
20
21#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Ulf Ralberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __ASM_THREAD_H__
23#define __ASM_THREAD_H__
24#include "config.h"
25
26#if defined(CPU_ARM)
27 #include "arm/thread.h"
28#elif defined(CPU_COLDFIRE)
29 #include "m68k/thread.h"
30#elif CONFIG_CPU == SH7034
31 #include "sh/thread.h"
32#elif defined(CPU_MIPS)
33 #include "mips/thread.h"
34#else
35
36/* generic thread.h */
37
38struct regs
39{
40 void (*start)(void); /* thread's entry point, or NULL when started */
41 void* uc; /* host thread handle */
42 uintptr_t sp; /* Stack pointer, unused */
43 size_t stack_size; /* stack size, not always used */
44 uintptr_t stack; /* pointer to start of the stack buffer */
45};
46
47#ifdef HAVE_SIGALTSTACK_THREADS
48 #include <signal.h>
49 /* MINSIGSTKSZ for the OS to deliver the signal + 0x3000 for us */
50 #define DEFAULT_STACK_SIZE (MINSIGSTKSZ+0x3000) /* Bytes */
51#elif defined(HAVE_WIN32_FIBER_THREADS)
52 #define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
53#endif
54
55#endif /* __ASM_THREAD_H__ */
56
57#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 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21
21#ifndef THREAD_H 22#ifndef THREAD_H
22#define THREAD_H 23#define THREAD_H
23 24
@@ -93,66 +94,8 @@
93 * maybe more expensive C lib functions? 94 * maybe more expensive C lib functions?
94 * 95 *
95 * simulator (possibly) doesn't simulate stack usage anyway but well ... */ 96 * simulator (possibly) doesn't simulate stack usage anyway but well ... */
96#ifdef HAVE_SIGALTSTACK_THREADS
97#include <signal.h>
98/* MINSIGSTKSZ for the OS to deliver the signal + 0x3000 for us */
99#define DEFAULT_STACK_SIZE (MINSIGSTKSZ+0x3000) /* Bytes */
100#elif (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(HAVE_WIN32_FIBER_THREADS)
101#define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
102#else /* native threads, sdl threads */
103#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
104#endif
105
106
107#if defined(ASSEMBLER_THREADS)
108/* Need to keep structures inside the header file because debug_menu
109 * needs them. */
110#ifdef CPU_COLDFIRE
111struct regs
112{
113 uint32_t macsr; /* 0 - EMAC status register */
114 uint32_t d[6]; /* 4-24 - d2-d7 */
115 uint32_t a[5]; /* 28-44 - a2-a6 */
116 uint32_t sp; /* 48 - Stack pointer (a7) */
117 uint32_t start; /* 52 - Thread start address, or NULL when started */
118};
119#elif CONFIG_CPU == SH7034
120struct regs
121{
122 uint32_t r[7]; /* 0-24 - Registers r8 thru r14 */
123 uint32_t sp; /* 28 - Stack pointer (r15) */
124 uint32_t pr; /* 32 - Procedure register */
125 uint32_t start; /* 36 - Thread start address, or NULL when started */
126};
127#elif defined(CPU_ARM)
128struct regs
129{
130 uint32_t r[8]; /* 0-28 - Registers r4-r11 */
131 uint32_t sp; /* 32 - Stack pointer (r13) */
132 uint32_t lr; /* 36 - r14 (lr) */
133 uint32_t start; /* 40 - Thread start address, or NULL when started */
134};
135 97
136#elif defined(CPU_MIPS) 98#ifdef HAVE_SDL_THREADS
137struct regs
138{
139 uint32_t r[9]; /* 0-32 - Registers s0-s7, fp */
140 uint32_t sp; /* 36 - Stack pointer */
141 uint32_t ra; /* 40 - Return address */
142 uint32_t start; /* 44 - Thread start address, or NULL when started */
143};
144#endif /* CONFIG_CPU */
145#elif (CONFIG_PLATFORM & PLATFORM_HOSTED) || defined(__PCTOOL__)
146#ifndef HAVE_SDL_THREADS
147struct regs
148{
149 void (*start)(void); /* thread's entry point, or NULL when started */
150 void* uc; /* host thread handle */
151 uintptr_t sp; /* Stack pointer, unused */
152 size_t stack_size; /* stack size, not always used */
153 uintptr_t stack; /* pointer to start of the stack buffer */
154};
155#else /* SDL threads */
156struct regs 99struct regs
157{ 100{
158 void *t; /* OS thread */ 101 void *t; /* OS thread */
@@ -160,8 +103,11 @@ struct regs
160 void *s; /* Semaphore for blocking and wakeup */ 103 void *s; /* Semaphore for blocking and wakeup */
161 void (*start)(void); /* Start function */ 104 void (*start)(void); /* Start function */
162}; 105};
163#endif 106
164#endif /* PLATFORM_NATIVE */ 107#define DEFAULT_STACK_SIZE 0x100 /* tiny, ignored anyway */
108#else
109#include "asm/thread.h"
110#endif /* HAVE_SDL_THREADS */
165 111
166#ifdef CPU_PP 112#ifdef CPU_PP
167#ifdef HAVE_CORELOCK_OBJECT 113#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)
347 347
348} 348}
349 349
350#if defined(CPU_TCC780X) || defined(CPU_TCC77X) /* Single core only for now */ \
351|| CONFIG_CPU == IMX31L || CONFIG_CPU == DM320 || CONFIG_CPU == AS3525 \
352|| CONFIG_CPU == S3C2440 || CONFIG_CPU == S5L8701 || CONFIG_CPU == AS3525v2 \
353|| CONFIG_CPU == S5L8702
354/* Use the generic ARMv4/v5/v6 wait for IRQ */
355static inline void core_sleep(void)
356{
357 asm volatile (
358 "mcr p15, 0, %0, c7, c0, 4 \n" /* Wait for interrupt */
359#if CONFIG_CPU == IMX31L
360 "nop\n nop\n nop\n nop\n nop\n" /* Clean out the pipes */
361#endif
362 : : "r"(0)
363 );
364 enable_irq();
365}
366#else
367/* Skip this if special code is required and implemented */
368#if !(defined(CPU_PP)) && CONFIG_CPU != RK27XX && CONFIG_CPU != IMX233
369static inline void core_sleep(void)
370{
371 /* TODO: core_sleep not implemented, battery life will be decreased */
372 enable_irq();
373}
374#endif /* CPU_PP */
375#endif
376
350#endif /* SYSTEM_ARM_H */ 377#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Thom Johansen
11 *
12 * Generic ARM threading support
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24/*---------------------------------------------------------------------------
25 * Start the thread running and terminate it if it returns
26 *---------------------------------------------------------------------------
27 */
28static void __attribute__((naked)) USED_ATTR start_thread(void)
29{
30 /* r0 = context */
31 asm volatile (
32 "ldr sp, [r0, #32] \n" /* Load initial sp */
33 "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */
34 "mov r1, #0 \n" /* Mark thread as running */
35 "str r1, [r0, #40] \n"
36#if NUM_CORES > 1
37 "ldr r0, =commit_discard_idcache \n" /* Invalidate this core's cache. */
38 "mov lr, pc \n" /* This could be the first entry into */
39 "bx r0 \n" /* plugin or codec code for this core. */
40#endif
41 "mov lr, pc \n" /* Call thread function */
42 "bx r4 \n"
43 ); /* No clobber list - new thread doesn't care */
44 thread_exit();
45#if 0
46 asm volatile (".ltorg"); /* Dump constant pool */
47#endif
48}
49
50/* For startup, place context pointer in r4 slot, start_thread pointer in r5
51 * slot, and thread function pointer in context.start. See load_context for
52 * what happens when thread is initially going to run. */
53#define THREAD_STARTUP_INIT(core, thread, function) \
54 ({ (thread)->context.r[0] = (uint32_t)&(thread)->context, \
55 (thread)->context.r[1] = (uint32_t)start_thread, \
56 (thread)->context.start = (uint32_t)function; })
57
58
59/*---------------------------------------------------------------------------
60 * Store non-volatile context.
61 *---------------------------------------------------------------------------
62 */
63static inline void store_context(void* addr)
64{
65 asm volatile(
66 "stmia %0, { r4-r11, sp, lr } \n"
67 : : "r" (addr)
68 );
69}
70
71/*---------------------------------------------------------------------------
72 * Load non-volatile context.
73 *---------------------------------------------------------------------------
74 */
75static inline void load_context(const void* addr)
76{
77 asm volatile(
78 "ldr r0, [%0, #40] \n" /* Load start pointer */
79 "cmp r0, #0 \n" /* Check for NULL */
80
81 /* If not already running, jump to start */
82#if ARM_ARCH == 4 && defined(USE_THUMB)
83 "ldmneia %0, { r0, r12 } \n"
84 "bxne r12 \n"
85#else
86 "ldmneia %0, { r0, pc } \n"
87#endif
88
89 "ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
90 : : "r" (addr) : "r0" /* only! */
91 );
92}
93
94#if defined(CPU_TCC780X) || defined(CPU_TCC77X) /* Single core only for now */ \
95|| CONFIG_CPU == IMX31L || CONFIG_CPU == DM320 || CONFIG_CPU == AS3525 \
96|| CONFIG_CPU == S3C2440 || CONFIG_CPU == S5L8701 || CONFIG_CPU == AS3525v2 \
97|| CONFIG_CPU == S5L8702
98/* Use the generic ARMv4/v5/v6 wait for IRQ */
99static inline void core_sleep(void)
100{
101 asm volatile (
102 "mcr p15, 0, %0, c7, c0, 4 \n" /* Wait for interrupt */
103#if CONFIG_CPU == IMX31L
104 "nop\n nop\n nop\n nop\n nop\n" /* Clean out the pipes */
105#endif
106 : : "r"(0)
107 );
108 enable_irq();
109}
110#else
111/* Skip this if special code is required and implemented */
112#if !(defined(CPU_PP)) && CONFIG_CPU != RK27XX && CONFIG_CPU != IMX233
113static inline void core_sleep(void)
114{
115 /* TODO: core_sleep not implemented, battery life will be decreased */
116 enable_irq();
117}
118#endif /* CPU_PP */
119#endif
120
121
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);
223static inline void commit_discard_dcache(void) {} 223static inline void commit_discard_dcache(void) {}
224static inline void commit_dcache(void) {} 224static inline void commit_dcache(void) {}
225 225
226/*---------------------------------------------------------------------------
227 * Put core in a power-saving state if waking list wasn't repopulated.
228 *---------------------------------------------------------------------------
229 */
230static inline void core_sleep(void)
231{
232 /* Supervisor mode, interrupts enabled upon wakeup */
233 asm volatile ("stop #0x2000");
234};
235
226#endif /* SYSTEM_TARGET_H */ 236#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 @@
23#define __SYSTEM_TARGET_H__ 23#define __SYSTEM_TARGET_H__
24 24
25#include "kernel-unix.h" 25#include "kernel-unix.h"
26 26#include "system-hosted.h"
27static inline void commit_dcache(void) {}
28static inline void commit_discard_dcache(void) {}
29static inline void commit_discard_idcache(void) {}
30 27
31 /* don't pull in jni.h for every user of this file, it should be only needed 28 /* don't pull in jni.h for every user of this file, it should be only needed
32 * within the target tree (if at all) 29 * 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);
41#define restore_irq(level) \ 41#define restore_irq(level) \
42 ((void)set_irq_level(level)) 42 ((void)set_irq_level(level))
43 43
44#include "system-hosted.h"
45
44void sim_enter_irq_handler(void); 46void sim_enter_irq_handler(void);
45void sim_exit_irq_handler(void); 47void sim_exit_irq_handler(void);
46void sim_kernel_shutdown(void); 48void sim_kernel_shutdown(void);
@@ -48,17 +50,10 @@ void sys_poweroff(void);
48void sys_handle_argv(int argc, char *argv[]); 50void sys_handle_argv(int argc, char *argv[]);
49void gui_message_loop(void); 51void gui_message_loop(void);
50void sim_do_exit(void) NORETURN_ATTR; 52void sim_do_exit(void) NORETURN_ATTR;
51#ifndef HAVE_SDL_THREADS
52void wait_for_interrupt(void);
53#endif
54 53
55extern bool background; /* True if the background image is enabled */ 54extern bool background; /* True if the background image is enabled */
56extern bool showremote; 55extern bool showremote;
57extern int display_zoom; 56extern int display_zoom;
58extern long start_tick; 57extern long start_tick;
59 58
60static inline void commit_dcache(void) {}
61static inline void commit_discard_dcache(void) {}
62static inline void commit_discard_idcache(void) {}
63
64#endif /* _SYSTEM_SDL_H_ */ 59#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 by Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __SYSTEM_HOSTED_H__
23#define __SYSTEM_HOSTED_H__
24
25#include "system.h"
26
27static inline void commit_dcache(void) {}
28static inline void commit_discard_dcache(void) {}
29static inline void commit_discard_idcache(void) {}
30
31static inline void core_sleep(void)
32{
33 enable_irq();
34 wait_for_interrupt();
35}
36
37#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 @@
22#define __SYSTEM_TARGET_H__ 22#define __SYSTEM_TARGET_H__
23 23
24#include "kernel-unix.h" 24#include "kernel-unix.h"
25 25#include "system-hosted.h"
26static inline void commit_dcache(void) {}
27static inline void commit_discard_dcache(void) {}
28static inline void commit_discard_idcache(void) {}
29 26
30#define NEED_GENERIC_BYTESWAPS 27#define NEED_GENERIC_BYTESWAPS
31#endif /* __SYSTEM_TARGET_H__ */ 28#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);
97#define DMA_IRQ(n) (IRQ_DMA_0 + (n)) 97#define DMA_IRQ(n) (IRQ_DMA_0 + (n))
98#define GPIO_IRQ(n) (IRQ_GPIO_0 + (n)) 98#define GPIO_IRQ(n) (IRQ_GPIO_0 + (n))
99 99
100/*---------------------------------------------------------------------------
101 * Put core in a power-saving state.
102 *---------------------------------------------------------------------------
103 */
104static inline void core_sleep(void)
105{
106#if CONFIG_CPU == JZ4732
107 __cpm_idle_mode();
108#endif
109 asm volatile(".set mips32r2 \n"
110 "mfc0 $8, $12 \n" /* mfc t0, $12 */
111 "move $9, $8 \n" /* move t1, t0 */
112 "la $10, 0x8000000 \n" /* la t2, 0x8000000 */
113 "or $8, $8, $10 \n" /* Enable reduced power mode */
114 "mtc0 $8, $12 \n" /* mtc t0, $12 */
115 "wait \n"
116 "mtc0 $9, $12 \n" /* mtc t1, $12 */
117 ".set mips0 \n"
118 ::: "t0", "t1", "t2"
119 );
120 enable_irq();
121}
122
123
100#endif /* __SYSTEM_TARGET_H_ */ 124#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) {}
137static inline void commit_discard_dcache(void) {} 137static inline void commit_discard_dcache(void) {}
138static inline void commit_discard_idcache(void) {} 138static inline void commit_discard_idcache(void) {}
139 139
140/*---------------------------------------------------------------------------
141 * Put core in a power-saving state.
142 *---------------------------------------------------------------------------
143 */
144static inline void core_sleep(void)
145{
146 asm volatile (
147 "and.b #0x7f, @(r0, gbr) \n" /* Clear SBY (bit 7) in SBYCR */
148 "mov #0, r1 \n" /* Enable interrupts */
149 "ldc r1, sr \n" /* Following instruction cannot be interrupted */
150 "sleep \n" /* Execute standby */
151 : : "z"(&SBYCR-GBR) : "r1");
152}
153
140#endif /* SYSTEM_TARGET_H */ 154#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)
178 * Processor/OS-specific section - include necessary core support 178 * Processor/OS-specific section - include necessary core support
179 */ 179 */
180 180
181#if defined(HAVE_WIN32_FIBER_THREADS) 181
182#include "thread-win32.c" 182#include "asm/thread.c"
183#elif defined(HAVE_SIGALTSTACK_THREADS) 183
184#include "thread-unix.c"
185#elif defined(CPU_ARM)
186#include "thread-arm.c"
187#if defined (CPU_PP) 184#if defined (CPU_PP)
188#include "thread-pp.c" 185#include "thread-pp.c"
189#endif /* CPU_PP */ 186#endif /* CPU_PP */
190#elif defined(CPU_COLDFIRE)
191#include "thread-coldfire.c"
192#elif CONFIG_CPU == SH7034
193#include "thread-sh.c"
194#elif defined(CPU_MIPS) && CPU_MIPS == 32
195#include "thread-mips32.c"
196#else
197/* Wouldn't compile anyway */
198#error Processor not implemented.
199#endif /* CONFIG_CPU == */
200 187
201#ifndef IF_NO_SKIP_YIELD 188#ifndef IF_NO_SKIP_YIELD
202#define IF_NO_SKIP_YIELD(...) 189#define IF_NO_SKIP_YIELD(...)