kernel: add support for switching to main thread without _Swap()

It's possible that an architecture needs a custom way of switching to
the main() task, rather than using _Swap() with a dummy thread.

Change-Id: I14e9bc67be35174ff16209bcea27b18a069ff754
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
Benjamin Walsh 2016-11-20 11:04:31 -05:00 committed by Anas Nashif
commit 296a234ddb
2 changed files with 25 additions and 3 deletions

View file

@ -354,3 +354,12 @@ config HEAP_MEM_POOL_SIZE
heap memory pool is defined.
endmenu
config ARCH_HAS_CUSTOM_SWAP_TO_MAIN
bool
# hidden
default n
help
It's possible that an architecture port cannot use _Swap() to swap to
the _main() thread, but instead must do something custom. It must
enable this option in that case.

View file

@ -241,6 +241,9 @@ void __weak main(void)
*/
static void prepare_multithreading(struct k_thread *dummy_thread)
{
#ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
ARG_UNUSED(dummy_thread);
#else
/*
* Initialize the current execution thread to permit a level of
* debugging output if an exception should happen during nanokernel
@ -257,6 +260,7 @@ static void prepare_multithreading(struct k_thread *dummy_thread)
*/
dummy_thread->base.flags = K_ESSENTIAL;
dummy_thread->base.prio = K_PRIO_COOP(0);
#endif
/* _kernel.ready_q is all zeroes */
@ -298,6 +302,9 @@ static void prepare_multithreading(struct k_thread *dummy_thread)
static void switch_to_main_thread(void)
{
#ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
_arch_switch_to_main_thread(main_stack, MAIN_STACK_SIZE, _main);
#else
/*
* Context switch to main task (entry function is _main()): the
* current fake thread is not on a wait queue or ready queue, so it
@ -305,6 +312,7 @@ static void switch_to_main_thread(void)
*/
_Swap(irq_lock());
#endif
}
#ifdef CONFIG_STACK_CANARIES
@ -357,9 +365,14 @@ extern void *__stack_chk_guard;
*/
FUNC_NORETURN void _Cstart(void)
{
/* floating point operations are NOT performed during nanokernel init */
#ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
void *dummy_thread = NULL;
#else
/* floating point is NOT used during nanokernel init */
char __stack dummy_thread[_K_THREAD_NO_FLOAT_SIZEOF];
char __stack dummy_stack[_K_THREAD_NO_FLOAT_SIZEOF];
void *dummy_thread = dummy_stack;
#endif
/*
* Initialize nanokernel data structures. This step includes
@ -367,7 +380,7 @@ FUNC_NORETURN void _Cstart(void)
* before the hardware initialization phase.
*/
prepare_multithreading((struct k_thread *)&dummy_thread);
prepare_multithreading(dummy_thread);
/* Deprecated */
_sys_device_do_config_level(_SYS_INIT_LEVEL_PRIMARY);