diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2008-04-06 22:08:36 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2008-04-06 22:08:36 +0000 |
commit | 9ba80c9641e19b421d5c7544d081a2d458c509b1 (patch) | |
tree | c6a93fd7afc3c6264db1becd699ab57197256e44 | |
parent | c2a01fdc7a4f80e0d8e6305944ac1efca3040df0 (diff) |
Get device-specific code out of init_threads and add core_thread_init to be implemented for multicore devices.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17000 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/thread.c | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/firmware/thread.c b/firmware/thread.c index 0f5378de7b..0049df3e90 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -733,6 +733,31 @@ static void __attribute__((naked)) ); (void)core; (void)thread; } + +/*--------------------------------------------------------------------------- + * Do any device-specific inits for the threads and synchronize the kernel + * initializations. + *--------------------------------------------------------------------------- + */ +static void core_thread_init(unsigned int core) +{ + if (core == CPU) + { + /* Wake up coprocessor and let it initialize kernel and threads */ +#ifdef CPU_PP502x + MBX_MSG_CLR = 0x3f; +#endif + COP_CTL = PROC_WAKE; + /* Sleep until COP has finished */ + CPU_CTL = PROC_SLEEP; + nop; nop; nop; + } + else + { + /* Wake the CPU and return */ + CPU_CTL = PROC_WAKE; + } +} #endif /* NUM_CORES */ #elif CONFIG_CPU == S3C2440 @@ -2955,24 +2980,22 @@ void init_threads(void) thread->stack = stackbegin; thread->stack_size = (uintptr_t)stackend - (uintptr_t)stackbegin; #if NUM_CORES > 1 /* This code path will not be run on single core targets */ - /* TODO: HAL interface for this */ - /* Wake up coprocessor and let it initialize kernel and threads */ -#ifdef CPU_PP502x - MBX_MSG_CLR = 0x3f; -#endif - COP_CTL = PROC_WAKE; - /* Sleep until finished */ - CPU_CTL = PROC_SLEEP; - nop; nop; nop; nop; + /* Wait for other processors to finish their inits since create_thread + * isn't safe to call until the kernel inits are done. The first + * threads created in the system must of course be created by CPU. */ + core_thread_init(CPU); } else { - /* Initial stack is the COP idle stack */ - thread->stack = cop_idlestackbegin; + /* Initial stack is the idle stack */ + thread->stack = idle_stacks[core]; thread->stack_size = IDLE_STACK_SIZE; - /* Get COP safely primed inside switch_thread where it will remain - * until a thread actually exists on it */ - CPU_CTL = PROC_WAKE; + /* After last processor completes, it should signal all others to + * proceed or may signal the next and call thread_exit(). The last one + * to finish will signal CPU. */ + core_thread_init(core); + /* Other cores do not have a main thread - go idle inside switch_thread + * until a thread can run on the core. */ thread_exit(); #endif /* NUM_CORES */ } |