Module Name:    src
Committed By:   skrll
Date:           Sat Feb 15 08:16:12 UTC 2020

Modified Files:
        src/sys/arch/aarch64/aarch64: cpu.c locore.S
        src/sys/arch/aarch64/conf: files.aarch64
        src/sys/arch/aarch64/include: cpu.h machdep.h
        src/sys/arch/arm/acpi: cpu_acpi.c
        src/sys/arch/arm/altera: cycv_platform.c
        src/sys/arch/arm/arm: arm_cpu_topology.c arm_machdep.c armv6_start.S
        src/sys/arch/arm/arm32: arm32_boot.c arm32_machdep.c cpu.c genassym.cf
        src/sys/arch/arm/broadcom: bcm2835_intr.c
        src/sys/arch/arm/conf: files.arm
        src/sys/arch/arm/fdt: cpu_fdt.c
        src/sys/arch/arm/include: cpu.h cpu_topology.h locore.h
        src/sys/arch/arm/include/arm32: machdep.h
        src/sys/arch/arm/mainbus: cpu_mainbus.c
        src/sys/arch/arm/nvidia: soc_tegra124.c
        src/sys/arch/arm/samsung: exynos_platform.c
        src/sys/arch/arm/vexpress: vexpress_platform.c
        src/sys/arch/evbarm/bcm53xx: bcm53xx_machdep.c
        src/sys/arch/evbarm/beagle: beagle_machdep.c
        src/sys/arch/evbarm/gumstix: gumstix_machdep.c
        src/sys/arch/evbarm/imx7: imx7_machdep.c
        src/sys/arch/evbarm/nitrogen6: nitrogen6_machdep.c
        src/sys/arch/evbarm/zynq: zynq_machdep.c
Added Files:
        src/sys/arch/arm/arm: cpu_subr.c
        src/sys/arch/arm/include: cpuvar.h

Log Message:
Various updates and improvements to cpu start up on arm/aarch64

- start sharing more code around the AP startup messaging.
- call arm_cpu_topology_set early so that ci_core_id is available for
  drivers, e.g. bcm2835_intr.c
- both arm and aarch64 now have
  - a static cpu_info_store array
  - the same arm_cpu_{hatched,mbox}


To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/aarch64/aarch64/cpu.c
cvs rdiff -u -r1.55 -r1.56 src/sys/arch/aarch64/aarch64/locore.S
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/aarch64/conf/files.aarch64
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/aarch64/include/cpu.h
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/aarch64/include/machdep.h
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/acpi/cpu_acpi.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/altera/cycv_platform.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/arm/arm_cpu_topology.c
cvs rdiff -u -r1.62 -r1.63 src/sys/arch/arm/arm/arm_machdep.c
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/arm/armv6_start.S
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/arm/cpu_subr.c
cvs rdiff -u -r1.36 -r1.37 src/sys/arch/arm/arm32/arm32_boot.c
cvs rdiff -u -r1.131 -r1.132 src/sys/arch/arm/arm32/arm32_machdep.c
cvs rdiff -u -r1.143 -r1.144 src/sys/arch/arm/arm32/cpu.c
cvs rdiff -u -r1.86 -r1.87 src/sys/arch/arm/arm32/genassym.cf
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/arm/broadcom/bcm2835_intr.c
cvs rdiff -u -r1.152 -r1.153 src/sys/arch/arm/conf/files.arm
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/arm/fdt/cpu_fdt.c
cvs rdiff -u -r1.107 -r1.108 src/sys/arch/arm/include/cpu.h
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/include/cpu_topology.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/include/cpuvar.h
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/arm/include/locore.h
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/arm/include/arm32/machdep.h
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/arm/mainbus/cpu_mainbus.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/arm/nvidia/soc_tegra124.c
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/arm/samsung/exynos_platform.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/arm/vexpress/vexpress_platform.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/evbarm/bcm53xx/bcm53xx_machdep.c
cvs rdiff -u -r1.81 -r1.82 src/sys/arch/evbarm/beagle/beagle_machdep.c
cvs rdiff -u -r1.64 -r1.65 src/sys/arch/evbarm/gumstix/gumstix_machdep.c
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/evbarm/imx7/imx7_machdep.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/evbarm/nitrogen6/nitrogen6_machdep.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/evbarm/zynq/zynq_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/aarch64/aarch64/cpu.c
diff -u src/sys/arch/aarch64/aarch64/cpu.c:1.40 src/sys/arch/aarch64/aarch64/cpu.c:1.41
--- src/sys/arch/aarch64/aarch64/cpu.c:1.40	Sun Feb  9 08:14:55 2020
+++ src/sys/arch/aarch64/aarch64/cpu.c	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.40 2020/02/09 08:14:55 skrll Exp $ */
+/* $NetBSD: cpu.c,v 1.41 2020/02/15 08:16:10 skrll Exp $ */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.40 2020/02/09 08:14:55 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.41 2020/02/15 08:16:10 skrll Exp $");
 
 #include "locators.h"
 #include "opt_arm_debug.h"
@@ -68,16 +68,6 @@ static void cpu_setup_id(struct cpu_info
 static void cpu_setup_sysctl(device_t, struct cpu_info *);
 
 #ifdef MULTIPROCESSOR
-uint64_t cpu_mpidr[MAXCPUS];
-
-volatile u_int aarch64_cpu_mbox[howmany(MAXCPUS, sizeof(u_int))] __cacheline_aligned = { 0 };
-volatile u_int aarch64_cpu_hatched[howmany(MAXCPUS, sizeof(u_int))] __cacheline_aligned = { 0 };
-u_int arm_cpu_max = 1;
-
-static kmutex_t cpu_hatch_lock;
-#endif /* MULTIPROCESSOR */
-
-#ifdef MULTIPROCESSOR
 #define NCPUINFO	MAXCPUS
 #else
 #define NCPUINFO	1
@@ -94,10 +84,6 @@ struct cpu_info cpu_info_store[NCPUINFO]
 	}
 };
 
-struct cpu_info *cpu_info[NCPUINFO] __read_mostly = {
-	[0] = &cpu_info_store[0]
-};
-
 void
 cpu_attach(device_t dv, cpuid_t id)
 {
@@ -498,38 +484,6 @@ cpu_setup_sysctl(device_t dv, struct cpu
 
 #ifdef MULTIPROCESSOR
 void
-cpu_boot_secondary_processors(void)
-{
-	u_int n, bit;
-
-	if ((boothowto & RB_MD1) != 0)
-		return;
-
-	mutex_init(&cpu_hatch_lock, MUTEX_DEFAULT, IPL_NONE);
-
-	VPRINTF("%s: starting secondary processors\n", __func__);
-
-	/* send mbox to have secondary processors do cpu_hatch() */
-	for (n = 0; n < __arraycount(aarch64_cpu_mbox); n++)
-		atomic_or_uint(&aarch64_cpu_mbox[n], aarch64_cpu_hatched[n]);
-	__asm __volatile ("sev; sev; sev");
-
-	/* wait all cpus have done cpu_hatch() */
-	for (n = 0; n < __arraycount(aarch64_cpu_mbox); n++) {
-		while (membar_consumer(), aarch64_cpu_mbox[n] & aarch64_cpu_hatched[n]) {
-			__asm __volatile ("wfe");
-		}
-		/* Add processors to kcpuset */
-		for (bit = 0; bit < 32; bit++) {
-			if (aarch64_cpu_hatched[n] & __BIT(bit))
-				kcpuset_set(kcpuset_attached, n * 32 + bit);
-		}
-	}
-
-	VPRINTF("%s: secondary processors hatched\n", __func__);
-}
-
-void
 cpu_hatch(struct cpu_info *ci)
 {
 	KASSERT(curcpu() == ci);
@@ -556,23 +510,12 @@ cpu_hatch(struct cpu_info *ci)
 #endif
 
 	/*
-	 * clear my bit of aarch64_cpu_mbox to tell cpu_boot_secondary_processors().
+	 * 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.
 	 */
-	const u_int off = device_unit(ci->ci_dev) / 32;
-	const u_int bit = device_unit(ci->ci_dev) % 32;
-	atomic_and_uint(&aarch64_cpu_mbox[off], ~__BIT(bit));
-	__asm __volatile ("sev; sev; sev");
-}
 
-bool
-cpu_hatched_p(u_int cpuindex)
-{
-	const u_int off = cpuindex / 32;
-	const u_int bit = cpuindex % 32;
-	membar_consumer();
-	return (aarch64_cpu_hatched[off] & __BIT(bit)) != 0;
+	cpu_clr_mbox(device_unit(ci->ci_dev));
 }
 #endif /* MULTIPROCESSOR */

Index: src/sys/arch/aarch64/aarch64/locore.S
diff -u src/sys/arch/aarch64/aarch64/locore.S:1.55 src/sys/arch/aarch64/aarch64/locore.S:1.56
--- src/sys/arch/aarch64/aarch64/locore.S:1.55	Sun Feb  9 08:09:58 2020
+++ src/sys/arch/aarch64/aarch64/locore.S	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.55 2020/02/09 08:09:58 skrll Exp $	*/
+/*	$NetBSD: locore.S,v 1.56 2020/02/15 08:16:10 skrll Exp $	*/
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -38,7 +38,7 @@
 #include <aarch64/hypervisor.h>
 #include "assym.h"
 
-RCSID("$NetBSD: locore.S,v 1.55 2020/02/09 08:09:58 skrll Exp $")
+RCSID("$NetBSD: locore.S,v 1.56 2020/02/15 08:16:10 skrll Exp $")
 
 #ifdef AARCH64_DEVICE_MEM_STRONGLY_ORDERED
 #define	MAIR_DEVICE_MEM		MAIR_DEVICE_nGnRnE
@@ -449,35 +449,41 @@ mp_vstart:
 	mrs	x1, mpidr_el1
 	str	x1, [x0, #CI_MPIDR]	/* curcpu()->ci_mpidr = mpidr_el1 */
 
-	mov	x0, #32
-	udiv	x1, x27, x0
-	adrl	x0, _C_LABEL(aarch64_cpu_hatched)
-	add	x28, x0, x1, lsl #2	/* x28 = &aarch64_cpu_hatched[cpuindex/32] */
+	/* set topology information */
+	mov	x2, #0
+	bl	arm_cpu_topology_set
+
+	/* x28 = &arm_cpu_hatched[cpuindex / (sizeof(u_long) * NBBY)] */
+	adrl	x0, _C_LABEL(arm_cpu_hatched)
+	mov	x1, x27, lsr #6
+	add	x28, x0, x1, lsl #3
+
+	/* x29 = __BIT(cpuindex % (sizeof(u_long) * NBBY)) */
 	mov	x0, #1
-	mov	x2, #32
-	msub	x1, x1, x2, x27
-	lsl	x29, x0, x1		/* x29 = 1 << (cpuindex % 32) */
+	and	x2, x27, #63
+	lsl	x29, x0, x2
 
 	/*
-	 * atomic_or_uint(&aarch64_cpu_hatched[cpuindex/32], 1<<cpuindex%32)
-	 * to tell my activity to primary processor.
+	 * atomic_or_ulong(&arm_cpu_hatched[cpuindex / (sizeof(u_long)  * NBBY)],
+	 *   _BIT(cpuindex % ((sizeof(u_long) * NBBY)
+	 * to inform the boot processor.
 	 */
 	mov	x0, x28
 	mov	x1, x29
-	bl	_C_LABEL(atomic_or_uint)	/* hatched! */
+	bl	_C_LABEL(atomic_or_ulong)	/* hatched! */
 	dsb	sy
 	sev
 
-	mov	x0, #32
-	udiv	x1, x27, x0
-	adrl	x0, _C_LABEL(aarch64_cpu_mbox)
-	add	x28, x0, x1, lsl #2	/* x28 = &aarch64_cpu_mbox[cpuindex/32] */
+	/* x28 = &arm_cpu_mbox[cpuindex / (sizeof(u_long) * NBBY)] */
+	adrl	x0, _C_LABEL(arm_cpu_mbox)
+	mov	x1, x27, lsr #6
+	add	x28, x0, x1, lsl #3
 
 	/* wait for the mailbox start bit to become true */
 1:
 	dmb	sy
-	ldr	w20, [x28]
-	tst	w20, w29
+	ldr	x20, [x28]
+	tst	x20, x29
 	bne	9f
 	wfe
 	b	1b

Index: src/sys/arch/aarch64/conf/files.aarch64
diff -u src/sys/arch/aarch64/conf/files.aarch64:1.19 src/sys/arch/aarch64/conf/files.aarch64:1.20
--- src/sys/arch/aarch64/conf/files.aarch64:1.19	Mon Feb  3 13:37:01 2020
+++ src/sys/arch/aarch64/conf/files.aarch64	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: files.aarch64,v 1.19 2020/02/03 13:37:01 ryo Exp $
+#	$NetBSD: files.aarch64,v 1.20 2020/02/15 08:16:10 skrll Exp $
 
 defflag opt_cpuoptions.h	AARCH64_ALIGNMENT_CHECK
 defflag opt_cpuoptions.h	AARCH64_EL0_STACK_ALIGNMENT_CHECK
@@ -86,6 +86,7 @@ file	arch/aarch64/aarch64/bus_space_noti
 file	arch/arm/arm/arm_cpu_topology.c
 file	arch/arm/arm/arm_generic_dma.c
 file	arch/arm/arm/bootconfig.c
+file	arch/arm/arm/cpu_subr.c
 file	arch/arm/arm32/bus_dma.c
 file	arch/aarch64/aarch64/aarch64_machdep.c
 file	arch/aarch64/aarch64/aarch64_reboot.c

Index: src/sys/arch/aarch64/include/cpu.h
diff -u src/sys/arch/aarch64/include/cpu.h:1.20 src/sys/arch/aarch64/include/cpu.h:1.21
--- src/sys/arch/aarch64/include/cpu.h:1.20	Wed Feb 12 06:05:46 2020
+++ src/sys/arch/aarch64/include/cpu.h	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.20 2020/02/12 06:05:46 riastradh Exp $ */
+/* $NetBSD: cpu.h,v 1.21 2020/02/15 08:16:10 skrll Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -32,6 +32,8 @@
 #ifndef _AARCH64_CPU_H_
 #define _AARCH64_CPU_H_
 
+#include <arm/cpu.h>
+
 #ifdef __aarch64__
 
 #ifdef _KERNEL_OPT
@@ -104,7 +106,6 @@ struct cpu_info {
 	uint64_t ci_acpiid;	/* ACPI Processor Unique ID */
 
 	struct aarch64_sysctl_cpu_id ci_id;
-#define arm_cpu_mpidr(ci)	((ci)->ci_id.ac_mpidr)
 
 	struct aarch64_cache_info *ci_cacheinfo;
 	struct aarch64_cpufuncs ci_cpufuncs;
@@ -123,15 +124,12 @@ curcpu(void)
 #define setsoftast(ci)		atomic_or_uint(&(ci)->ci_astpending, __BIT(0))
 #define cpu_signotify(l)	setsoftast((l)->l_cpu)
 
-void cpu_proc_fork(struct proc *, struct proc *);
-void cpu_need_proftick(struct lwp *l);
-void cpu_boot_secondary_processors(void);
-void cpu_mpstart(void);
-void cpu_hatch(struct cpu_info *);
+void	cpu_need_proftick(struct lwp *l);
+
+void	cpu_hatch(struct cpu_info *);
 
 extern struct cpu_info *cpu_info[];
-extern uint64_t cpu_mpidr[];		/* MULTIPROCESSOR */
-bool cpu_hatched_p(u_int);		/* MULTIPROCESSOR */
+extern struct cpu_info cpu_info_store[];
 
 #define CPU_INFO_ITERATOR	cpuid_t
 #if defined(MULTIPROCESSOR) || defined(_MODULE)
@@ -161,14 +159,8 @@ cpu_dosoftints(void)
 #endif
 }
 
-void	cpu_attach(device_t, cpuid_t);
-
 #endif /* _KERNEL || _KMEMUSER */
 
-#elif defined(__arm__)
-
-#include <arm/cpu.h>
-
 #endif
 
 #endif /* _AARCH64_CPU_H_ */

Index: src/sys/arch/aarch64/include/machdep.h
diff -u src/sys/arch/aarch64/include/machdep.h:1.9 src/sys/arch/aarch64/include/machdep.h:1.10
--- src/sys/arch/aarch64/include/machdep.h:1.9	Wed Dec 18 21:45:43 2019
+++ src/sys/arch/aarch64/include/machdep.h	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.h,v 1.9 2019/12/18 21:45:43 riastradh Exp $	*/
+/*	$NetBSD: machdep.h,v 1.10 2020/02/15 08:16:10 skrll Exp $	*/
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -66,10 +66,6 @@ extern void (*cpu_powerdown_address)(voi
 
 extern char *booted_kernel;
 
-#ifdef MULTIPROCESSOR
-extern u_int arm_cpu_max;
-#endif
-
 /*
  * note that we use void * as all the platforms have different ideas on what
  * the structure is

Index: src/sys/arch/arm/acpi/cpu_acpi.c
diff -u src/sys/arch/arm/acpi/cpu_acpi.c:1.7 src/sys/arch/arm/acpi/cpu_acpi.c:1.8
--- src/sys/arch/arm/acpi/cpu_acpi.c:1.7	Sat Oct 19 18:04:26 2019
+++ src/sys/arch/arm/acpi/cpu_acpi.c	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_acpi.c,v 1.7 2019/10/19 18:04:26 jmcneill Exp $ */
+/* $NetBSD: cpu_acpi.c,v 1.8 2020/02/15 08:16:10 skrll Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_acpi.c,v 1.7 2019/10/19 18:04:26 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_acpi.c,v 1.8 2020/02/15 08:16:10 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_acpi.c,v
 #include <arm/armreg.h>
 #include <arm/cpu.h>
 #include <arm/cpufunc.h>
+#include <arm/cpuvar.h>
 #include <arm/locore.h>
 
 #include <arm/arm/psci.h>
@@ -57,8 +58,6 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_acpi.c,v
 #include <dev/tprof/tprof_armv8.h>
 #endif
 
-extern struct cpu_info cpu_info_store[];
-
 static int	cpu_acpi_match(device_t, cfdata_t, void *);
 static void	cpu_acpi_attach(device_t, device_t, void *);
 

Index: src/sys/arch/arm/altera/cycv_platform.c
diff -u src/sys/arch/arm/altera/cycv_platform.c:1.11 src/sys/arch/arm/altera/cycv_platform.c:1.12
--- src/sys/arch/arm/altera/cycv_platform.c:1.11	Mon May 20 20:17:25 2019
+++ src/sys/arch/arm/altera/cycv_platform.c	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cycv_platform.c,v 1.11 2019/05/20 20:17:25 aymeric Exp $ */
+/* $NetBSD: cycv_platform.c,v 1.12 2020/02/15 08:16:10 skrll Exp $ */
 
 /* This file is in the public domain. */
 
@@ -7,7 +7,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cycv_platform.c,v 1.11 2019/05/20 20:17:25 aymeric Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cycv_platform.c,v 1.12 2020/02/15 08:16:10 skrll Exp $");
 
 #define	_ARM32_BUS_DMA_PRIVATE
 #include <sys/param.h>
@@ -117,7 +117,7 @@ cycv_mpstart(void)
 	int i;
 	for (i = 0x10000000; i > 0; i--) {
 		membar_consumer();
-		if (arm_cpu_hatched == (1 << 1))
+		if (cpu_hatched_p(1))
 			break;
 	}
 	if (i == 0) {

Index: src/sys/arch/arm/arm/arm_cpu_topology.c
diff -u src/sys/arch/arm/arm/arm_cpu_topology.c:1.3 src/sys/arch/arm/arm/arm_cpu_topology.c:1.4
--- src/sys/arch/arm/arm/arm_cpu_topology.c:1.3	Sat Feb 15 07:20:41 2020
+++ src/sys/arch/arm/arm/arm_cpu_topology.c	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm_cpu_topology.c,v 1.3 2020/02/15 07:20:41 skrll Exp $	*/
+/*	$NetBSD: arm_cpu_topology.c,v 1.4 2020/02/15 08:16:10 skrll Exp $	*/
 
 /*
  * Copyright (c) 2020 Matthew R. Green
@@ -33,7 +33,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm_cpu_topology.c,v 1.3 2020/02/15 07:20:41 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_cpu_topology.c,v 1.4 2020/02/15 08:16:10 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -47,7 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: arm_cpu_topo
 #include <prop/proplib.h>
 
 void
-arm_cpu_topology_set(struct cpu_info * const ci, uint64_t mpidr, bool slow)
+arm_cpu_topology_set(struct cpu_info * const ci, mpidr_t mpidr)
 {
 #ifdef MULTIPROCESSOR
 	uint pkgid, coreid, smtid, numaid = 0;

Index: src/sys/arch/arm/arm/arm_machdep.c
diff -u src/sys/arch/arm/arm/arm_machdep.c:1.62 src/sys/arch/arm/arm/arm_machdep.c:1.63
--- src/sys/arch/arm/arm/arm_machdep.c:1.62	Wed Jan 22 10:52:35 2020
+++ src/sys/arch/arm/arm/arm_machdep.c	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm_machdep.c,v 1.62 2020/01/22 10:52:35 skrll Exp $	*/
+/*	$NetBSD: arm_machdep.c,v 1.63 2020/02/15 08:16:10 skrll Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.62 2020/01/22 10:52:35 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.63 2020/02/15 08:16:10 skrll Exp $");
 
 #include <sys/atomic.h>
 #include <sys/cpu.h>
@@ -106,24 +106,22 @@ char	machine_arch[] = MACHINE_ARCH;	/* f
 
 extern const uint32_t undefinedinstruction_bounce[];
 
-/* Our exported CPU info; we can have only one. */
-struct cpu_info cpu_info_store = {
-	.ci_cpl = IPL_HIGH,
-	.ci_curlwp = &lwp0,
-	.ci_undefsave[2] = (register_t) undefinedinstruction_bounce,
-#if defined(ARM_MMU_EXTENDED) && KERNEL_PID != 0
-	.ci_pmap_asid_cur = KERNEL_PID,
-#endif
-};
-
 #ifdef MULTIPROCESSOR
 #define	NCPUINFO	MAXCPUS
 #else
 #define	NCPUINFO	1
 #endif
 
-struct cpu_info *cpu_info[NCPUINFO] = {
-	[0] = &cpu_info_store
+/* Our exported CPU info; we can have only one. */
+struct cpu_info cpu_info_store[NCPUINFO] = {
+	[0] = {
+		.ci_cpl = IPL_HIGH,
+		.ci_curlwp = &lwp0,
+		.ci_undefsave[2] = (register_t) undefinedinstruction_bounce,
+#if defined(ARM_MMU_EXTENDED) && KERNEL_PID != 0
+		.ci_pmap_asid_cur = KERNEL_PID,
+#endif
+	}
 };
 
 const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = {

Index: src/sys/arch/arm/arm/armv6_start.S
diff -u src/sys/arch/arm/arm/armv6_start.S:1.14 src/sys/arch/arm/arm/armv6_start.S:1.15
--- src/sys/arch/arm/arm/armv6_start.S:1.14	Wed Jun 12 06:53:21 2019
+++ src/sys/arch/arm/arm/armv6_start.S	Sat Feb 15 08:16:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: armv6_start.S,v 1.14 2019/06/12 06:53:21 skrll Exp $	*/
+/*	$NetBSD: armv6_start.S,v 1.15 2020/02/15 08:16:10 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2012, 2017, 2018 The NetBSD Foundation, Inc.
@@ -178,14 +178,6 @@ arm_bad_vtopdiff:
 1:	b	 1b
 ASEND(generic_start)
 
-generic_vstart:
-	VPRINTF("go\n\r")
-
-	/*
-	 * Jump to start in locore.S, which in turn will call initarm and main.
-	 */
-	b	start
-
 /*
  * Save the u-boot arguments (including FDT address) and the virtual to physical
  * offset.
@@ -464,10 +456,31 @@ generic_startv7:
 	sub	r0, R_VTOPDIFF
 
 	// Return to virtual addess after the call to armv7_mmuinit
-	movw	lr, #:lower16:generic_vstart
-	movt	lr, #:upper16:generic_vstart
+	movw	lr, #:lower16:generic_vstartv7
+	movt	lr, #:upper16:generic_vstartv7
 	b	armv7_mmuinit
 
+generic_vstartv7:
+
+	/* r0 = &cpu_info_store[0] */
+	movw	r0, #:lower16:cpu_info_store
+	movt	r0, #:upper16:cpu_info_store
+
+	mrc	p15, 0, r1, c0, c0, 0	// MIDR get
+	str	r1, [r0, #CI_MIDR]
+	mrc	p15, 0, r1, c0, c0, 5	// MPIDR get
+	str	r1, [r0, #CI_MPIDR]
+
+	mov	r2, #0
+	bl	arm_cpu_topology_set
+
+	VPRINTF("go\n\r")
+
+	/*
+	 * Jump to start in locore.S, which in turn will call initarm and main.
+	 */
+	b	start
+
 	/* NOTREACHED */
 	.ltorg
 #elif defined(_ARM_ARCH_6)
@@ -491,9 +504,17 @@ generic_startv6:
 	ldr	r0, =TEMP_L1_TABLE
 	sub	r0, R_VTOPDIFF
 
-	ldr	lr, =generic_vstart
+	ldr	lr, =generic_vstartv6
 	b	armv6_mmuinit
 
+generic_vstartv6:
+	VPRINTF("go\n\r")
+
+	/*
+	 * Jump to start in locore.S, which in turn will call initarm and main.
+	 */
+	b	start
+
 	/* NOTREACHED */
 	.ltorg
 
@@ -851,20 +872,38 @@ armv7_mpcontinuation:
 
 	VPRINTF("go\n\r")
 
-	mov	r0, R_INDEX			// index into cpu_mpidr[] or cpu_number if not found
+	// index into cpu_mpidr[] or cpu_number if not found
+	mov	r0, R_INDEX
 	bl	cpu_init_secondary_processor
 
+	/* r0 = &cpu_info_store[0] */
+	movw	r0, #:lower16:cpu_info_store
+	movt	r0, #:upper16:cpu_info_store
+
+	mov	r4, #CPU_INFO_SIZE
+	mul	r5, r4, R_INDEX
+	add	r0, r5
+
+	mrc	p15, 0, r1, c0, c0, 0	// MIDR get
+	str	r1, [r0, #CI_MIDR]
+	mrc	p15, 0, r1, c0, c0, 5	// MPIDR get
+	str	r1, [r0, #CI_MPIDR]
+
+	mov	r2, #0
+	bl	arm_cpu_topology_set
+
 	/*
-	 * Wait for cpu_boot_secondary_processors when cpu_info has
-	 * been allocated, etc
+	 * Wait for cpu_boot_secondary_processors
 	 */
 
+	/* r6 = &arm_cpu_mbox[0] */
 	movw	r6, #:lower16:arm_cpu_mbox
 	movt	r6, #:upper16:arm_cpu_mbox
 
 	mov	r5, #1				// bitmask...
 	lsl	r5, R_INDEX			// ... for our cpu
 
+	/* wait for the mailbox start bit to become true */
 1:	dmb					// data memory barrier
 	ldr	r2, [r6]			// load mbox
 	tst	r2, r5				// is our bit set?
@@ -872,7 +911,7 @@ armv7_mpcontinuation:
 	beq	1b				//    no, and try again
 
 	movw	r0, #:lower16:cpu_info
-	movt	r0, #:upper16:cpu_info		// get pointer to cpu_infos
+	movt	r0, #:upper16:cpu_info		// get pointer to cpu_info
 	ldr	r5, [r0, R_INDEX, lsl #2]	// load our cpu_info
 	ldr	r6, [r5, #CI_IDLELWP]		// get the idlelwp
 	ldr	r7, [r6, #L_PCB]		// now get its pcb

Index: src/sys/arch/arm/arm32/arm32_boot.c
diff -u src/sys/arch/arm/arm32/arm32_boot.c:1.36 src/sys/arch/arm/arm32/arm32_boot.c:1.37
--- src/sys/arch/arm/arm32/arm32_boot.c:1.36	Wed Jan  8 18:47:43 2020
+++ src/sys/arch/arm/arm32/arm32_boot.c	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm32_boot.c,v 1.36 2020/01/08 18:47:43 jmcneill Exp $	*/
+/*	$NetBSD: arm32_boot.c,v 1.37 2020/02/15 08:16:11 skrll Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
@@ -122,7 +122,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.36 2020/01/08 18:47:43 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.37 2020/02/15 08:16:11 skrll Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_cputypes.h"
@@ -158,10 +158,6 @@ __KERNEL_RCSID(1, "$NetBSD: arm32_boot.c
 #define VPRINTF(...)	__nothing
 #endif
 
-#ifdef MULTIPROCESSOR
-static kmutex_t cpu_hatch_lock;
-#endif
-
 vaddr_t
 initarm_common(vaddr_t kvm_base, vsize_t kvm_size,
 	const struct boot_physmem *bp, size_t nbp)
@@ -323,8 +319,6 @@ initarm_common(vaddr_t kvm_base, vsize_t
 #endif
 
 #ifdef MULTIPROCESSOR
-	mutex_init(&cpu_hatch_lock, MUTEX_DEFAULT, IPL_NONE);
-
 	/*
 	 * Ensure BP cache is flushed to memory so that APs start cache
 	 * coherency with correct view.
@@ -354,9 +348,8 @@ cpu_hatch(struct cpu_info *ci, u_int cpu
 	splhigh();
 
 	VPRINTF("%s(%s): ", __func__, cpu_name(ci));
+	/* mpidr/midr filled in by armv7_mpcontinuation */
 	ci->ci_ctrl = armreg_sctlr_read();
-	uint32_t mpidr = armreg_mpidr_read();
-	ci->ci_mpidr = mpidr;
 	ci->ci_arm_cpuid = cpu_idnum();
 	ci->ci_arm_cputype = ci->ci_arm_cpuid & CPU_ID_CPU_MASK;
 	ci->ci_arm_cpurev = ci->ci_arm_cpuid & CPU_ID_REVISION_MASK;
@@ -424,9 +417,6 @@ cpu_hatch(struct cpu_info *ci, u_int cpu
 
 	VPRINTF(" done!\n");
 
-	/* Notify cpu_boot_secondary_processors that we're done */
-	atomic_and_32(&arm_cpu_mbox, ~__BIT(cpuindex));
-	membar_producer();
-	__asm __volatile("sev; sev; sev");
+	cpu_clr_mbox(cpuindex);
 }
 #endif /* MULTIPROCESSOR */

Index: src/sys/arch/arm/arm32/arm32_machdep.c
diff -u src/sys/arch/arm/arm32/arm32_machdep.c:1.131 src/sys/arch/arm/arm32/arm32_machdep.c:1.132
--- src/sys/arch/arm/arm32/arm32_machdep.c:1.131	Sun Feb  2 07:59:41 2020
+++ src/sys/arch/arm/arm32/arm32_machdep.c	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm32_machdep.c,v 1.131 2020/02/02 07:59:41 skrll Exp $	*/
+/*	$NetBSD: arm32_machdep.c,v 1.132 2020/02/15 08:16:11 skrll Exp $	*/
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.131 2020/02/02 07:59:41 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.132 2020/02/15 08:16:11 skrll Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_arm_start.h"
@@ -472,7 +472,7 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
 		       CTLTYPE_INT, "fpu_id", NULL,
-		       NULL, 0, &cpu_info_store.ci_vfp_id, 0,
+		       NULL, 0, &cpu_info_store[0].ci_vfp_id, 0,
 		       CTL_MACHDEP, CTL_CREATE, CTL_EOL);
 #endif
 	sysctl_createv(clog, 0, NULL, NULL,
@@ -735,7 +735,6 @@ void
 cpu_init_secondary_processor(int cpuindex)
 {
 	// pmap_kernel has been successfully built and we can switch to it
-
 	cpu_domains(DOMAIN_DEFAULT);
 	cpu_idcache_wbinv_all();
 
@@ -777,30 +776,16 @@ cpu_init_secondary_processor(int cpuinde
 	VPRINTS(")");
 #endif
 
-	VPRINTS(" hatched=");
-	VPRINTX(arm_cpu_hatched | __BIT(cpuindex));
+	VPRINTS(" hatched|=");
+	VPRINTX(__BIT(cpuindex));
 	VPRINTS("\n\r");
 
-	atomic_or_uint(&arm_cpu_hatched, __BIT(cpuindex));
+	cpu_set_hatched(cpuindex);
 
 	/* return to assembly to wait for cpu_boot_secondary_processors */
 }
 
 void
-cpu_boot_secondary_processors(void)
-{
-	VPRINTF("%s: writing mbox with %#x\n", __func__, arm_cpu_hatched);
-	arm_cpu_mbox = arm_cpu_hatched;
-	membar_producer();
-#ifdef _ARM_ARCH_7
-	__asm __volatile("sev; sev; sev");
-#endif
-	while (membar_consumer(), arm_cpu_mbox) {
-		__asm __volatile("wfe" ::: "memory");
-	}
-}
-
-void
 xc_send_ipi(struct cpu_info *ci)
 {
 	KASSERT(kpreempt_disabled());

Index: src/sys/arch/arm/arm32/cpu.c
diff -u src/sys/arch/arm/arm32/cpu.c:1.143 src/sys/arch/arm/arm32/cpu.c:1.144
--- src/sys/arch/arm/arm32/cpu.c:1.143	Wed Jan 22 12:23:12 2020
+++ src/sys/arch/arm/arm32/cpu.c	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.143 2020/01/22 12:23:12 skrll Exp $	*/
+/*	$NetBSD: cpu.c,v 1.144 2020/02/15 08:16:11 skrll Exp $	*/
 
 /*
  * Copyright (c) 1995 Mark Brinicombe.
@@ -46,7 +46,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.143 2020/01/22 12:23:12 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.144 2020/02/15 08:16:11 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.14
 #include <sys/device.h>
 #include <sys/kmem.h>
 #include <sys/proc.h>
+#include <sys/reboot.h>
 #include <sys/systm.h>
 
 #include <uvm/uvm_extern.h>
@@ -65,14 +66,6 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.14
 extern const char *cpu_arch;
 
 #ifdef MULTIPROCESSOR
-uint32_t cpu_mpidr[MAXCPUS] = {
-	[0 ... MAXCPUS - 1] = ~0,
-};
-
-volatile u_int arm_cpu_hatched __cacheline_aligned = 0;
-volatile uint32_t arm_cpu_mbox __cacheline_aligned = 0;
-u_int arm_cpu_max = 1;
-
 #ifdef MPDEBUG
 uint32_t arm_cpu_marker[2] __cacheline_aligned = { 0, 0 };
 #endif
@@ -107,19 +100,23 @@ cpu_attach(device_t dv, cpuid_t id)
 		ci->ci_arm_cpuid = cpu_idnum();
 		ci->ci_arm_cputype = ci->ci_arm_cpuid & CPU_ID_CPU_MASK;
 		ci->ci_arm_cpurev = ci->ci_arm_cpuid & CPU_ID_REVISION_MASK;
-#ifdef MULTIPROCESSOR
-		uint32_t mpidr = armreg_mpidr_read();
-		ci->ci_mpidr = mpidr;
-#endif
 	} else {
 #ifdef MULTIPROCESSOR
+		if ((boothowto & RB_MD1) != 0) {
+			aprint_naive("\n");
+			aprint_normal(": multiprocessor boot disabled\n");
+			return;
+		}
+
+		KASSERT(unit < MAXCPUS);
+		ci = &cpu_info_store[unit];
+
 		KASSERT(cpu_info[unit] == NULL);
-		ci = kmem_zalloc(sizeof(*ci), KM_SLEEP);
 		ci->ci_cpl = IPL_HIGH;
 		ci->ci_cpuid = id;
-		ci->ci_data.cpu_cc_freq = cpu_info_store.ci_data.cpu_cc_freq;
+		ci->ci_data.cpu_cc_freq = cpu_info_store[0].ci_data.cpu_cc_freq;
 
-		ci->ci_undefsave[2] = cpu_info_store.ci_undefsave[2];
+		ci->ci_undefsave[2] = cpu_info_store[0].ci_undefsave[2];
 
 		cpu_info[unit] = ci;
 		if (cpu_hatched_p(unit) == false) {
@@ -233,15 +230,6 @@ cpu_attach(device_t dv, cpuid_t id)
 	vfp_attach(ci);		/* XXX SMP */
 }
 
-#ifdef MULTIPROCESSOR
-bool
-cpu_hatched_p(u_int cpuindex)
-{
-	membar_consumer();
-	return (arm_cpu_hatched & __BIT(cpuindex)) != 0;
-}
-#endif
-
 enum cpu_class {
 	CPU_CLASS_NONE,
 	CPU_CLASS_ARM2,

Index: src/sys/arch/arm/arm32/genassym.cf
diff -u src/sys/arch/arm/arm32/genassym.cf:1.86 src/sys/arch/arm/arm32/genassym.cf:1.87
--- src/sys/arch/arm/arm32/genassym.cf:1.86	Fri Feb 14 07:23:24 2020
+++ src/sys/arch/arm/arm32/genassym.cf	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.86 2020/02/14 07:23:24 skrll Exp $
+#	$NetBSD: genassym.cf,v 1.87 2020/02/15 08:16:11 skrll Exp $
 
 # Copyright (c) 1982, 1990 The Regents of the University of California.
 # All rights reserved.
@@ -219,11 +219,14 @@ define	CF_CONTEXT_SWITCH	offsetof(struct
 define	CF_SLEEP		offsetof(struct cpu_functions, cf_sleep)
 define	CF_CONTROL		offsetof(struct cpu_functions, cf_control)
 
+define	CPU_INFO_SIZE		sizeof(struct cpu_info)
 define	CI_ARM_CPUID		offsetof(struct cpu_info, ci_arm_cpuid)
 define	CI_ASTPENDING		offsetof(struct cpu_info, ci_astpending)
 define	CI_CPL			offsetof(struct cpu_info, ci_cpl)
 define	CI_CURLWP		offsetof(struct cpu_info, ci_curlwp)
 define	CI_INTR_DEPTH		offsetof(struct cpu_info, ci_intr_depth)
+define	CI_MIDR			offsetof(struct cpu_info, ci_midr)
+define	CI_MPIDR		offsetof(struct cpu_info, ci_mpidr)
 define	CI_MTX_COUNT		offsetof(struct cpu_info, ci_mtx_count)
 define	CI_LASTLWP		offsetof(struct cpu_info, ci_lastlwp)
 define	CI_UNDEFSAVE		offsetof(struct cpu_info, ci_undefsave[0])

Index: src/sys/arch/arm/broadcom/bcm2835_intr.c
diff -u src/sys/arch/arm/broadcom/bcm2835_intr.c:1.31 src/sys/arch/arm/broadcom/bcm2835_intr.c:1.32
--- src/sys/arch/arm/broadcom/bcm2835_intr.c:1.31	Mon Jan 20 06:55:35 2020
+++ src/sys/arch/arm/broadcom/bcm2835_intr.c	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm2835_intr.c,v 1.31 2020/01/20 06:55:35 mrg Exp $	*/
+/*	$NetBSD: bcm2835_intr.c,v 1.32 2020/02/15 08:16:11 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2012, 2015, 2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.31 2020/01/20 06:55:35 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.32 2020/02/15 08:16:11 skrll Exp $");
 
 #define _INTR_PRIVATE
 
@@ -337,7 +337,7 @@ bcm2835_irq_handler(void *frame)
 {
 	struct cpu_info * const ci = curcpu();
 	const int oldipl = ci->ci_cpl;
-	const cpuid_t cpuid = __SHIFTOUT(arm_cpu_mpidr(ci), MPIDR_AFF0);
+	const cpuid_t cpuid = ci->ci_core_id;
 	const uint32_t oldipl_mask = __BIT(oldipl);
 	int ipl_mask = 0;
 
@@ -700,7 +700,7 @@ static int
 bcm2836mp_pic_find_pending_irqs(struct pic_softc *pic)
 {
 	struct cpu_info * const ci = curcpu();
-	const cpuid_t cpuid = __SHIFTOUT(arm_cpu_mpidr(ci), MPIDR_AFF0);
+	const cpuid_t cpuid = ci->ci_core_id;
 	uint32_t lpending;
 	int ipl = 0;
 
@@ -741,7 +741,7 @@ bcm2836mp_pic_source_name(struct pic_sof
 #if defined(MULTIPROCESSOR)
 static void bcm2836mp_cpu_init(struct pic_softc *pic, struct cpu_info *ci)
 {
-	const cpuid_t cpuid = __SHIFTOUT(arm_cpu_mpidr(ci), MPIDR_AFF0);
+	const cpuid_t cpuid = ci->ci_core_id;
 
 	KASSERT(cpuid < BCM2836_NCPUS);
 
@@ -768,7 +768,7 @@ int
 bcm2836mp_ipi_handler(void *priv)
 {
 	const struct cpu_info *ci = curcpu();
-	const cpuid_t cpuid = __SHIFTOUT(arm_cpu_mpidr(ci), MPIDR_AFF0);
+	const cpuid_t cpuid = ci->ci_core_id;
 	uint32_t ipimask, bit;
 
 	KASSERT(cpuid < BCM2836_NCPUS);
@@ -817,7 +817,7 @@ bcm2836mp_ipi_handler(void *priv)
 static void
 bcm2836mp_intr_init(void *priv, struct cpu_info *ci)
 {
-	const cpuid_t cpuid = __SHIFTOUT(arm_cpu_mpidr(ci), MPIDR_AFF0);
+	const cpuid_t cpuid = ci->ci_core_id;
 	struct pic_softc * const pic = &bcm2836mp_pic[cpuid];
 
 	KASSERT(cpuid < BCM2836_NCPUS);

Index: src/sys/arch/arm/conf/files.arm
diff -u src/sys/arch/arm/conf/files.arm:1.152 src/sys/arch/arm/conf/files.arm:1.153
--- src/sys/arch/arm/conf/files.arm:1.152	Tue Jan 21 05:05:22 2020
+++ src/sys/arch/arm/conf/files.arm	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: files.arm,v 1.152 2020/01/21 05:05:22 skrll Exp $
+#	$NetBSD: files.arm,v 1.153 2020/02/15 08:16:11 skrll Exp $
 
 # temporary define to allow easy moving to ../arch/arm/arm32
 defflag				ARM32
@@ -200,6 +200,7 @@ file	arch/arm/arm/cpufunc_asm_ixp12x0.S	
 file	arch/arm/arm/cpufunc_asm_sheeva.S	cpu_sheeva
 file	arch/arm/arm/cpu_exec.c
 file	arch/arm/arm/cpu_in_cksum.S		(inet | inet6) & cpu_in_cksum
+file	arch/arm/arm/cpu_subr.c
 file	arch/arm/arm/fusu.S
 file	arch/arm/arm/idle_machdep.c
 file	arch/arm/arm/lock_cas.S

Index: src/sys/arch/arm/fdt/cpu_fdt.c
diff -u src/sys/arch/arm/fdt/cpu_fdt.c:1.33 src/sys/arch/arm/fdt/cpu_fdt.c:1.34
--- src/sys/arch/arm/fdt/cpu_fdt.c:1.33	Mon Jan 27 23:26:15 2020
+++ src/sys/arch/arm/fdt/cpu_fdt.c	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_fdt.c,v 1.33 2020/01/27 23:26:15 jmcneill Exp $ */
+/* $NetBSD: cpu_fdt.c,v 1.34 2020/02/15 08:16:11 skrll Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -30,7 +30,7 @@
 #include "psci_fdt.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.33 2020/01/27 23:26:15 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.34 2020/02/15 08:16:11 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 
 #include <arm/armreg.h>
 #include <arm/cpu.h>
 #include <arm/cpufunc.h>
+#include <arm/cpuvar.h>
 #include <arm/locore.h>
 
 #include <arm/arm/psci.h>

Index: src/sys/arch/arm/include/cpu.h
diff -u src/sys/arch/arm/include/cpu.h:1.107 src/sys/arch/arm/include/cpu.h:1.108
--- src/sys/arch/arm/include/cpu.h:1.107	Wed Jan 22 12:23:12 2020
+++ src/sys/arch/arm/include/cpu.h	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.107 2020/01/22 12:23:12 skrll Exp $	*/
+/*	$NetBSD: cpu.h,v 1.108 2020/02/15 08:16:11 skrll Exp $	*/
 
 /*
  * Copyright (c) 1994-1996 Mark Brinicombe.
@@ -48,6 +48,30 @@
 #ifndef _ARM_CPU_H_
 #define _ARM_CPU_H_
 
+#ifdef _KERNEL
+#ifndef _LOCORE
+
+typedef unsigned long mpidr_t;
+
+#ifdef MULTIPROCESSOR
+extern u_int arm_cpu_max;
+extern mpidr_t cpu_mpidr[];
+extern kmutex_t cpu_hatch_lock;
+
+void cpu_boot_secondary_processors(void);
+void cpu_mpstart(void);
+bool cpu_hatched_p(u_int);
+
+void cpu_clr_mbox(int);
+void cpu_set_hatched(int);
+
+#endif
+
+void	cpu_proc_fork(struct proc *, struct proc *);
+
+#endif	/* !_LOCORE */
+#endif	/* _KERNEL */
+
 #ifdef __arm__
 
 /*
@@ -178,7 +202,6 @@ struct cpu_info {
 
 	uint32_t	ci_midr;
 	uint32_t	ci_mpidr;
-#define arm_cpu_mpidr(ci)	((ci)->ci_mpidr)
 	uint32_t	ci_capacity_dmips_mhz;
 
 	struct arm_cache_info *
@@ -189,7 +212,7 @@ struct cpu_info {
 #endif
 };
 
-extern struct cpu_info cpu_info_store;
+extern struct cpu_info cpu_info_store[];
 
 struct lwp *arm_curlwp(void);
 struct cpu_info *arm_curcpu(void);
@@ -228,7 +251,7 @@ curcpu(void)
 	return (struct cpu_info *) armreg_tpidrprw_read();
 }
 #elif !defined(MULTIPROCESSOR)
-#define	curcpu()	(&cpu_info_store)
+#define	curcpu()	(&cpu_info_store[0])
 #elif !defined(__HAVE_PREEMPTION)
 #error MULTIPROCESSOR && !__HAVE_PREEMPTION requires TPIDRPRW_IS_CURCPU or TPIDRPRW_IS_CURLWP
 #else
@@ -255,16 +278,10 @@ extern struct cpu_info *cpu_info[];
 #endif
 
 #if defined(MULTIPROCESSOR)
-
-extern uint32_t cpu_mpidr[];
-bool cpu_hatched_p(u_int);
-
-void cpu_mpstart(void);
 void cpu_init_secondary_processor(int);
-void cpu_boot_secondary_processors(void);
 #endif
 
-#define	LWP0_CPU_INFO	(&cpu_info_store)
+#define	LWP0_CPU_INFO	(&cpu_info_store[0])
 
 static inline int
 curcpl(void)
@@ -291,8 +308,6 @@ cpu_dosoftints(void)
 #endif
 }
 
-void	cpu_proc_fork(struct proc *, struct proc *);
-
 /*
  * Scheduling glue
  */
@@ -324,11 +339,6 @@ void	cpu_proc_fork(struct proc *, struct
  */
 vaddr_t cpu_uarea_alloc_idlelwp(struct cpu_info *);
 
-/*
- * cpu device glue (belongs in cpuvar.h)
- */
-void	cpu_attach(device_t, cpuid_t);
-
 #ifdef _ARM_ARCH_6
 int	cpu_maxproc_hook(int);
 #endif

Index: src/sys/arch/arm/include/cpu_topology.h
diff -u src/sys/arch/arm/include/cpu_topology.h:1.1 src/sys/arch/arm/include/cpu_topology.h:1.2
--- src/sys/arch/arm/include/cpu_topology.h:1.1	Wed Jan 15 08:34:04 2020
+++ src/sys/arch/arm/include/cpu_topology.h	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_topology.h,v 1.1 2020/01/15 08:34:04 mrg Exp $	*/
+/*	$NetBSD: cpu_topology.h,v 1.2 2020/02/15 08:16:11 skrll Exp $	*/
 
 /*
  * Copyright (c) 2020 Matthew R. Green
@@ -36,24 +36,23 @@
  *
  * arm_cpu_do_topology(cpuinfo)
  *
- * Call arm_cpu_do_topology() in cpu_attach() after making sure that
- * arm_cpu_mpidr() will work for this CPU, and it will split up
- * package/core/smt IDs.
- *
- * The CPU frontend can set the "capacity_dmips_mhz" property for
- * this CPU device, and arm_cpu_set_topology() will calculate the
- * best way to call cpu_topology_set() for the known system.
+ * Call arm_cpu_do_topology() in cpu_attach(). It will update the topology
+ * view of relative speed.
  *
- * arm_cpu_topology_set(cpuinfo, mpidr, slow)
+ * The CPU frontend can set the "capacity_dmips_mhz" property for this CPU,
+ * and arm_cpu_do_topology() will update the system view of this and other
+ * CPUs relative speeds
+ *
+ * arm_cpu_topology_set(cpuinfo, mpidr)
  *
  * arm_cpu_topology_set() is provided for locore and the boot CPU,
- * and only works for the current CPU.
+ * and application CPUs.  It updates data for the current CPU.
  */
 
 #include <sys/param.h>
 #include <sys/cpu.h>
 
 void arm_cpu_do_topology(struct cpu_info * const);
-void arm_cpu_topology_set(struct cpu_info * const, uint64_t, bool);
+void arm_cpu_topology_set(struct cpu_info * const, mpidr_t);
 
 #endif /* _ARM_CPU_TOPOLOGY_H_ */

Index: src/sys/arch/arm/include/locore.h
diff -u src/sys/arch/arm/include/locore.h:1.31 src/sys/arch/arm/include/locore.h:1.32
--- src/sys/arch/arm/include/locore.h:1.31	Sat Apr  6 03:06:25 2019
+++ src/sys/arch/arm/include/locore.h	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.h,v 1.31 2019/04/06 03:06:25 thorpej Exp $	*/
+/*	$NetBSD: locore.h,v 1.32 2020/02/15 08:16:11 skrll Exp $	*/
 
 /*
  * Copyright (c) 1994-1996 Mark Brinicombe.
@@ -167,10 +167,6 @@ extern int cpu_media_and_vfp_features[2]
 
 extern bool arm_has_tlbiasid_p;
 extern bool arm_has_mpext_p;
-#ifdef MULTIPROCESSOR
-extern u_int arm_cpu_max;
-extern volatile u_int arm_cpu_hatched;
-#endif
 
 #if !defined(CPU_ARMV7)
 #define	CPU_IS_ARMV7_P()		false

Index: src/sys/arch/arm/include/arm32/machdep.h
diff -u src/sys/arch/arm/include/arm32/machdep.h:1.30 src/sys/arch/arm/include/arm32/machdep.h:1.31
--- src/sys/arch/arm/include/arm32/machdep.h:1.30	Wed Dec 18 21:45:44 2019
+++ src/sys/arch/arm/include/arm32/machdep.h	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.h,v 1.30 2019/12/18 21:45:44 riastradh Exp $ */
+/* $NetBSD: machdep.h,v 1.31 2020/02/15 08:16:11 skrll Exp $ */
 
 #ifndef _ARM32_MACHDEP_H_
 #define _ARM32_MACHDEP_H_
@@ -48,13 +48,8 @@ struct bootmem_info {
 extern struct bootmem_info bootmem_info;
 
 extern char *booted_kernel;
-
-extern volatile uint32_t arm_cpu_hatched;
-extern volatile uint32_t arm_cpu_mbox;
-extern u_int arm_cpu_max;
 extern u_long kern_vtopdiff;
 
-
 /* misc prototypes used by the many arm machdeps */
 void cortex_pmc_ccnt_init(void);
 void cpu_hatch(struct cpu_info *, u_int, void (*)(struct cpu_info *));

Index: src/sys/arch/arm/mainbus/cpu_mainbus.c
diff -u src/sys/arch/arm/mainbus/cpu_mainbus.c:1.17 src/sys/arch/arm/mainbus/cpu_mainbus.c:1.18
--- src/sys/arch/arm/mainbus/cpu_mainbus.c:1.17	Tue Jan 28 07:47:26 2020
+++ src/sys/arch/arm/mainbus/cpu_mainbus.c	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_mainbus.c,v 1.17 2020/01/28 07:47:26 skrll Exp $	*/
+/*	$NetBSD: cpu_mainbus.c,v 1.18 2020/02/15 08:16:11 skrll Exp $	*/
 
 /*
  * Copyright (c) 1995 Mark Brinicombe.
@@ -45,14 +45,16 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_mainbus.c,v 1.17 2020/01/28 07:47:26 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_mainbus.c,v 1.18 2020/02/15 08:16:11 skrll Exp $");
 
 #include <sys/param.h>
+#include <sys/types.h>
 #include <sys/systm.h>
 #include <sys/cpu.h>
 #include <sys/device.h>
 #include <sys/proc.h>
 
+#include <arm/cpuvar.h>
 #include <arm/mainbus/mainbus.h>
 
 /*
@@ -67,9 +69,7 @@ static void cpu_mainbus_attach(device_t,
  * Probe for the main cpu. Currently all this does is return 1 to
  * indicate that the cpu was found.
  */
-#ifdef MULTIPROCESSOR
-extern u_int arm_cpu_max;
-#else
+#ifndef MULTIPROCESSOR
 #define	arm_cpu_max		1
 #endif
 
@@ -81,7 +81,7 @@ cpu_mainbus_match(device_t parent, cfdat
 
 	if (id != MAINBUSCF_CORE_DEFAULT) {
 		if (id == 0)
-			return cpu_info_store.ci_dev == NULL;
+			return cpu_info_store[0].ci_dev == NULL;
 		if (id >= arm_cpu_max)
 			return 0;
 #ifdef MULTIPROCESSOR
@@ -91,7 +91,7 @@ cpu_mainbus_match(device_t parent, cfdat
 		return 1;
 	}
 
-	if (cpu_info_store.ci_dev == NULL) {
+	if (cpu_info_store[0].ci_dev == NULL) {
 		mb->mb_core = 0;
 		return 1;
 	}

Index: src/sys/arch/arm/nvidia/soc_tegra124.c
diff -u src/sys/arch/arm/nvidia/soc_tegra124.c:1.21 src/sys/arch/arm/nvidia/soc_tegra124.c:1.22
--- src/sys/arch/arm/nvidia/soc_tegra124.c:1.21	Thu Jan 31 13:19:19 2019
+++ src/sys/arch/arm/nvidia/soc_tegra124.c	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: soc_tegra124.c,v 1.21 2019/01/31 13:19:19 skrll Exp $ */
+/* $NetBSD: soc_tegra124.c,v 1.22 2020/02/15 08:16:11 skrll Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <[email protected]>
@@ -30,7 +30,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.21 2019/01/31 13:19:19 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.22 2020/02/15 08:16:11 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -70,21 +70,28 @@ tegra124_mpstart(void)
 	    (uint32_t)KERN_VTOPHYS((vaddr_t)cpu_mpstart));
 	bus_space_barrier(bst, bsh, EVP_RESET_VECTOR_0_REG, 4,
 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-	uint32_t started = 0;
 
-	tegra_pmc_power(PMC_PARTID_CPU1, true); started |= __BIT(1);
-	tegra_pmc_power(PMC_PARTID_CPU2, true); started |= __BIT(2);
-	tegra_pmc_power(PMC_PARTID_CPU3, true); started |= __BIT(3);
-
-	u_int i;
-	for (i = 0x10000000; i > 0; i--) {
-		arm_dmb();
-		if (arm_cpu_hatched == started)
-			break;
-	}
-	if (i == 0) {
-		ret++;
-		aprint_error("cpu%d: WARNING: AP failed to start\n", i);
+	for (u_int cpuindex = 1; cpuindex < arm_cpu_max; cpuindex++) {
+		static u_int tegra_cpu_pmu[] = {
+		    0,
+		    PMC_PARTID_CPU1,
+		    PMC_PARTID_CPU2,
+		    PMC_PARTID_CPU3
+		};
+
+		tegra_pmc_power(tegra_cpu_pmu[cpuindex], true);
+
+		u_int i;
+		for (i = 0x10000000; i > 0; i--) {
+			if (cpu_hatched_p(cpuindex))
+				break;
+		}
+
+		if (i == 0) {
+			ret++;
+			aprint_error("cpu%d: WARNING: AP failed to start\n",
+			    cpuindex);
+		}
 	}
 #endif
 	return ret;

Index: src/sys/arch/arm/samsung/exynos_platform.c
diff -u src/sys/arch/arm/samsung/exynos_platform.c:1.26 src/sys/arch/arm/samsung/exynos_platform.c:1.27
--- src/sys/arch/arm/samsung/exynos_platform.c:1.26	Tue Apr  9 07:37:16 2019
+++ src/sys/arch/arm/samsung/exynos_platform.c	Sat Feb 15 08:16:11 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_platform.c,v 1.26 2019/04/09 07:37:16 skrll Exp $ */
+/* $NetBSD: exynos_platform.c,v 1.27 2020/02/15 08:16:11 skrll Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <[email protected]>
@@ -35,7 +35,7 @@
 #include "ukbd.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.26 2019/04/09 07:37:16 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.27 2020/02/15 08:16:11 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -168,7 +168,7 @@ exynos5800_mpstart(void)
 		/* Wait for AP to start */
 		for (n = 0x100000; n > 0; n--) {
 			membar_consumer();
-			if (arm_cpu_hatched & __BIT(cpuindex))
+			if (cpu_hatched_p(cpuindex))
 				break;
 		}
 		if (n == 0) {

Index: src/sys/arch/arm/vexpress/vexpress_platform.c
diff -u src/sys/arch/arm/vexpress/vexpress_platform.c:1.15 src/sys/arch/arm/vexpress/vexpress_platform.c:1.16
--- src/sys/arch/arm/vexpress/vexpress_platform.c:1.15	Tue Jul 23 12:34:47 2019
+++ src/sys/arch/arm/vexpress/vexpress_platform.c	Sat Feb 15 08:16:12 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: vexpress_platform.c,v 1.15 2019/07/23 12:34:47 jmcneill Exp $ */
+/* $NetBSD: vexpress_platform.c,v 1.16 2020/02/15 08:16:12 skrll Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -30,7 +30,7 @@
 #include "opt_console.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vexpress_platform.c,v 1.15 2019/07/23 12:34:47 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vexpress_platform.c,v 1.16 2020/02/15 08:16:12 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -120,11 +120,6 @@ vexpress_a15_smp_init(void)
 #ifdef MULTIPROCESSOR
 	bus_space_tag_t gicd_bst = &armv7_generic_bs_tag;
 	bus_space_handle_t gicd_bsh;
-	int started = 0;
-
-	/* Bitmask of CPUs (non-BSP) to start */
-	for (int i = 1; i < arm_cpu_max; i++)
-		started |= __BIT(i);
 
 	/* Write init vec to SYS_FLAGS register */
 	SYSREG_WRITE(SYS_FLAGSCLR, 0xffffffff);
@@ -142,16 +137,19 @@ vexpress_a15_smp_init(void)
 	const uint32_t sgir = GICD_SGIR_TargetListFilter_NotMe;
 	bus_space_write_4(gicd_bst, gicd_bsh, GICD_SGIR, sgir);
 
-	/* Wait for APs to start */
-	u_int i;
-	for (i = 0x10000000; i > 0; i--) {
-		arm_dmb();
-		if (arm_cpu_hatched == started)
-			break;
-	}
-	if (i == 0) {
-		aprint_error("WARNING: AP failed to start\n");
-		ret++;
+	/* Bitmask of CPUs (non-BSP) to start */
+	for (u_int cpuindex = 1; cpuindex < arm_cpu_max; cpuindex++) {
+		u_int i;
+		for (i = 0x10000000; i > 0; i--) {
+			if (cpu_hatched_p(cpuindex))
+				break;
+		}
+
+		if (i == 0) {
+			ret++;
+			aprint_error("cpu%d: WARNING: AP failed to start\n",
+			    cpuindex);
+		}
 	}
 
 	/* Disable GIC distributor */

Index: src/sys/arch/evbarm/bcm53xx/bcm53xx_machdep.c
diff -u src/sys/arch/evbarm/bcm53xx/bcm53xx_machdep.c:1.22 src/sys/arch/evbarm/bcm53xx/bcm53xx_machdep.c:1.23
--- src/sys/arch/evbarm/bcm53xx/bcm53xx_machdep.c:1.22	Mon Jan 20 22:25:07 2020
+++ src/sys/arch/evbarm/bcm53xx/bcm53xx_machdep.c	Sat Feb 15 08:16:12 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm53xx_machdep.c,v 1.22 2020/01/20 22:25:07 skrll Exp $	*/
+/*	$NetBSD: bcm53xx_machdep.c,v 1.23 2020/02/15 08:16:12 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #define IDM_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm53xx_machdep.c,v 1.22 2020/01/20 22:25:07 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm53xx_machdep.c,v 1.23 2020/02/15 08:16:12 skrll Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_console.h"
@@ -255,7 +255,7 @@ bcm53xx_mpstart(void)
 				break;
 	}
 	for (size_t i = 1; i < arm_cpu_max; i++) {
-		if ((arm_cpu_hatched & __BIT(i)) == 0) {
+		if (cpu_hatched_p(i)) {)
 			printf("%s: warning: cpu%zu failed to hatch\n",
 			    __func__, i);
 		}

Index: src/sys/arch/evbarm/beagle/beagle_machdep.c
diff -u src/sys/arch/evbarm/beagle/beagle_machdep.c:1.81 src/sys/arch/evbarm/beagle/beagle_machdep.c:1.82
--- src/sys/arch/evbarm/beagle/beagle_machdep.c:1.81	Mon Jan 20 22:25:07 2020
+++ src/sys/arch/evbarm/beagle/beagle_machdep.c	Sat Feb 15 08:16:12 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: beagle_machdep.c,v 1.81 2020/01/20 22:25:07 skrll Exp $ */
+/*	$NetBSD: beagle_machdep.c,v 1.82 2020/02/15 08:16:12 skrll Exp $ */
 
 /*
  * Machine dependent functions for kernel setup for TI OSK5912 board.
@@ -125,7 +125,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: beagle_machdep.c,v 1.81 2020/01/20 22:25:07 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: beagle_machdep.c,v 1.82 2020/02/15 08:16:12 skrll Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_console.h"
@@ -487,25 +487,26 @@ beagle_mpstart(void)
 	arm_dsb();
 	__asm __volatile("sev" ::: "memory");
 
-	for (int loop = 0; loop < 16; loop++) {
-		VPRINTF("%u hatched %#x\n", loop, arm_cpu_hatched);
-		if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1))
-			break;
-		int timo = 1500000;
-		while (arm_cpu_hatched != __BITS(arm_cpu_max - 1, 1))
-			if (--timo == 0)
+	u_int hatched = 0;
+	for (u_int cpuindex = 1; cpuindex < arm_cpu_max; cpuindex++) {
+		/* Wait for AP to start */
+		u_int i;
+		for (i = 1500000; i > 0; i--) {
+			if (cpu_hatched_p(cpuindex)) {
+				hatched |= __BIT(cpuindex);
 				break;
-	}
-	for (size_t i = 1; i < arm_cpu_max; i++) {
-		if ((arm_cpu_hatched & __BIT(i)) == 0) {
-			printf("%s: warning: cpu%zu failed to hatch\n",
-			    __func__, i);
+			}
 		}
+
+		if (i == 0) {
+			aprint_error("cpu%d: WARNING: AP failed to start\n", cpuindex);
+		}
+
+		cpuindex++;
 	}
 
-	VPRINTF(" (%u cpu%s, hatched %#x)",
-	    arm_cpu_max, arm_cpu_max ? "s" : "",
-	    arm_cpu_hatched);
+	VPRINTF(" (%u cpu%s, hatched %#x)", arm_cpu_max,
+	    arm_cpu_max ? "s" : "", hatched);
 #endif
 }
 

Index: src/sys/arch/evbarm/gumstix/gumstix_machdep.c
diff -u src/sys/arch/evbarm/gumstix/gumstix_machdep.c:1.64 src/sys/arch/evbarm/gumstix/gumstix_machdep.c:1.65
--- src/sys/arch/evbarm/gumstix/gumstix_machdep.c:1.64	Mon Jan 20 22:25:07 2020
+++ src/sys/arch/evbarm/gumstix/gumstix_machdep.c	Sat Feb 15 08:16:12 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: gumstix_machdep.c,v 1.64 2020/01/20 22:25:07 skrll Exp $ */
+/*	$NetBSD: gumstix_machdep.c,v 1.65 2020/02/15 08:16:12 skrll Exp $ */
 /*
  * Copyright (C) 2005, 2006, 2007  WIDE Project and SOUM Corporation.
  * All rights reserved.
@@ -545,7 +545,7 @@ gumstix_mpstart(void)
 				break;
 	}
 	for (size_t i = 1; i < arm_cpu_max; i++) {
-		if ((arm_cpu_hatched & __BIT(i)) == 0) {
+		if (cpu_hatched_p(i)) {
 			printf("%s: warning: cpu%zu failed to hatch\n",
 			    __func__, i);
 		}

Index: src/sys/arch/evbarm/imx7/imx7_machdep.c
diff -u src/sys/arch/evbarm/imx7/imx7_machdep.c:1.12 src/sys/arch/evbarm/imx7/imx7_machdep.c:1.13
--- src/sys/arch/evbarm/imx7/imx7_machdep.c:1.12	Mon Jan 20 22:25:07 2020
+++ src/sys/arch/evbarm/imx7/imx7_machdep.c	Sat Feb 15 08:16:12 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx7_machdep.c,v 1.12 2020/01/20 22:25:07 skrll Exp $	*/
+/*	$NetBSD: imx7_machdep.c,v 1.13 2020/02/15 08:16:12 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx7_machdep.c,v 1.12 2020/01/20 22:25:07 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx7_machdep.c,v 1.13 2020/02/15 08:16:12 skrll Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_arm_debug.h"
@@ -209,25 +209,24 @@ imx7_mpstart(void)
 	arm_dsb();
 	__asm __volatile("sev" ::: "memory");
 
-	for (int loop = 0; loop < 16; loop++) {
-		VPRINTF("%u hatched %#x\n", loop, arm_cpu_hatched);
-		if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1))
-			break;
-		int timo = 1500000;
-		while (arm_cpu_hatched != __BITS(arm_cpu_max - 1, 1))
-			if (--timo == 0)
+	u_int hatched = 0;
+	for (u_int cpuindex = 1; cpuindex < arm_cpu_max; cpuindex++) {
+		u_int i;
+		for (i = 1500000; i > 0; i--) {
+			if (cpu_hatched_p(cpuindex)) {
+				hatched |= __BIT(cpuindex);
 				break;
-	}
-	for (size_t i = 1; i < arm_cpu_max; i++) {
-		if ((arm_cpu_hatched & __BIT(i)) == 0) {
-			printf("%s: warning: cpu%zu failed to hatch\n",
-			    __func__, i);
+			}
+		}
+
+		if (i == 0) {
+			aprint_error("cpu%d: WARNING: AP failed to start\n",
+			    cpuindex);
 		}
 	}
 
 	VPRINTF(" (%u cpu%s, hatched %#x)",
-	    arm_cpu_max, arm_cpu_max ? "s" : "",
-	    arm_cpu_hatched);
+	    arm_cpu_max, arm_cpu_max ? "s" : "", hatched);
 #endif
 }
 
@@ -292,11 +291,6 @@ initarm(void *arg)
 
 #ifdef VERBOSE_INIT_ARM
 	printf("initarm: Configuring system");
-#ifdef MULTIPROCESSOR
-	printf(" (%u cpu%s, hatched %#x)",
-	    arm_cpu_max, arm_cpu_max ? "s" : "",
-	    arm_cpu_hatched);
-#endif /* MULTIPROCESSOR */
 	printf(", CLIDR=%010o CTR=%#x",
 	    armreg_clidr_read(), armreg_ctr_read());
 	printf("\n");

Index: src/sys/arch/evbarm/nitrogen6/nitrogen6_machdep.c
diff -u src/sys/arch/evbarm/nitrogen6/nitrogen6_machdep.c:1.19 src/sys/arch/evbarm/nitrogen6/nitrogen6_machdep.c:1.20
--- src/sys/arch/evbarm/nitrogen6/nitrogen6_machdep.c:1.19	Mon Jan 20 22:25:07 2020
+++ src/sys/arch/evbarm/nitrogen6/nitrogen6_machdep.c	Sat Feb 15 08:16:12 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nitrogen6_machdep.c,v 1.19 2020/01/20 22:25:07 skrll Exp $	*/
+/*	$NetBSD: nitrogen6_machdep.c,v 1.20 2020/02/15 08:16:12 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nitrogen6_machdep.c,v 1.19 2020/01/20 22:25:07 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nitrogen6_machdep.c,v 1.20 2020/02/15 08:16:12 skrll Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_arm_debug.h"
@@ -234,27 +234,29 @@ nitrogen6_mpstart(void)
 	    AIPS1_SRC_BASE + SRC_SCR, srcctl);
 
 	arm_dsb();
+	/* Wake up AP in case firmware has placed it in WFE state */
 	__asm __volatile("sev" ::: "memory");
 
-	for (int loop = 0; loop < 16; loop++) {
-		VPRINTF("%u hatched %#x\n", loop, arm_cpu_hatched);
-		if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1))
-			break;
-		int timo = 1500000;
-		while (arm_cpu_hatched != __BITS(arm_cpu_max - 1, 1))
-			if (--timo == 0)
+	u_int hatched = 0;
+	for (u_int cpuindex = 1; cpuindex < arm_cpu_max; cpuindex++) {
+		/* Wait for AP to start */
+		u_int i;
+		for (i = 1500000; i > 0; i--) {
+			if (cpu_hatched_p(cpuindex)) {
+				hatched |= __BIT(cpuindex);
 				break;
-	}
-	for (size_t i = 1; i < arm_cpu_max; i++) {
-		if ((arm_cpu_hatched & __BIT(i)) == 0) {
-			printf("%s: warning: cpu%zu failed to hatch\n",
-			    __func__, i);
+			}
+		}
+
+		if (i == 0) {
+			aprint_error("cpu%d: WARNING: AP failed to start\n", cpuindex);
 		}
+
+		cpuindex++;
 	}
 
-	VPRINTF(" (%u cpu%s, hatched %#x)",
-	    arm_cpu_max, arm_cpu_max ? "s" : "",
-	    arm_cpu_hatched);
+	VPRINTF(" (%u cpu%s, hatched %#x)", arm_cpu_max,
+	    arm_cpu_max ? "s" : "", hatched);
 #endif /* MULTIPROCESSOR */
 }
 
@@ -324,11 +326,6 @@ initarm(void *arg)
 
 #ifdef VERBOSE_INIT_ARM
 	printf("initarm: Configuring system");
-#ifdef MULTIPROCESSOR
-	printf(" (%u cpu%s, hatched %#x)",
-	    arm_cpu_max, arm_cpu_max ? "s" : "",
-	    arm_cpu_hatched);
-#endif /* MULTIPROCESSOR */
 	printf(", CLIDR=%010o CTR=%#x",
 	    armreg_clidr_read(), armreg_ctr_read());
 	printf("\n");

Index: src/sys/arch/evbarm/zynq/zynq_machdep.c
diff -u src/sys/arch/evbarm/zynq/zynq_machdep.c:1.11 src/sys/arch/evbarm/zynq/zynq_machdep.c:1.12
--- src/sys/arch/evbarm/zynq/zynq_machdep.c:1.11	Tue Jul 16 14:41:48 2019
+++ src/sys/arch/evbarm/zynq/zynq_machdep.c	Sat Feb 15 08:16:12 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: zynq_machdep.c,v 1.11 2019/07/16 14:41:48 skrll Exp $	*/
+/*	$NetBSD: zynq_machdep.c,v 1.12 2020/02/15 08:16:12 skrll Exp $	*/
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: zynq_machdep.c,v 1.11 2019/07/16 14:41:48 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: zynq_machdep.c,v 1.12 2020/02/15 08:16:12 skrll Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_arm_debug.h"
@@ -234,7 +234,7 @@ zynq_mpstart(void)
 				break;
 	}
 	for (size_t i = 1; i < arm_cpu_max; i++) {
-		if ((arm_cpu_hatched & __BIT(i)) == 0) {
+		if (cpu_hatched_p(i)) {
 			ret++;
 			printf("%s: warning: cpu%zu failed to hatch\n",
 			    __func__, i);

Added files:

Index: src/sys/arch/arm/arm/cpu_subr.c
diff -u /dev/null src/sys/arch/arm/arm/cpu_subr.c:1.1
--- /dev/null	Sat Feb 15 08:16:13 2020
+++ src/sys/arch/arm/arm/cpu_subr.c	Sat Feb 15 08:16:10 2020
@@ -0,0 +1,142 @@
+/*	$NetBSD: cpu_subr.c,v 1.1 2020/02/15 08:16:10 skrll Exp $	*/
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_cputypes.h"
+#include "opt_multiprocessor.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.1 2020/02/15 08:16:10 skrll Exp $");
+
+#include <sys/param.h>
+#include <sys/atomic.h>
+#include <sys/cpu.h>
+#include <sys/reboot.h>
+
+#ifdef VERBOSE_INIT_ARM
+#define VPRINTF(...)	printf(__VA_ARGS__)
+#else
+#define VPRINTF(...)	__nothing
+#endif
+
+#ifdef MULTIPROCESSOR
+#define NCPUINFO	MAXCPUS
+#else
+#define NCPUINFO	1
+#endif /* MULTIPROCESSOR */
+
+mpidr_t cpu_mpidr[NCPUINFO] = {
+	[0 ... NCPUINFO - 1] = ~0,
+};
+
+struct cpu_info *cpu_info[NCPUINFO] __read_mostly = {
+	[0] = &cpu_info_store[0]
+};
+
+#ifdef MULTIPROCESSOR
+
+#define	CPUINDEX_DIVISOR	(sizeof(u_long) * NBBY)
+
+volatile u_long arm_cpu_hatched[howmany(MAXCPUS, CPUINDEX_DIVISOR)] __cacheline_aligned = { 0 };
+volatile u_long arm_cpu_mbox[howmany(MAXCPUS, CPUINDEX_DIVISOR)] __cacheline_aligned = { 0 };
+u_int arm_cpu_max = 1;
+
+kmutex_t cpu_hatch_lock;
+
+void
+cpu_boot_secondary_processors(void)
+{
+	u_int cpuno;
+
+	if ((boothowto & RB_MD1) != 0)
+		return;
+
+	mutex_init(&cpu_hatch_lock, MUTEX_DEFAULT, IPL_NONE);
+
+	VPRINTF("%s: starting secondary processors\n", __func__);
+
+	/* send mbox to have secondary processors do cpu_hatch() */
+	for (size_t n = 0; n < __arraycount(arm_cpu_mbox); n++)
+		atomic_or_ulong(&arm_cpu_mbox[n], arm_cpu_hatched[n]);
+
+	__asm __volatile ("sev; sev; sev");
+
+	/* wait all cpus have done cpu_hatch() */
+	for (cpuno = 1; cpuno < ncpu; cpuno++) {
+		if (!cpu_hatched_p(cpuno))
+			continue;
+
+		const size_t off = cpuno / CPUINDEX_DIVISOR;
+		const u_long bit = __BIT(cpuno % CPUINDEX_DIVISOR);
+
+		while (membar_consumer(), arm_cpu_mbox[off] & bit) {
+			__asm __volatile ("wfe");
+		}
+		/* Add processor to kcpuset */
+		kcpuset_set(kcpuset_attached, cpuno);
+	}
+
+	VPRINTF("%s: secondary processors hatched\n", __func__);
+}
+
+bool
+cpu_hatched_p(u_int cpuindex)
+{
+	const u_int off = cpuindex / CPUINDEX_DIVISOR;
+	const u_int bit = cpuindex % CPUINDEX_DIVISOR;
+
+	membar_consumer();
+	return (arm_cpu_hatched[off] & __BIT(bit)) != 0;
+}
+
+void
+cpu_set_hatched(int cpuindex)
+{
+
+	const size_t off = cpuindex / CPUINDEX_DIVISOR;
+	const u_long bit = __BIT(cpuindex % CPUINDEX_DIVISOR);
+
+	atomic_or_ulong(&arm_cpu_hatched[off], bit);
+}
+
+void
+cpu_clr_mbox(int cpuindex)
+{
+
+	const size_t off = cpuindex / CPUINDEX_DIVISOR;
+	const u_long bit = __BIT(cpuindex % CPUINDEX_DIVISOR);
+
+	/* Notify cpu_boot_secondary_processors that we're done */
+	atomic_and_ulong(&arm_cpu_mbox[off], ~bit);
+	membar_producer();
+	__asm __volatile("sev; sev; sev");
+}
+
+#endif

Index: src/sys/arch/arm/include/cpuvar.h
diff -u /dev/null src/sys/arch/arm/include/cpuvar.h:1.1
--- /dev/null	Sat Feb 15 08:16:13 2020
+++ src/sys/arch/arm/include/cpuvar.h	Sat Feb 15 08:16:11 2020
@@ -0,0 +1,43 @@
+/*	$NetBSD: cpuvar.h,v 1.1 2020/02/15 08:16:11 skrll Exp $	*/
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ARM_CPUVAR_H_
+#define _ARM_CPUVAR_H_
+
+#ifdef _KERNEL
+
+#include <sys/device_if.h>
+
+void	cpu_attach(device_t, cpuid_t);
+
+#endif
+
+#endif

Reply via email to