diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -124,7 +124,7 @@ static volatile int aps_started; /* Set to 1 once we're ready to let the APs out of the pen. */ -static volatile int aps_ready; +static volatile int aps_after_dev, aps_ready; /* Temporary variables for init_secondary() */ static void *dpcpu[MAXCPU - 1]; @@ -160,6 +160,26 @@ return (false); } +static void +release_aps_after_dev(void *dummy __unused) +{ + /* Only release CPUs if they exist */ + if (mp_ncpus == 1) + return; + + atomic_store_int(&aps_started, 0); + atomic_store_rel_int(&aps_after_dev, 1); + /* Wake up the other CPUs */ + __asm __volatile( + "dsb ishst \n" + "sev \n" + ::: "memory"); + + wait_for_aps(); +} +SYSINIT(aps_after_dev, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE + 1, + release_aps_after_dev, NULL); + static void release_aps(void *dummy __unused) { @@ -237,8 +257,20 @@ /* Detect early CPU feature support */ enable_cpu_feat(CPU_FEAT_EARLY_BOOT); - /* Signal the BSP and spin until it has released all APs. */ + /* Signal we are waiting for aps_after_dev */ atomic_add_int(&aps_started, 1); + + /* Wait for devices to be ready */ + while (!atomic_load_int(&aps_after_dev)) + __asm __volatile("wfe"); + + install_cpu_errata(); + enable_cpu_feat(CPU_FEAT_AFTER_DEV); + + /* Signal we are done */ + atomic_add_int(&aps_started, 1); + + /* Wait until we can run the scheduler */ while (!atomic_load_int(&aps_ready)) __asm __volatile("wfe"); @@ -253,9 +285,6 @@ ("pmap0 doesn't match cpu %ld's ttbr0", cpu)); pcpup->pc_curpmap = pmap0; - install_cpu_errata(); - enable_cpu_feat(CPU_FEAT_AFTER_DEV); - intr_pic_init_secondary(); /* Start per-CPU event timers. */