From f0fad1590bcb8b04a1e0f872838f92aa0f832241 Mon Sep 17 00:00:00 2001 From: Travis Geiselbrecht Date: Fri, 27 Mar 2015 14:08:32 -0700 Subject: [PATCH] [init][smp] have secondary init run in arch code up to threading, and complete in secondary thread -move the per-cpu initialization of the gic and cortex-a9 timer into an init hook. This removes the hard coded call in arm/arch.c -make sure the timer initialization happens in the pre-threading callback, in case a secondary init hook needs the timer. --- arch/arm/arm/arch.c | 9 +++------ dev/interrupt/arm_gic/arm_gic.c | 10 +++++++--- .../arm_gic/include/dev/interrupt/arm_gic.h | 1 - dev/timer/arm_cortex_a9/arm_cortex_a9_timer.c | 12 ++++++++++-- .../arm_cortex_a9/include/dev/timer/arm_cortex_a9.h | 1 - dev/timer/arm_generic/arm_generic_timer.c | 3 ++- top/main.c | 3 ++- 7 files changed, 24 insertions(+), 15 deletions(-) diff --git a/arch/arm/arm/arch.c b/arch/arm/arm/arch.c index a2c79b26..9d29293a 100644 --- a/arch/arm/arm/arch.c +++ b/arch/arm/arm/arch.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -163,12 +164,8 @@ void arm_secondary_entry(void) sctlr |= (1<<12) | (1<<2); // enable i and dcache arm_write_sctlr(sctlr); -#if WITH_DEV_TIMER_ARM_CORTEX_A9 - arm_cortex_a9_timer_init_percpu(); -#endif -#if WITH_DEV_INTERRUPT_ARM_GIC - arm_gic_init_percpu(); -#endif + /* run early secondary cpu init routines up to the threading level */ + lk_init_level(LK_INIT_FLAG_SECONDARY_CPUS, LK_INIT_LEVEL_EARLIEST, LK_INIT_LEVEL_THREADING - 1); arch_mp_init_percpu(); diff --git a/dev/interrupt/arm_gic/arm_gic.c b/dev/interrupt/arm_gic/arm_gic.c index eda8e708..c8a47548 100644 --- a/dev/interrupt/arm_gic/arm_gic.c +++ b/dev/interrupt/arm_gic/arm_gic.c @@ -174,7 +174,7 @@ static void gic_set_enable(uint vector, bool enable) GICREG(0, GICD_ICENABLER(reg)) = mask; } -void arm_gic_init_percpu(void) +static void arm_gic_init_percpu(uint level) { #if WITH_LIB_SM GICREG(0, GICC_CTLR) = 0xb; // enable GIC0 and select fiq mode for secure @@ -185,6 +185,10 @@ void arm_gic_init_percpu(void) GICREG(0, GICC_PMR) = 0xFF; // unmask interrupts at all priority levels } +LK_INIT_HOOK_FLAGS(arm_gic_init_percpu, + arm_gic_init_percpu, + LK_INIT_LEVEL_PLATFORM_EARLY, LK_INIT_FLAG_SECONDARY_CPUS); + static void arm_gic_suspend_cpu(uint level) { suspend_resume_fiq(false, false); @@ -204,7 +208,7 @@ static void arm_gic_resume_cpu(uint level) arm_gic_init(); resume_gicd = true; } else { - arm_gic_init_percpu(); + arm_gic_init_percpu(0); } spin_unlock_restore(&gicd_lock, state, GICD_LOCK_FLAGS); suspend_resume_fiq(true, resume_gicd); @@ -246,7 +250,7 @@ void arm_gic_init(void) GICREG(0, GICD_IGROUPR(reg)) = gicd_igroupr[reg]; } #endif - arm_gic_init_percpu(); + arm_gic_init_percpu(0); } static status_t arm_gic_set_secure_locked(u_int irq, bool secure) diff --git a/dev/interrupt/arm_gic/include/dev/interrupt/arm_gic.h b/dev/interrupt/arm_gic/include/dev/interrupt/arm_gic.h index a4f21c88..ee0fe614 100644 --- a/dev/interrupt/arm_gic/include/dev/interrupt/arm_gic.h +++ b/dev/interrupt/arm_gic/include/dev/interrupt/arm_gic.h @@ -26,7 +26,6 @@ #include void arm_gic_init(void); -void arm_gic_init_percpu(void); enum { /* Ignore cpu_mask and forward interrupt to all CPUs other than the current cpu */ diff --git a/dev/timer/arm_cortex_a9/arm_cortex_a9_timer.c b/dev/timer/arm_cortex_a9/arm_cortex_a9_timer.c index 8d85e8c9..ce7077b9 100644 --- a/dev/timer/arm_cortex_a9/arm_cortex_a9_timer.c +++ b/dev/timer/arm_cortex_a9/arm_cortex_a9_timer.c @@ -34,6 +34,7 @@ #include #include #include +#include /* driver for cortex-a9's private timer */ #define LOCAL_TRACE 0 @@ -79,6 +80,8 @@ static struct fp_32_64 timer_freq_msec_conversion; static struct fp_32_64 timer_freq_usec_conversion_inverse; static struct fp_32_64 timer_freq_msec_conversion_inverse; +static void arm_cortex_a9_timer_init_percpu(uint level); + uint64_t get_global_val(void) { uint32_t lo, hi; @@ -189,7 +192,7 @@ void arm_cortex_a9_timer_init(addr_t _scu_control_base, uint32_t freq) { scu_control_base = _scu_control_base; - arm_cortex_a9_timer_init_percpu(); + arm_cortex_a9_timer_init_percpu(0); /* save the timer frequency for later calculations */ timer_freq = freq; @@ -200,7 +203,7 @@ void arm_cortex_a9_timer_init(addr_t _scu_control_base, uint32_t freq) fp_32_64_div_32_32(&timer_freq_msec_conversion_inverse, 1000, timer_freq); } -void arm_cortex_a9_timer_init_percpu(void) +static void arm_cortex_a9_timer_init_percpu(uint level) { /* disable timer */ TIMREG(TIMER_CONTROL) = 0; @@ -216,4 +219,9 @@ void arm_cortex_a9_timer_init_percpu(void) unmask_interrupt(CPU_PRIV_TIMER_INT); } +/* secondary cpu initialize the timer just before the kernel starts with interrupts enabled */ +LK_INIT_HOOK_FLAGS(arm_cortex_a9_timer_init_percpu, + arm_cortex_a9_timer_init_percpu, + LK_INIT_LEVEL_THREADING - 1, LK_INIT_FLAG_SECONDARY_CPUS); + /* vim: set ts=4 sw=4 expandtab: */ diff --git a/dev/timer/arm_cortex_a9/include/dev/timer/arm_cortex_a9.h b/dev/timer/arm_cortex_a9/include/dev/timer/arm_cortex_a9.h index 4ce13380..053e8116 100644 --- a/dev/timer/arm_cortex_a9/include/dev/timer/arm_cortex_a9.h +++ b/dev/timer/arm_cortex_a9/include/dev/timer/arm_cortex_a9.h @@ -25,4 +25,3 @@ #include void arm_cortex_a9_timer_init(addr_t scu_control_base, uint32_t freq); -void arm_cortex_a9_timer_init_percpu(void); diff --git a/dev/timer/arm_generic/arm_generic_timer.c b/dev/timer/arm_generic/arm_generic_timer.c index 5d10ceb9..6193be3b 100644 --- a/dev/timer/arm_generic/arm_generic_timer.c +++ b/dev/timer/arm_generic/arm_generic_timer.c @@ -362,9 +362,10 @@ static void arm_generic_timer_init_secondary_cpu(uint level) unmask_interrupt(timer_irq); } +/* secondary cpu initialize the timer just before the kernel starts with interrupts enabled */ LK_INIT_HOOK_FLAGS(arm_generic_timer_init_secondary_cpu, arm_generic_timer_init_secondary_cpu, - LK_INIT_LEVEL_PLATFORM, LK_INIT_FLAG_SECONDARY_CPUS); + LK_INIT_LEVEL_THREADING - 1, LK_INIT_FLAG_SECONDARY_CPUS); static void arm_generic_timer_resume_cpu(uint level) { diff --git a/top/main.c b/top/main.c index adcc002e..7484b790 100644 --- a/top/main.c +++ b/top/main.c @@ -170,7 +170,8 @@ void lk_secondary_cpu_entry(void) static int secondary_cpu_bootstrap2(void *arg) { - lk_init_level_all(LK_INIT_FLAG_SECONDARY_CPUS); + /* secondary cpu initialize from threading level up. 0 to threading was handled in arch */ + lk_init_level(LK_INIT_FLAG_SECONDARY_CPUS, LK_INIT_LEVEL_THREADING, LK_INIT_LEVEL_LAST); return 0; }