? difz ? odifz Index: aarch64/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/cpu.c,v retrieving revision 1.16 diff -p -u -u -r1.16 cpu.c --- aarch64/cpu.c 21 Jan 2019 08:04:26 -0000 1.16 +++ aarch64/cpu.c 1 May 2019 19:10:47 -0000 @@ -42,6 +42,7 @@ __KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.16 #include #include #include +#include #include #include @@ -108,6 +109,7 @@ cpu_attach(device_t dv, cpuid_t id) ci = curcpu(); ci->ci_cpuid = id; cpu_setup_id(ci); + mutex_init(&cpu_hatch_lock, MUTEX_DEFAULT, IPL_NONE); } else { #ifdef MULTIPROCESSOR if ((boothowto & RB_MD1) != 0) { @@ -159,6 +161,24 @@ cpu_attach(device_t dv, cpuid_t id) #ifdef MULTIPROCESSOR if (unit != 0) { mi_cpu_attach(ci); + /* + * Tell this CPU to finish attaching locally, and wait for + * it to complete this part. The protocol is to turn off + * the hatched bit, turn on the mbox bit, and wait for the + * hatched bit to come back. Then when secondary boot runs + * to finally enable CPUs, they rely upon mp_online becoming + * true to notice. + */ + atomic_and_32(&arm_cpu_hatched, ~__BIT(unit)); + atomic_or_32(&arm_cpu_mbox, __BIT(unit)); + __asm __volatile ("sev; sev; sev"); + for (uint64_t count = 0; count < 512 * 1024 * 1024; count++) { + if ((arm_cpu_hatched & __BIT(unit)) != 0) + break; + __asm __volatile ("wfe"); + } + if ((arm_cpu_hatched & __BIT(unit)) == 0) + panic("cpu%d did not hatch second time", unit); return; } #endif /* MULTIPROCESSOR */ @@ -295,10 +315,8 @@ cpu_identify2(device_t self, struct cpu_ struct aarch64_sysctl_cpu_id *id = &ci->ci_id; uint64_t dfr0; - if (!CPU_IS_PRIMARY(ci)) { + if (!CPU_IS_PRIMARY(ci)) cpu_setup_id(ci); - cpu_setup_sysctl(self, ci); - } dfr0 = reg_id_aa64dfr0_el1_read(); @@ -493,34 +511,21 @@ cpu_setup_sysctl(device_t dv, struct cpu void cpu_boot_secondary_processors(void) { - if ((boothowto & RB_MD1) != 0) - return; - - mutex_init(&cpu_hatch_lock, MUTEX_DEFAULT, IPL_NONE); - - VPRINTF("%s: writing mbox with %#x\n", __func__, arm_cpu_hatched); - /* send mbox to have secondary processors do cpu_hatch() */ - atomic_or_32(&arm_cpu_mbox, arm_cpu_hatched); + /* poke other CPUs to notice mp_online is now true. */ __asm __volatile ("sev; sev; sev"); - - /* wait all cpus have done cpu_hatch() */ - while (membar_consumer(), arm_cpu_mbox & arm_cpu_hatched) { - __asm __volatile ("wfe"); - } - - VPRINTF("%s: secondary processors hatched\n", __func__); - - /* add available processors to kcpuset */ - uint32_t mbox = arm_cpu_hatched; - kcpuset_export_u32(kcpuset_attached, &mbox, sizeof(mbox)); } void cpu_hatch(struct cpu_info *ci) { + int unit; + KASSERT(curcpu() == ci); + /* ci_index may be -1 if hatching fails, use device_unit(). */ + unit = device_unit(ci->ci_dev); + mutex_enter(&cpu_hatch_lock); set_cpufuncs(); @@ -531,8 +536,6 @@ cpu_hatch(struct cpu_info *ci) aarch64_printcacheinfo(ci->ci_dev); cpu_identify2(ci->ci_dev, ci); - mutex_exit(&cpu_hatch_lock); - intr_cpu_init(ci); #ifdef FDT @@ -542,13 +545,30 @@ cpu_hatch(struct cpu_info *ci) MD_CPU_HATCH(ci); /* for non-fdt arch? */ #endif + mutex_exit(&cpu_hatch_lock); + /* - * clear my bit of arm_cpu_mbox to tell cpu_boot_secondary_processors(). - * there are cpu0,1,2,3, and if cpu2 is unresponsive, - * ci_index are each cpu0=0, cpu1=1, cpu2=undef, cpu3=2. - * therefore we have to use device_unit instead of ci_index for mbox. + * Set this CPUs bit in the hatced list so that cpu_attach() on + * cpu0 knows to continue. + * + * Then wait here for mp_online to become true before going into + * the idle loop. */ - atomic_and_32(&arm_cpu_mbox, ~__BIT(device_unit(ci->ci_dev))); + atomic_or_32(&arm_cpu_hatched, __BIT(unit)); __asm __volatile ("sev; sev; sev"); + + while (!mp_online) + __asm __volatile ("wfe"); + + /* Setup this CPUs sysctl */ + /* XXX moved here from cpu_identify2() due to pool crashes */ + if (!CPU_IS_PRIMARY(ci)) + cpu_setup_sysctl(ci->ci_dev, ci); + + /* add self available kcpuset */ + kcpuset_set(kcpuset_attached, unit); + printf("cpu%d: online\n", unit); + + idle_loop(NULL); } #endif /* MULTIPROCESSOR */ Index: aarch64/locore.S =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/locore.S,v retrieving revision 1.33 diff -p -u -u -r1.33 locore.S --- aarch64/locore.S 27 Jan 2019 02:08:36 -0000 1.33 +++ aarch64/locore.S 1 May 2019 19:10:47 -0000 @@ -450,16 +450,17 @@ mp_vstart: CPU_DPRINTREG("arm_cpu_hatched |= ", x28) - /* - * atomic_or_32(&arm_cpu_hatched, (1 << cpuindex)) - * to tell my activity to primary processor. - */ + /* Tell cpu0 running the main autoconfig that this CPU has come up. */ ADDR x0, _C_LABEL(arm_cpu_hatched) mov x1, x28 bl _C_LABEL(atomic_or_32) /* hatched! */ sev - /* wait for my bit of arm_cpu_mbox become true */ + /* + * Wait for my bit of arm_cpu_mbox become true. That means it is time + * for this CPU to run cpu_hatch() which never returns. Depends upon + * mi_cpu_attach(this_cpuinfo) being called first. + */ ADDR x0, _C_LABEL(arm_cpu_mbox) 1: dmb sy @@ -484,9 +485,7 @@ mp_vstart: mov fp, xzr /* trace back starts here */ - bl _C_LABEL(cpu_hatch) - mov x0, xzr - b _C_LABEL(idle_loop) /* never to return */ + b _C_LABEL(cpu_hatch) /* never to return */ END(cpu_mpstart) toomanycpus: