forked from len0rd/rockbox
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
This commit is contained in:
parent
eaa83bd647
commit
991ae1e395
24 changed files with 352 additions and 295 deletions
|
|
@ -8,7 +8,6 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 by Thom Johansen
|
* Copyright (C) 2005 by Thom Johansen
|
||||||
* Copyright (C) 2010 by Thomas Martitz (Android-suitable core_sleep())
|
|
||||||
*
|
*
|
||||||
* Generic ARM threading support
|
* Generic ARM threading support
|
||||||
*
|
*
|
||||||
|
|
@ -22,8 +21,6 @@
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <system.h>
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Start the thread running and terminate it if it returns
|
* 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 */
|
"ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */
|
||||||
"mov r1, #0 \n" /* Mark thread as running */
|
"mov r1, #0 \n" /* Mark thread as running */
|
||||||
"str r1, [r0, #40] \n"
|
"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 */
|
"mov lr, pc \n" /* Call thread function */
|
||||||
"bx r4 \n"
|
"bx r4 \n"
|
||||||
); /* No clobber list - new thread doesn't care */
|
); /* No clobber list - new thread doesn't care */
|
||||||
thread_exit();
|
thread_exit();
|
||||||
|
#if 0
|
||||||
|
asm volatile (".ltorg"); /* Dump constant pool */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For startup, place context pointer in r4 slot, start_thread pointer in r5
|
/* 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 */
|
"cmp r0, #0 \n" /* Check for NULL */
|
||||||
|
|
||||||
/* If not already running, jump to start */
|
/* 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"
|
"ldmneia %0, { r0, pc } \n"
|
||||||
|
#endif
|
||||||
|
|
||||||
"ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
|
"ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
|
||||||
: : "r" (addr) : "r0" /* only! */
|
: : "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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
36
firmware/asm/arm/thread.h
Normal file
36
firmware/asm/arm/thread.h
Normal file
|
|
@ -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
|
||||||
|
|
@ -86,16 +86,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
|
* Call this from asm to make sure the sp is pointing to the
|
||||||
* correct place before the context is saved.
|
* correct place before the context is saved.
|
||||||
31
firmware/asm/m68k/thread.h
Normal file
31
firmware/asm/m68k/thread.h
Normal file
|
|
@ -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 */
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
6
firmware/asm/mips/thread.c
Normal file
6
firmware/asm/mips/thread.c
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#if CPU_MIPS == 32
|
||||||
|
#include "thread-mips32.c"
|
||||||
|
#else
|
||||||
|
#error Missing thread impl
|
||||||
|
#endif
|
||||||
|
|
||||||
31
firmware/asm/mips/thread.h
Normal file
31
firmware/asm/mips/thread.h
Normal file
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
30
firmware/asm/sh/thread.h
Normal file
30
firmware/asm/sh/thread.h
Normal file
|
|
@ -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 */
|
||||||
|
|
@ -305,12 +305,3 @@ static inline void load_context(const void* addr)
|
||||||
}
|
}
|
||||||
swap_context(target_context, r->uc);
|
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();
|
|
||||||
}
|
|
||||||
|
|
@ -74,12 +74,3 @@ static inline void load_context(const void* addr)
|
||||||
}
|
}
|
||||||
SwitchToFiber(context->uc);
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
21
firmware/asm/thread.c
Normal file
21
firmware/asm/thread.c
Normal file
|
|
@ -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
|
||||||
57
firmware/asm/thread.h
Normal file
57
firmware/asm/thread.h
Normal file
|
|
@ -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
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
* KIND, either express or implied.
|
* KIND, either express or implied.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef THREAD_H
|
#ifndef THREAD_H
|
||||||
#define THREAD_H
|
#define THREAD_H
|
||||||
|
|
||||||
|
|
@ -93,66 +94,8 @@
|
||||||
* maybe more expensive C lib functions?
|
* maybe more expensive C lib functions?
|
||||||
*
|
*
|
||||||
* simulator (possibly) doesn't simulate stack usage anyway but well ... */
|
* 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
|
|
||||||
|
|
||||||
|
#ifdef HAVE_SDL_THREADS
|
||||||
#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 */
|
|
||||||
struct regs
|
struct regs
|
||||||
{
|
{
|
||||||
void *t; /* OS thread */
|
void *t; /* OS thread */
|
||||||
|
|
@ -160,8 +103,11 @@ struct regs
|
||||||
void *s; /* Semaphore for blocking and wakeup */
|
void *s; /* Semaphore for blocking and wakeup */
|
||||||
void (*start)(void); /* Start function */
|
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 CPU_PP
|
||||||
#ifdef HAVE_CORELOCK_OBJECT
|
#ifdef HAVE_CORELOCK_OBJECT
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
#endif /* SYSTEM_ARM_H */
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -223,4 +223,14 @@ void commit_discard_idcache(void);
|
||||||
static inline void commit_discard_dcache(void) {}
|
static inline void commit_discard_dcache(void) {}
|
||||||
static inline void commit_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 */
|
#endif /* SYSTEM_TARGET_H */
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,7 @@
|
||||||
#define __SYSTEM_TARGET_H__
|
#define __SYSTEM_TARGET_H__
|
||||||
|
|
||||||
#include "kernel-unix.h"
|
#include "kernel-unix.h"
|
||||||
|
#include "system-hosted.h"
|
||||||
static inline void commit_dcache(void) {}
|
|
||||||
static inline void commit_discard_dcache(void) {}
|
|
||||||
static inline void commit_discard_idcache(void) {}
|
|
||||||
|
|
||||||
/* don't pull in jni.h for every user of this file, it should be only needed
|
/* don't pull in jni.h for every user of this file, it should be only needed
|
||||||
* within the target tree (if at all)
|
* within the target tree (if at all)
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ int set_irq_level(int level);
|
||||||
#define restore_irq(level) \
|
#define restore_irq(level) \
|
||||||
((void)set_irq_level(level))
|
((void)set_irq_level(level))
|
||||||
|
|
||||||
|
#include "system-hosted.h"
|
||||||
|
|
||||||
void sim_enter_irq_handler(void);
|
void sim_enter_irq_handler(void);
|
||||||
void sim_exit_irq_handler(void);
|
void sim_exit_irq_handler(void);
|
||||||
void sim_kernel_shutdown(void);
|
void sim_kernel_shutdown(void);
|
||||||
|
|
@ -48,17 +50,10 @@ void sys_poweroff(void);
|
||||||
void sys_handle_argv(int argc, char *argv[]);
|
void sys_handle_argv(int argc, char *argv[]);
|
||||||
void gui_message_loop(void);
|
void gui_message_loop(void);
|
||||||
void sim_do_exit(void) NORETURN_ATTR;
|
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 background; /* True if the background image is enabled */
|
||||||
extern bool showremote;
|
extern bool showremote;
|
||||||
extern int display_zoom;
|
extern int display_zoom;
|
||||||
extern long start_tick;
|
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_ */
|
#endif /* _SYSTEM_SDL_H_ */
|
||||||
|
|
|
||||||
37
firmware/target/hosted/system-hosted.h
Normal file
37
firmware/target/hosted/system-hosted.h
Normal file
|
|
@ -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
|
||||||
|
|
@ -22,10 +22,7 @@
|
||||||
#define __SYSTEM_TARGET_H__
|
#define __SYSTEM_TARGET_H__
|
||||||
|
|
||||||
#include "kernel-unix.h"
|
#include "kernel-unix.h"
|
||||||
|
#include "system-hosted.h"
|
||||||
static inline void commit_dcache(void) {}
|
|
||||||
static inline void commit_discard_dcache(void) {}
|
|
||||||
static inline void commit_discard_idcache(void) {}
|
|
||||||
|
|
||||||
#define NEED_GENERIC_BYTESWAPS
|
#define NEED_GENERIC_BYTESWAPS
|
||||||
#endif /* __SYSTEM_TARGET_H__ */
|
#endif /* __SYSTEM_TARGET_H__ */
|
||||||
|
|
|
||||||
|
|
@ -97,4 +97,28 @@ void dma_disable(void);
|
||||||
#define DMA_IRQ(n) (IRQ_DMA_0 + (n))
|
#define DMA_IRQ(n) (IRQ_DMA_0 + (n))
|
||||||
#define GPIO_IRQ(n) (IRQ_GPIO_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_ */
|
#endif /* __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_dcache(void) {}
|
||||||
static inline void commit_discard_idcache(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 */
|
#endif /* SYSTEM_TARGET_H */
|
||||||
|
|
|
||||||
|
|
@ -178,25 +178,12 @@ void switch_thread(void)
|
||||||
* Processor/OS-specific section - include necessary core support
|
* Processor/OS-specific section - include necessary core support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_WIN32_FIBER_THREADS)
|
|
||||||
#include "thread-win32.c"
|
#include "asm/thread.c"
|
||||||
#elif defined(HAVE_SIGALTSTACK_THREADS)
|
|
||||||
#include "thread-unix.c"
|
|
||||||
#elif defined(CPU_ARM)
|
|
||||||
#include "thread-arm.c"
|
|
||||||
#if defined (CPU_PP)
|
#if defined (CPU_PP)
|
||||||
#include "thread-pp.c"
|
#include "thread-pp.c"
|
||||||
#endif /* CPU_PP */
|
#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
|
#ifndef IF_NO_SKIP_YIELD
|
||||||
#define IF_NO_SKIP_YIELD(...)
|
#define IF_NO_SKIP_YIELD(...)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue