diff --git a/arch b/arch index 211160ebe8..9336bbac1c 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit 211160ebe8733a5456a49b88ef4c27482690b5d6 +Subproject commit 9336bbac1c82d417d65d0a973359e4fad25e2dd1 diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 0a176653fd..04caec1319 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -1743,7 +1743,6 @@ int up_cpu_index(void); * cpu - The index of the CPU being started. This will be a numeric * value in the range of from one to (CONFIG_SMP_NCPUS-1). (CPU * 0 is already active) - * idletask - The entry point to the IDLE task. * * Returned Value: * Zero on success; a negated errno value on failure. @@ -1751,7 +1750,7 @@ int up_cpu_index(void); ****************************************************************************/ #ifdef CONFIG_SMP -int up_cpu_start(int cpu, main_t idletask); +int up_cpu_start(int cpu); #endif /**************************************************************************** diff --git a/sched/init/init.h b/sched/init/init.h index 1d95df1f6c..4724c83392 100644 --- a/sched/init/init.h +++ b/sched/init/init.h @@ -65,7 +65,7 @@ void os_start(void); /**************************************************************************** - * Name: os_smpstart + * Name: os_smp_start * * Description: * In an SMP configution, only one CPU is initially active (CPU 0). System @@ -82,11 +82,11 @@ void os_start(void); ****************************************************************************/ #ifdef CONFIG_SMP -int os_smpstart(void); +int os_smp_start(void); #endif /**************************************************************************** - * Name: os_idletask + * Name: os_idle_trampoline * * Description: * This is the common IDLE task for CPUs 1 through (CONFIG_SMP_NCPUS-1). @@ -101,7 +101,26 @@ int os_smpstart(void); ****************************************************************************/ #ifdef CONFIG_SMP -int os_idletask(int argc, FAR char *argv[]); +void os_idle_trampoline(void); +#endif + +/**************************************************************************** + * Name: os_idle_task + * + * Description: + * This is the common IDLE task for CPUs 1 through (CONFIG_SMP_NCPUS-1). + * It is equivalent to the CPU 0 IDLE logic in os_start.c + * + * Input Parameters: + * Standard task arguments. + * + * Returned Value: + * This function does not return. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int os_idle_task(int argc, FAR char *argv[]); #endif /**************************************************************************** diff --git a/sched/init/os_smpstart.c b/sched/init/os_smpstart.c index 215cdd45fc..3a0aa8d470 100644 --- a/sched/init/os_smpstart.c +++ b/sched/init/os_smpstart.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -74,11 +73,11 @@ static const char g_idlename[] = "CPUn Idle" #endif /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: os_idletask + * Name: os_idle_trampoline * * Description: * This is the common IDLE task for CPUs 1 through (CONFIG_SMP_NCPUS-1). @@ -92,7 +91,33 @@ static const char g_idlename[] = "CPUn Idle" * ****************************************************************************/ -int os_idletask(int argc, FAR char *argv[]) +void os_idle_trampoline(void) +{ + /* Transfer control to the IDLE task */ + + (void)os_idle_task(0, NULL); + + /* The IDLE task should never return */ + + PANIC(); +} + +/**************************************************************************** + * Name: os_idle_task + * + * Description: + * This is the common IDLE task for CPUs 1 through (CONFIG_SMP_NCPUS-1). + * It is equivalent to the CPU 0 IDLE logic in os_start.c + * + * Input Parameters: + * Standard task arguments. + * + * Returned Value: + * This function does not return. + * + ****************************************************************************/ + +int os_idle_task(int argc, FAR char *argv[]) { /* Enter the IDLE loop */ @@ -133,11 +158,7 @@ int os_idletask(int argc, FAR char *argv[]) } /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: os_smpstart + * Name: os_smp_start * * Description: * In an SMP configution, only one CPU is initially active (CPU 0). System @@ -157,18 +178,38 @@ int os_idletask(int argc, FAR char *argv[]) * ****************************************************************************/ -int os_smpstart(void) +int os_smp_start(void) { int ret; int cpu; - /* CPU0 is already running. Start the remaining CPUs */ + /* Create a stack for all CPU IDLE threads (except CPU0 which already has + * a stack). + */ for (cpu = 1; cpu < CONFIG_SMP_NCPUS; cpu++) { - /* And start the CPU. */ + FAR struct tcb_s *tcb = current_task(cpu); + DEBUGASSERT(tcb != NULL); - ret = up_cpu_start(cpu, os_idletask); + ret = up_create_stack(tcb, CONFIG_SMP_IDLETHREAD_STACKSIZE, + TCB_FLAG_TTYPE_KERNEL); + if (ret < 0) + { + sdbg("ERROR: Failed to allocate stack for CPU%d\n", cpu); + return ret; + } + } + + /* Then start all of the other CPUs after we have completed the memory + * allocations. CPU0 is already running. + */ + + for (cpu = 1; cpu < CONFIG_SMP_NCPUS; cpu++) + { + /* Start the CPU */ + + ret = up_cpu_start(cpu); if (ret < 0) { sdbg("ERROR: Failed to start CPU%d: %d\n", cpu, ret); diff --git a/sched/init/os_start.c b/sched/init/os_start.c index 8858a58341..1e0a90b916 100644 --- a/sched/init/os_start.c +++ b/sched/init/os_start.c @@ -453,11 +453,13 @@ void os_start(void) #ifdef CONFIG_SMP if (cpu > 0) { - g_idletcb[cpu].cmn.entry.main = os_idletask; + g_idletcb[cpu].cmn.start = os_idle_trampoline; + g_idletcb[cpu].cmn.entry.main = os_idle_task; } else #endif { + g_idletcb[cpu].cmn.start = (start_t)os_start; g_idletcb[cpu].cmn.entry.main = (main_t)os_start; } @@ -762,7 +764,7 @@ void os_start(void) /* Then start the other CPUs */ - DEBUGVERIFY(os_smpstart()); + DEBUGVERIFY(os_smp_start()); #endif /* CONFIG_SMP */