xref: /netbsd/sys/arch/arm/arm/cpu_subr.c (revision 4cbb6682)
1*4cbb6682Sriastradh /*	$NetBSD: cpu_subr.c,v 1.5 2021/11/14 16:56:32 riastradh Exp $	*/
2483c6a3dSskrll 
3483c6a3dSskrll /*-
4483c6a3dSskrll  * Copyright (c) 2020 The NetBSD Foundation, Inc.
5483c6a3dSskrll  * All rights reserved.
6483c6a3dSskrll  *
7483c6a3dSskrll  * This code is derived from software contributed to The NetBSD Foundation
8483c6a3dSskrll  * by Nick Hudson
9483c6a3dSskrll  *
10483c6a3dSskrll  * Redistribution and use in source and binary forms, with or without
11483c6a3dSskrll  * modification, are permitted provided that the following conditions
12483c6a3dSskrll  * are met:
13483c6a3dSskrll  * 1. Redistributions of source code must retain the above copyright
14483c6a3dSskrll  *    notice, this list of conditions and the following disclaimer.
15483c6a3dSskrll  * 2. Redistributions in binary form must reproduce the above copyright
16483c6a3dSskrll  *    notice, this list of conditions and the following disclaimer in the
17483c6a3dSskrll  *    documentation and/or other materials provided with the distribution.
18483c6a3dSskrll  *
19483c6a3dSskrll  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20483c6a3dSskrll  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21483c6a3dSskrll  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22483c6a3dSskrll  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23483c6a3dSskrll  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24483c6a3dSskrll  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25483c6a3dSskrll  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26483c6a3dSskrll  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27483c6a3dSskrll  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28483c6a3dSskrll  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29483c6a3dSskrll  * POSSIBILITY OF SUCH DAMAGE.
30483c6a3dSskrll  */
31483c6a3dSskrll 
32483c6a3dSskrll #include "opt_cputypes.h"
33483c6a3dSskrll #include "opt_multiprocessor.h"
34483c6a3dSskrll 
35483c6a3dSskrll #include <sys/cdefs.h>
36*4cbb6682Sriastradh __KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.5 2021/11/14 16:56:32 riastradh Exp $");
37483c6a3dSskrll 
38483c6a3dSskrll #include <sys/param.h>
39483c6a3dSskrll #include <sys/atomic.h>
40483c6a3dSskrll #include <sys/cpu.h>
41483c6a3dSskrll #include <sys/reboot.h>
42483c6a3dSskrll 
43a15683c1Sskrll #include <arm/cpufunc.h>
44a15683c1Sskrll 
45483c6a3dSskrll #ifdef VERBOSE_INIT_ARM
46483c6a3dSskrll #define VPRINTF(...)	printf(__VA_ARGS__)
47483c6a3dSskrll #else
48483c6a3dSskrll #define VPRINTF(...)	__nothing
49483c6a3dSskrll #endif
50483c6a3dSskrll 
51483c6a3dSskrll #ifdef MULTIPROCESSOR
52483c6a3dSskrll #define NCPUINFO	MAXCPUS
53483c6a3dSskrll #else
54483c6a3dSskrll #define NCPUINFO	1
55483c6a3dSskrll #endif /* MULTIPROCESSOR */
56483c6a3dSskrll 
57483c6a3dSskrll mpidr_t cpu_mpidr[NCPUINFO] = {
58483c6a3dSskrll 	[0 ... NCPUINFO - 1] = ~0,
59483c6a3dSskrll };
60483c6a3dSskrll 
61483c6a3dSskrll struct cpu_info *cpu_info[NCPUINFO] __read_mostly = {
62483c6a3dSskrll 	[0] = &cpu_info_store[0]
63483c6a3dSskrll };
64483c6a3dSskrll 
65483c6a3dSskrll #ifdef MULTIPROCESSOR
66483c6a3dSskrll 
67483c6a3dSskrll #define	CPUINDEX_DIVISOR	(sizeof(u_long) * NBBY)
68483c6a3dSskrll 
69483c6a3dSskrll volatile u_long arm_cpu_hatched[howmany(MAXCPUS, CPUINDEX_DIVISOR)] __cacheline_aligned = { 0 };
70483c6a3dSskrll volatile u_long arm_cpu_mbox[howmany(MAXCPUS, CPUINDEX_DIVISOR)] __cacheline_aligned = { 0 };
71483c6a3dSskrll u_int arm_cpu_max = 1;
72483c6a3dSskrll 
73483c6a3dSskrll void
cpu_boot_secondary_processors(void)74483c6a3dSskrll cpu_boot_secondary_processors(void)
75483c6a3dSskrll {
76483c6a3dSskrll 	u_int cpuno;
77483c6a3dSskrll 
78483c6a3dSskrll 	if ((boothowto & RB_MD1) != 0)
79483c6a3dSskrll 		return;
80483c6a3dSskrll 
81483c6a3dSskrll 	VPRINTF("%s: starting secondary processors\n", __func__);
82483c6a3dSskrll 
83483c6a3dSskrll 	/* send mbox to have secondary processors do cpu_hatch() */
84*4cbb6682Sriastradh 	dmb(ish);	/* store-release matches locore.S/armv6_start.S */
85483c6a3dSskrll 	for (size_t n = 0; n < __arraycount(arm_cpu_mbox); n++)
86483c6a3dSskrll 		atomic_or_ulong(&arm_cpu_mbox[n], arm_cpu_hatched[n]);
87483c6a3dSskrll 
88a15683c1Sskrll 	dsb(ishst);
890ef099a7Sskrll 	sev();
90483c6a3dSskrll 
91483c6a3dSskrll 	/* wait all cpus have done cpu_hatch() */
92483c6a3dSskrll 	for (cpuno = 1; cpuno < ncpu; cpuno++) {
93483c6a3dSskrll 		if (!cpu_hatched_p(cpuno))
94483c6a3dSskrll 			continue;
95483c6a3dSskrll 
96483c6a3dSskrll 		const size_t off = cpuno / CPUINDEX_DIVISOR;
97483c6a3dSskrll 		const u_long bit = __BIT(cpuno % CPUINDEX_DIVISOR);
98483c6a3dSskrll 
99*4cbb6682Sriastradh 		/* load-acquire matches cpu_clr_mbox */
100*4cbb6682Sriastradh 		while (atomic_load_acquire(&arm_cpu_mbox[off]) & bit) {
101483c6a3dSskrll 			__asm __volatile ("wfe");
102483c6a3dSskrll 		}
103483c6a3dSskrll 		/* Add processor to kcpuset */
104483c6a3dSskrll 		kcpuset_set(kcpuset_attached, cpuno);
105483c6a3dSskrll 	}
106483c6a3dSskrll 
107483c6a3dSskrll 	VPRINTF("%s: secondary processors hatched\n", __func__);
108483c6a3dSskrll }
109483c6a3dSskrll 
110483c6a3dSskrll bool
cpu_hatched_p(u_int cpuindex)111483c6a3dSskrll cpu_hatched_p(u_int cpuindex)
112483c6a3dSskrll {
113483c6a3dSskrll 	const u_int off = cpuindex / CPUINDEX_DIVISOR;
114483c6a3dSskrll 	const u_int bit = cpuindex % CPUINDEX_DIVISOR;
115483c6a3dSskrll 
116*4cbb6682Sriastradh 	/* load-acquire matches cpu_set_hatched */
117*4cbb6682Sriastradh 	return (atomic_load_acquire(&arm_cpu_hatched[off]) & __BIT(bit)) != 0;
118483c6a3dSskrll }
119483c6a3dSskrll 
120483c6a3dSskrll void
cpu_set_hatched(int cpuindex)121483c6a3dSskrll cpu_set_hatched(int cpuindex)
122483c6a3dSskrll {
123483c6a3dSskrll 
124483c6a3dSskrll 	const size_t off = cpuindex / CPUINDEX_DIVISOR;
125483c6a3dSskrll 	const u_long bit = __BIT(cpuindex % CPUINDEX_DIVISOR);
126483c6a3dSskrll 
127*4cbb6682Sriastradh 	dmb(ish);		/* store-release matches cpu_hatched_p */
128483c6a3dSskrll 	atomic_or_ulong(&arm_cpu_hatched[off], bit);
1290ab152a3Sskrll 	dsb(ishst);
1300ab152a3Sskrll 	sev();
131483c6a3dSskrll }
132483c6a3dSskrll 
133483c6a3dSskrll void
cpu_clr_mbox(int cpuindex)134483c6a3dSskrll cpu_clr_mbox(int cpuindex)
135483c6a3dSskrll {
136483c6a3dSskrll 
137483c6a3dSskrll 	const size_t off = cpuindex / CPUINDEX_DIVISOR;
138483c6a3dSskrll 	const u_long bit = __BIT(cpuindex % CPUINDEX_DIVISOR);
139483c6a3dSskrll 
140483c6a3dSskrll 	/* Notify cpu_boot_secondary_processors that we're done */
141*4cbb6682Sriastradh 	dmb(ish);		/* store-release */
142483c6a3dSskrll 	atomic_and_ulong(&arm_cpu_mbox[off], ~bit);
143a15683c1Sskrll 	dsb(ishst);
1440ef099a7Sskrll 	sev();
145483c6a3dSskrll }
146483c6a3dSskrll 
147483c6a3dSskrll #endif
148