diff options
author | Thomas Martitz <kugel@rockbox.org> | 2012-01-04 18:07:21 +0100 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2012-01-22 18:46:44 +0100 |
commit | 991ae1e39553172a7dd6cd8c634aebfce892e261 (patch) | |
tree | 672a4583af663def399c4fefdbad060605397fbc | |
parent | eaa83bd64775b87e943d345e2810deed44408776 (diff) | |
download | rockbox-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
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(...) |