xref: /netbsd-src/sys/arch/mips/rmi/rmixl_cpucore.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1 /*	$NetBSD: rmixl_cpucore.c,v 1.7 2021/08/07 16:18:59 thorpej Exp $	*/
2 
3 /*
4  * Copyright 2002 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Simon Burge for Wasabi Systems, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed for the NetBSD Project by
20  *      Wasabi Systems, Inc.
21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include "locators.h"
39 
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: rmixl_cpucore.c,v 1.7 2021/08/07 16:18:59 thorpej Exp $");
42 
43 #include "opt_multiprocessor.h"
44 
45 #include <sys/param.h>
46 #include <sys/device.h>
47 #include <sys/systm.h>
48 #include <sys/cpu.h>
49 
50 #include <uvm/uvm_extern.h>
51 
52 #include <mips/rmi/rmixlvar.h>
53 #include <mips/rmi/rmixl_cpunodevar.h>
54 #include <mips/rmi/rmixl_cpucorevar.h>
55 #include <mips/rmi/rmixl_fmnvar.h>
56 
57 static int	cpucore_rmixl_match(device_t, cfdata_t, void *);
58 static void	cpucore_rmixl_attach(device_t, device_t, void *);
59 static int	cpucore_rmixl_print(void *, const char *);
60 
61 CFATTACH_DECL_NEW(cpucore_rmixl, sizeof(struct cpucore_softc),
62 	cpucore_rmixl_match, cpucore_rmixl_attach, NULL, NULL);
63 
64 static int
cpucore_rmixl_match(device_t parent,cfdata_t cf,void * aux)65 cpucore_rmixl_match(device_t parent, cfdata_t cf, void *aux)
66 {
67 	struct cpunode_attach_args *na = aux;
68 	int core = cf->cf_loc[CPUNODECF_CORE];
69 
70 	if (!cpu_rmixl(mips_options.mips_cpu))
71 		return 0;
72 
73 	if (strncmp(na->na_name, cf->cf_name, strlen(cf->cf_name)) == 0
74 #ifndef MULTIPROCESSOR
75 	    && na->na_core == 0
76 #endif
77 	    && (core == CPUNODECF_CORE_DEFAULT || core == na->na_core))
78 		return 1;
79 
80 	return 0;
81 }
82 
83 static void
cpucore_rmixl_attach(device_t parent,device_t self,void * aux)84 cpucore_rmixl_attach(device_t parent, device_t self, void *aux)
85 {
86 	struct cpucore_softc * const sc = device_private(self);
87 	struct cpunode_attach_args *na = aux;
88 	struct cpucore_attach_args ca;
89 	u_int nthreads;
90 	struct rmixl_config *rcp = &rmixl_configuration;
91 
92 	sc->sc_dev = self;
93 	sc->sc_core = na->na_core;
94 	KASSERT(sc->sc_hatched == false);
95 
96 #if 0
97 #ifdef MULTIPROCESSOR
98 	/*
99 	 * Create the TLB structure needed - one per core and core0 uses the
100 	 * default one for the system.
101 	 */
102 	if (sc->sc_core == 0) {
103 		sc->sc_tlbinfo = &pmap_tlb0_info;
104 	} else {
105 		const vaddr_t va = (vaddr_t)&sc->sc_tlbinfo0;
106 		paddr_t pa;
107 
108 		if (! pmap_extract(pmap_kernel(), va, &pa))
109 			panic("%s: pmap_extract fail, va %#"PRIxVADDR, __func__, va);
110 #ifdef _LP64
111 		sc->sc_tlbinfo = (struct pmap_tlb_info *)
112 			MIPS_PHYS_TO_XKPHYS_CACHED(pa);
113 #else
114 		sc->sc_tlbinfo = (struct pmap_tlb_info *)
115 			MIPS_PHYS_TO_KSEG0(pa);
116 #endif
117 		pmap_tlb_info_init(sc->sc_tlbinfo);
118 	}
119 #endif
120 #endif
121 
122 	aprint_normal("\n");
123 	aprint_normal_dev(self, "%lu.%02luMHz (hz cycles = %lu, "
124 	    "delay divisor = %lu)\n",
125 	    curcpu()->ci_cpu_freq / 1000000,
126 	    (curcpu()->ci_cpu_freq % 1000000) / 10000,
127 	    curcpu()->ci_cycles_per_hz, curcpu()->ci_divisor_delay);
128 
129 	aprint_normal("%s: ", device_xname(self));
130 	cpu_identify(self);
131 
132 	nthreads = MIPS_CIDFL_RMI_NTHREADS(mips_options.mips_cpu->cpu_cidflags);
133 	aprint_normal_dev(self, "%d %s on core\n", nthreads,
134 		nthreads == 1 ? "thread" : "threads");
135 
136 	/*
137 	 * Attach CPU (RMI thread contexts) devices
138 	 * according to userapp_cpu_map bitmask.
139 	 */
140 	u_int thread_mask = (1 << nthreads) - 1;
141 	u_int core_shft = sc->sc_core * nthreads;
142 	u_int threads_enb =
143 		(u_int)(rcp->rc_psb_info.userapp_cpu_map >> core_shft) & thread_mask;
144 	u_int threads_dis = (~threads_enb) & thread_mask;
145 
146 	sc->sc_threads_dis = threads_dis;
147 	if (threads_dis != 0) {
148 		aprint_normal_dev(self, "threads");
149 		u_int d = threads_dis;
150 		while (d != 0) {
151 			const u_int t = ffs(d) - 1;
152 			d ^= (1 << t);
153 			aprint_normal(" %d%s", t, (d==0) ? "" : ",");
154 		}
155 		aprint_normal(" offline (disabled by firmware)\n");
156 	}
157 
158 	u_int threads_try_attach = threads_enb;
159 	while (threads_try_attach != 0) {
160 		const u_int t = ffs(threads_try_attach) - 1;
161 		const u_int bit = 1 << t;
162 		threads_try_attach ^= bit;
163 		ca.ca_name = "cpu";
164 		ca.ca_thread = t;
165 		ca.ca_core = sc->sc_core;
166 		if (config_found(self, &ca, cpucore_rmixl_print,
167 				 CFARGS_NONE) == NULL) {
168 			/*
169 			 * thread did not attach, e.g. not configured
170 			 * arrange to have it disabled in THREADEN PCR
171 			 */
172 			threads_enb ^= bit;
173 			threads_dis |= bit;
174 		}
175 	}
176 
177 	sc->sc_threads_enb = threads_enb;
178 	sc->sc_threads_dis = threads_dis;
179 
180 	/*
181 	 * when attaching the core of the primary cpu,
182 	 * do the post-running initialization here
183 	 */
184 	if (sc->sc_core == RMIXL_CPU_CORE((curcpu()->ci_cpuid)))
185 		cpucore_rmixl_run(self);
186 }
187 
188 static int
cpucore_rmixl_print(void * aux,const char * pnp)189 cpucore_rmixl_print(void *aux, const char *pnp)
190 {
191 	struct cpucore_attach_args *ca = aux;
192 
193 	if (pnp != NULL)
194 		aprint_normal("%s:", pnp);
195 	aprint_normal(" thread %d", ca->ca_thread);
196 
197 	return (UNCONF);
198 }
199 
200 /*
201  * cpucore_rmixl_run
202  *	called from cpucore_rmixl_attach for primary core
203  *	and called from cpu_rmixl_run for each hatched cpu
204  *	the first call for each cpucore causes init of per-core features:
205  *	- disable unused threads
206  *	- set Fine-grained (Round Robin) thread scheduling mode
207  */
208 void
cpucore_rmixl_run(device_t self)209 cpucore_rmixl_run(device_t self)
210 {
211 	struct cpucore_softc * const sc = device_private(self);
212 
213 	if (sc->sc_running == false) {
214 		sc->sc_running = true;
215 		rmixl_mtcr(RMIXL_PCR_THREADEN, sc->sc_threads_enb);
216 		rmixl_mtcr(RMIXL_PCR_SCHEDULING, 0);
217 	}
218 }
219 
220 #ifdef MULTIPROCESSOR
221 /*
222  * cpucore_rmixl_hatch
223  *	called from cpu_rmixl_hatch for each cpu
224  *	the first call for each cpucore causes init of per-core features
225  */
226 void
cpucore_rmixl_hatch(device_t self)227 cpucore_rmixl_hatch(device_t self)
228 {
229 	struct cpucore_softc * const sc = device_private(self);
230 
231 	if (sc->sc_hatched == false) {
232 		/* PCRs for core#0 are set up in mach_init() */
233 		if (sc->sc_core != 0)
234 			rmixl_pcr_init_core();
235 		rmixl_fmn_init_core();
236 		sc->sc_hatched = true;
237 	}
238 }
239 #endif	/* MULTIPROCESSOR */
240