1/*	$NetBSD: cpu.c,v 1.260 2021/05/29 02:58:37 mrg Exp $ */
2
3/*
4 * Copyright (c) 1996
5 *	The President and Fellows of Harvard College. All rights reserved.
6 * Copyright (c) 1992, 1993
7 *	The Regents of the University of California.  All rights reserved.
8 *
9 * This software was developed by the Computer Systems Engineering group
10 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
11 * contributed to Berkeley.
12 *
13 * All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 *	This product includes software developed by Harvard University.
16 *	This product includes software developed by the University of
17 *	California, Lawrence Berkeley Laboratory.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 *    notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 *    notice, this list of conditions and the following disclaimer in the
27 *    documentation and/or other materials provided with the distribution.
28 * 3. All advertising materials mentioning features or use of this software
29 *    must display the following acknowledgement:
30 *	This product includes software developed by Aaron Brown and
31 *	Harvard University.
32 *	This product includes software developed by the University of
33 *	California, Berkeley and its contributors.
34 * 4. Neither the name of the University nor the names of its contributors
35 *    may be used to endorse or promote products derived from this software
36 *    without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 *
50 *	@(#)cpu.c	8.5 (Berkeley) 11/23/93
51 *
52 */
53
54#include <sys/cdefs.h>
55__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.260 2021/05/29 02:58:37 mrg Exp $");
56
57#include "opt_multiprocessor.h"
58#include "opt_lockdebug.h"
59#include "opt_ddb.h"
60#include "opt_sparc_arch.h"
61
62#include <sys/param.h>
63#include <sys/systm.h>
64#include <sys/device.h>
65#include <sys/malloc.h>
66#include <sys/kernel.h>
67#include <sys/evcnt.h>
68#include <sys/xcall.h>
69#include <sys/ipi.h>
70#include <sys/cpu.h>
71#include <sys/reboot.h>
72#include <sys/sysctl.h>
73#include <sys/kmem.h>
74
75#include <uvm/uvm.h>
76
77#include <machine/promlib.h>
78#include <machine/autoconf.h>
79#include <machine/cpu.h>
80#include <machine/reg.h>
81#include <machine/ctlreg.h>
82#include <machine/trap.h>
83#include <machine/pcb.h>
84#include <machine/pmap.h>
85#include <machine/locore.h>
86
87#if defined(MULTIPROCESSOR) && defined(DDB)
88#include <ddb/db_output.h>
89#include <machine/db_machdep.h>
90#endif
91
92#include <sparc/sparc/cache.h>
93#include <sparc/sparc/asm.h>
94#include <sparc/sparc/cpuvar.h>
95#include <sparc/sparc/memreg.h>
96#include <sparc/sparc/cache_print.h>
97#if defined(SUN4D)
98#include <sparc/sparc/cpuunitvar.h>
99#endif
100
101#ifdef DEBUG
102#ifndef DEBUG_XCALL
103#define DEBUG_XCALL 0
104#endif
105int	debug_xcall = DEBUG_XCALL;
106#else
107#define debug_xcall 0
108#endif
109
110struct cpu_softc {
111	device_t sc_dev;
112	struct cpu_info	*sc_cpuinfo;
113};
114
115/* The following are used externally (sysctl_hw). */
116char	machine[] = MACHINE;		/* from <machine/param.h> */
117char	machine_arch[] = MACHINE_ARCH;	/* from <machine/param.h> */
118int	cpu_arch;			/* sparc architecture version */
119
120int	sparc_ncpus;			/* # of CPUs detected by PROM */
121struct cpu_info *cpus[_MAXNCPU+1];	/* we only support 4 CPUs. */
122
123/* The CPU configuration driver. */
124static void cpu_mainbus_attach(device_t, device_t, void *);
125int  cpu_mainbus_match(device_t, cfdata_t, void *);
126
127CFATTACH_DECL_NEW(cpu_mainbus, sizeof(struct cpu_softc),
128    cpu_mainbus_match, cpu_mainbus_attach, NULL, NULL);
129
130#if defined(SUN4D)
131static int cpu_cpuunit_match(device_t, cfdata_t, void *);
132static void cpu_cpuunit_attach(device_t, device_t, void *);
133
134CFATTACH_DECL_NEW(cpu_cpuunit, sizeof(struct cpu_softc),
135    cpu_cpuunit_match, cpu_cpuunit_attach, NULL, NULL);
136#endif /* SUN4D */
137
138static void cpu_setup_sysctl(struct cpu_softc *);
139static void cpu_init_evcnt(struct cpu_info *);
140static void cpu_attach(struct cpu_softc *, int, int);
141
142static const char *fsrtoname(int, int, int);
143static void cache_print(struct cpu_softc *);
144void cpu_setup(void);
145void fpu_init(struct cpu_info *);
146
147#define	IU_IMPL(psr)	((u_int)(psr) >> 28)
148#define	IU_VERS(psr)	(((psr) >> 24) & 0xf)
149
150#define SRMMU_IMPL(mmusr)	((u_int)(mmusr) >> 28)
151#define SRMMU_VERS(mmusr)	(((mmusr) >> 24) & 0xf)
152
153int bootmid;		/* Module ID of boot CPU */
154
155#ifdef notdef
156/*
157 * IU implementations are parceled out to vendors (with some slight
158 * glitches).  Printing these is cute but takes too much space.
159 */
160static char *iu_vendor[16] = {
161	"Fujitsu",	/* and also LSI Logic */
162	"ROSS",		/* ROSS (ex-Cypress) */
163	"BIT",
164	"LSIL",		/* LSI Logic finally got their own */
165	"TI",		/* Texas Instruments */
166	"Matsushita",
167	"Philips",
168	"Harvest",	/* Harvest VLSI Design Center */
169	"SPEC",		/* Systems and Processes Engineering Corporation */
170	"Weitek",
171	"vendor#10",
172	"vendor#11",
173	"vendor#12",
174	"vendor#13",
175	"vendor#14",
176	"vendor#15"
177};
178#endif
179
180#if defined(MULTIPROCESSOR)
181u_int	cpu_ready_mask;			/* the set of CPUs marked as READY */
182void cpu_spinup(struct cpu_info *);
183static void cpu_attach_non_boot(struct cpu_softc *, struct cpu_info *, int);
184
185int go_smp_cpus = 0;	/* non-primary CPUs wait for this to go */
186
187/*
188 * This must be locked around all message transactions to ensure only
189 * one CPU is generating them.
190 */
191kmutex_t xpmsg_mutex;
192
193#endif /* MULTIPROCESSOR */
194
195/*
196 * 4/110 comment: the 4/110 chops off the top 4 bits of an OBIO address.
197 *	this confuses autoconf.  for example, if you try and map
198 *	0xfe000000 in obio space on a 4/110 it actually maps 0x0e000000.
199 *	this is easy to verify with the PROM.   this causes problems
200 *	with devices like "esp0 at obio0 addr 0xfa000000" because the
201 *	4/110 treats it as esp0 at obio0 addr 0x0a000000" which is the
202 *	address of the 4/110's "sw0" scsi chip.   the same thing happens
203 *	between zs1 and zs2.    since the sun4 line is "closed" and
204 *	we know all the "obio" devices that will ever be on it we just
205 *	put in some special case "if"'s in the match routines of esp,
206 *	dma, and zs.
207 */
208
209int
210cpu_mainbus_match(device_t parent, cfdata_t cf, void *aux)
211{
212	struct mainbus_attach_args *ma = aux;
213
214	return (strcmp(cf->cf_name, ma->ma_name) == 0);
215}
216
217static void
218cpu_mainbus_attach(device_t parent, device_t self, void *aux)
219{
220	struct mainbus_attach_args *ma = aux;
221	struct { uint32_t va; uint32_t size; } *mbprop = NULL;
222	struct openprom_addr *rrp = NULL;
223	struct cpu_info *cpi;
224	struct cpu_softc *sc;
225	int mid, node;
226	int error, n;
227
228	node = ma->ma_node;
229	mid = (node != 0) ? prom_getpropint(node, "mid", 0) : 0;
230	sc = device_private(self);
231	sc->sc_dev = self;
232	cpu_attach(sc, node, mid);
233
234	cpi = sc->sc_cpuinfo;
235	if (cpi == NULL)
236		return;
237
238	/*
239	 * Map CPU mailbox if available
240	 */
241	if (node != 0 && (error = prom_getprop(node, "mailbox-virtual",
242					sizeof(*mbprop),
243					&n, &mbprop)) == 0) {
244		cpi->mailbox = mbprop->va;
245		free(mbprop, M_DEVBUF);
246	} else if (node != 0 && (error = prom_getprop(node, "mailbox",
247					sizeof(struct openprom_addr),
248					&n, &rrp)) == 0) {
249		/* XXX - map cached/uncached? If cached, deal with
250		 *	 cache congruency!
251		 */
252		if (rrp[0].oa_space == 0)
253			printf("%s: mailbox in mem space\n", device_xname(self));
254
255		if (bus_space_map(ma->ma_bustag,
256				BUS_ADDR(rrp[0].oa_space, rrp[0].oa_base),
257				rrp[0].oa_size,
258				BUS_SPACE_MAP_LINEAR,
259				&cpi->mailbox) != 0)
260			panic("%s: can't map CPU mailbox", device_xname(self));
261		free(rrp, M_DEVBUF);
262	}
263
264	/*
265	 * Map Module Control Space if available
266	 */
267	if (cpi->mxcc == 0)
268		/* We only know what it means on MXCCs */
269		return;
270
271	rrp = NULL;
272	if (node == 0 || (error = prom_getprop(node, "reg",
273					sizeof(struct openprom_addr),
274					&n, &rrp)) != 0)
275		return;
276
277	/* register set #0 is the MBus port register */
278	if (bus_space_map(ma->ma_bustag,
279			BUS_ADDR(rrp[0].oa_space, rrp[0].oa_base),
280			rrp[0].oa_size,
281			BUS_SPACE_MAP_LINEAR,
282			&cpi->ci_mbusport) != 0) {
283		panic("%s: can't map CPU regs", device_xname(self));
284	}
285	/* register set #1: MCXX control */
286	if (bus_space_map(ma->ma_bustag,
287			BUS_ADDR(rrp[1].oa_space, rrp[1].oa_base),
288			rrp[1].oa_size,
289			BUS_SPACE_MAP_LINEAR,
290			&cpi->ci_mxccregs) != 0) {
291		panic("%s: can't map CPU regs", device_xname(self));
292	}
293	/* register sets #3 and #4 are E$ cache data and tags */
294
295	free(rrp, M_DEVBUF);
296}
297
298#if defined(SUN4D)
299static int
300cpu_cpuunit_match(device_t parent, cfdata_t cf, void *aux)
301{
302	struct cpuunit_attach_args *cpua = aux;
303
304	return (strcmp(cf->cf_name, cpua->cpua_type) == 0);
305}
306
307static void
308cpu_cpuunit_attach(device_t parent, device_t self, void *aux)
309{
310	struct cpuunit_attach_args *cpua = aux;
311	struct cpu_softc *sc = device_private(self);
312
313	sc->sc_dev = self;
314	cpu_attach(sc, cpua->cpua_node, cpua->cpua_device_id);
315}
316#endif /* SUN4D */
317
318static const char * const hard_intr_names[] = {
319	"spur hard",
320	"lev1 hard",
321	"lev2 hard",
322	"lev3 hard",
323	"lev4 hard",
324	"lev5 hard",
325	"lev6 hard",
326	"lev7 hard",
327	"lev8 hard",
328	"lev9 hard",
329	"clock hard",
330	"lev11 hard",
331	"lev12 hard",
332	"lev13 hard",
333	"prof hard",
334	"nmi hard",
335};
336
337static const char * const soft_intr_names[] = {
338	"spur soft",
339	"lev1 soft",
340	"lev2 soft",
341	"lev3 soft",
342	"lev4 soft",
343	"lev5 soft",
344	"lev6 soft",
345	"lev7 soft",
346	"lev8 soft",
347	"lev9 soft",
348	"lev10 soft",
349	"lev11 soft",
350	"lev12 soft",
351	"xcall std",
352	"xcall fast",
353	"nmi soft",
354};
355
356static void
357cpu_init_evcnt(struct cpu_info *cpi)
358{
359	int i;
360
361	/*
362	 * Setup the per-cpu counters.
363	 *
364	 * The "savefp null" counter should go away when the NULL
365	 * struct fpstate * bug is fixed.
366	 */
367	evcnt_attach_dynamic(&cpi->ci_savefpstate, EVCNT_TYPE_INTR,
368			     NULL, cpu_name(cpi), "savefp ipi");
369	evcnt_attach_dynamic(&cpi->ci_savefpstate_null, EVCNT_TYPE_MISC,
370			     NULL, cpu_name(cpi), "savefp null ipi");
371	evcnt_attach_dynamic(&cpi->ci_xpmsg_mutex_fail, EVCNT_TYPE_MISC,
372			     NULL, cpu_name(cpi), "IPI mutex_trylock fail");
373	evcnt_attach_dynamic(&cpi->ci_xpmsg_mutex_fail_call, EVCNT_TYPE_MISC,
374			     NULL, cpu_name(cpi), "IPI mutex_trylock fail/call");
375	evcnt_attach_dynamic(&cpi->ci_xpmsg_mutex_not_held, EVCNT_TYPE_MISC,
376			     NULL, cpu_name(cpi), "IPI with mutex not held");
377	evcnt_attach_dynamic(&cpi->ci_xpmsg_bogus, EVCNT_TYPE_MISC,
378			     NULL, cpu_name(cpi), "bogus IPI");
379
380	/*
381	 * These are the per-cpu per-IPL hard & soft interrupt counters.
382	 */
383	for (i = 0; i < 16; i++) {
384		evcnt_attach_dynamic(&cpi->ci_intrcnt[i], EVCNT_TYPE_INTR,
385				     NULL, cpu_name(cpi), hard_intr_names[i]);
386		evcnt_attach_dynamic(&cpi->ci_sintrcnt[i], EVCNT_TYPE_INTR,
387				     NULL, cpu_name(cpi), soft_intr_names[i]);
388	}
389}
390
391/* setup the hw.cpuN.* nodes for this cpu */
392static void
393cpu_setup_sysctl(struct cpu_softc *sc)
394{
395	struct cpu_info	*ci = sc->sc_cpuinfo;
396	const struct sysctlnode *cpunode = NULL;
397
398	sysctl_createv(NULL, 0, NULL, &cpunode,
399		       CTLFLAG_PERMANENT,
400		       CTLTYPE_NODE, device_xname(sc->sc_dev), NULL,
401		       NULL, 0, NULL, 0,
402		       CTL_HW,
403		       CTL_CREATE, CTL_EOL);
404
405	if (cpunode == NULL)
406		return;
407
408#define SETUPS(name, member)					\
409	sysctl_createv(NULL, 0, &cpunode, NULL,			\
410		       CTLFLAG_PERMANENT,			\
411		       CTLTYPE_STRING, name, NULL,		\
412		       NULL, 0, member, 0,			\
413		       CTL_CREATE, CTL_EOL);
414
415	SETUPS("name", __UNCONST(ci->cpu_longname))
416	SETUPS("fpuname", __UNCONST(ci->fpu_name))
417#undef SETUPS
418
419#define SETUPI(name, member)					\
420	sysctl_createv(NULL, 0, &cpunode, NULL,			\
421		       CTLFLAG_PERMANENT,			\
422		       CTLTYPE_INT, name, NULL,			\
423		       NULL, 0, member, 0,			\
424		       CTL_CREATE, CTL_EOL);
425
426	SETUPI("mid", &ci->mid)
427	SETUPI("clock_frequency", &ci->hz)
428	SETUPI("psr_implementation", &ci->cpu_impl)
429	SETUPI("psr_version", &ci->cpu_vers)
430	SETUPI("mmu_implementation", &ci->mmu_impl)
431	SETUPI("mmu_version", &ci->mmu_vers)
432	SETUPI("mmu_nctx", &ci->mmu_ncontext)
433#undef SETUPI
434
435        sysctl_createv(NULL, 0, &cpunode, NULL,
436                       CTLFLAG_PERMANENT,
437                       CTLTYPE_STRUCT, "cacheinfo", NULL,
438                       NULL, 0, &ci->cacheinfo, sizeof(ci->cacheinfo),
439		       CTL_CREATE, CTL_EOL);
440
441}
442
443/*
444 * Attach the CPU.
445 * Discover interesting goop about the virtual address cache
446 * (slightly funny place to do it, but this is where it is to be found).
447 */
448static void
449cpu_attach(struct cpu_softc *sc, int node, int mid)
450{
451	char buf[100];
452	struct cpu_info *cpi;
453	int idx;
454	static int cpu_attach_count = 0;
455
456	/*
457	 * The first CPU we're attaching must be the boot CPU.
458	 * (see autoconf.c and cpuunit.c)
459	 */
460	idx = cpu_attach_count++;
461
462#if !defined(MULTIPROCESSOR)
463	if (cpu_attach_count > 1) {
464		printf(": no SMP support in kernel\n");
465		return;
466	}
467#endif
468
469	/*
470	 * Initialise this cpu's cpu_info.
471	 */
472	cpi = sc->sc_cpuinfo = cpus[idx];
473	getcpuinfo(cpi, node);
474
475	cpi->ci_cpuid = idx;
476	cpi->mid = mid;
477	cpi->node = node;
478#ifdef DEBUG
479	cpi->redzone = (void *)((long)cpi->eintstack + REDSIZE);
480#endif
481
482	if (sparc_ncpus > 1) {
483		printf(": mid %d", mid);
484		if (mid == 0 && !CPU_ISSUN4D)
485			printf(" [WARNING: mid should not be 0]");
486	}
487
488#if defined(MULTIPROCESSOR)
489	if (cpu_attach_count > 1) {
490		if ((boothowto & RB_MD1) != 0) {
491			aprint_naive("\n");
492			aprint_normal(": multiprocessor boot disabled\n");
493			return;
494		}
495		cpu_attach_non_boot(sc, cpi, node);
496		cpu_init_evcnt(cpi);
497		cpu_setup_sysctl(sc);
498		return;
499	}
500#endif /* MULTIPROCESSOR */
501
502	cpu_init_evcnt(cpi);
503
504	/* Stuff to only run on the boot CPU */
505	cpu_setup();
506	snprintf(buf, sizeof buf, "%s @ %s MHz, %s FPU",
507		cpi->cpu_longname, clockfreq(cpi->hz), cpi->fpu_name);
508	cpu_setmodel("%s (%s)", machine_model, buf);
509	printf(": %s\n", buf);
510	cache_print(sc);
511	cpu_setup_sysctl(sc);
512
513	cpi->master = 1;
514	cpi->eintstack = eintstack;
515
516	/*
517	 * If we haven't been able to determine the Id of the
518	 * boot CPU, set it now. In this case we can only boot
519	 * from CPU #0 (see also the CPU attach code in autoconf.c)
520	 */
521	if (bootmid == 0)
522		bootmid = mid;
523
524	/*
525	 * Set speeds now we've attached all CPUs.
526	 */
527	if (sparc_ncpus > 1 && sparc_ncpus == cpu_attach_count) {
528		CPU_INFO_ITERATOR n;
529		unsigned best_hz = 0;
530
531		for (CPU_INFO_FOREACH(n, cpi))
532			best_hz = MAX(cpi->hz, best_hz);
533		for (CPU_INFO_FOREACH(n, cpi))
534			cpu_topology_setspeed(cpi, cpi->hz < best_hz);
535	}
536}
537
538/*
539 * Finish CPU attach.
540 * Must be run by the CPU which is being attached.
541 */
542void
543cpu_setup(void)
544{
545 	if (cpuinfo.hotfix)
546		(*cpuinfo.hotfix)(&cpuinfo);
547
548	/* Initialize FPU */
549	fpu_init(&cpuinfo);
550
551	/* Enable the cache */
552	cpuinfo.cache_enable();
553
554	cpuinfo.flags |= CPUFLG_HATCHED;
555}
556
557#if defined(MULTIPROCESSOR)
558/*
559 * Perform most of the tasks needed for a non-boot CPU.
560 */
561static void
562cpu_attach_non_boot(struct cpu_softc *sc, struct cpu_info *cpi, int node)
563{
564	vaddr_t intstack, va;
565	int error;
566
567	/*
568	 * Arrange interrupt stack.  This cpu will also abuse the bottom
569	 * half of the interrupt stack before it gets to run its idle LWP.
570	 */
571	intstack = uvm_km_alloc(kernel_map, INT_STACK_SIZE, 0, UVM_KMF_WIRED);
572	if (intstack == 0)
573		panic("%s: no uspace/intstack", __func__);
574	cpi->eintstack = (void*)(intstack + INT_STACK_SIZE);
575
576	/* Allocate virtual space for pmap page_copy/page_zero */
577	va = uvm_km_alloc(kernel_map, 2*PAGE_SIZE, 0, UVM_KMF_VAONLY);
578	if (va == 0)
579		panic("%s: no virtual space", __func__);
580
581	cpi->vpage[0] = (void *)(va + 0);
582	cpi->vpage[1] = (void *)(va + PAGE_SIZE);
583
584	/*
585	 * Call the MI attach which creates an idle LWP for us.
586	 */
587	error = mi_cpu_attach(cpi);
588	if (error != 0) {
589		aprint_normal("\n");
590		aprint_error("%s: mi_cpu_attach failed with %d\n",
591		    device_xname(sc->sc_dev), error);
592		return;
593	}
594
595	/*
596	 * Note: `eintstack' is set in cpu_attach_non_boot() above.
597	 * The %wim register will be initialized in cpu_hatch().
598	 */
599	cpi->ci_curlwp = cpi->ci_data.cpu_idlelwp;
600	cpi->curpcb = lwp_getpcb(cpi->ci_curlwp);
601	cpi->curpcb->pcb_wim = 1;
602
603	/* for now use the fixed virtual addresses setup in autoconf.c */
604	cpi->intreg_4m = (struct icr_pi *)
605		(PI_INTR_VA + (_MAXNBPG * CPU_MID2CPUNO(cpi->mid)));
606
607	/* Now start this CPU */
608	cpu_spinup(cpi);
609	printf(": %s @ %s MHz, %s FPU\n", cpi->cpu_longname,
610		clockfreq(cpi->hz), cpi->fpu_name);
611
612	cache_print(sc);
613
614	/*
615	 * Now we're on the last CPU to be attaching.
616	 */
617	if (sparc_ncpus > 1 && cpi->ci_cpuid == sparc_ncpus - 1) {
618		CPU_INFO_ITERATOR n;
619		/*
620		 * Install MP cache flush functions, unless the
621		 * single-processor versions are no-ops.
622		 */
623		for (CPU_INFO_FOREACH(n, cpi)) {
624#define SET_CACHE_FUNC(x) \
625	if (cpi->x != __CONCAT(noop_,x)) cpi->x = __CONCAT(smp_,x)
626			SET_CACHE_FUNC(vcache_flush_page);
627			SET_CACHE_FUNC(vcache_flush_segment);
628			SET_CACHE_FUNC(vcache_flush_region);
629			SET_CACHE_FUNC(vcache_flush_context);
630		}
631	}
632#undef SET_CACHE_FUNC
633}
634
635/*
636 * Start secondary processors in motion.
637 */
638void
639cpu_boot_secondary_processors(void)
640{
641	CPU_INFO_ITERATOR n;
642	struct cpu_info *cpi;
643
644	printf("cpu0: booting secondary processors:");
645	for (CPU_INFO_FOREACH(n, cpi)) {
646		if (cpuinfo.mid == cpi->mid ||
647		    (cpi->flags & CPUFLG_HATCHED) == 0)
648			continue;
649
650		printf(" cpu%d", cpi->ci_cpuid);
651		cpu_ready_mask |= (1 << n);
652	}
653
654	/* Mark the boot CPU as ready */
655	cpu_ready_mask |= (1 << 0);
656
657	/* Tell the other CPU's to start up.  */
658	go_smp_cpus = 1;
659
660	printf("\n");
661}
662
663/*
664 * Early initialisation, before main().
665 */
666void
667cpu_init_system(void)
668{
669
670	mutex_init(&xpmsg_mutex, MUTEX_SPIN, IPL_SCHED);
671}
672
673/*
674 * Allocate per-CPU data, then start up this CPU using PROM.
675 */
676void
677cpu_spinup(struct cpu_info *cpi)
678{
679	struct openprom_addr oa;
680	void *pc;
681	int n;
682
683	pc = (void *)cpu_hatch;
684
685	/* Setup CPU-specific MMU tables */
686	pmap_alloc_cpu(cpi);
687
688	cpi->flags &= ~CPUFLG_HATCHED;
689
690	/*
691	 * The physical address of the context table is passed to
692	 * the PROM in a "physical address descriptor".
693	 */
694	oa.oa_space = 0;
695	oa.oa_base = (uint32_t)cpi->ctx_tbl_pa;
696	oa.oa_size = cpi->mmu_ncontext * sizeof(cpi->ctx_tbl[0]); /*???*/
697
698	/*
699	 * Flush entire cache here, since the CPU may start with
700	 * caches off, hence no cache-coherency may be assumed.
701	 */
702	cpuinfo.cache_flush_all();
703	prom_cpustart(cpi->node, &oa, 0, pc);
704
705	/*
706	 * Wait for this CPU to spin up.
707	 */
708	for (n = 10000; n != 0; n--) {
709		cache_flush((void *) __UNVOLATILE(&cpi->flags),
710			    sizeof(cpi->flags));
711		if (cpi->flags & CPUFLG_HATCHED)
712			return;
713		delay(100);
714	}
715	printf("CPU did not spin up\n");
716}
717
718/*
719 * Call a function on some CPUs.  `cpuset' can be set to CPUSET_ALL
720 * to call every CPU, or `1 << cpi->ci_cpuid' for each CPU to call.
721 */
722void
723xcall(xcall_func_t func, xcall_trap_t trap, int arg0, int arg1, int arg2,
724      u_int cpuset)
725{
726	struct cpu_info *cpi;
727	int n, i, done, callself, mybit;
728	volatile struct xpmsg_func *p;
729	u_int pil;
730	int fasttrap;
731	int is_noop = func == (xcall_func_t)sparc_noop;
732	static char errbuf[160];
733	char *bufp = errbuf;
734	size_t bufsz = sizeof errbuf, wrsz;
735
736	if (is_noop) return;
737
738	mybit = (1 << cpuinfo.ci_cpuid);
739	callself = func && (cpuset & mybit) != 0;
740	cpuset &= ~mybit;
741
742	/* Mask any CPUs that are not ready */
743	cpuset &= cpu_ready_mask;
744
745#if 0
746	mutex_spin_enter(&xpmsg_mutex);
747#else
748	/*
749	 * There's a deadlock potential between multiple CPUs trying
750	 * to xcall() at the same time, and the thread that loses the
751	 * race to get xpmsg_lock is at an IPL above the incoming IPI
752	 * IPL level, so it sits around waiting to take the lock while
753	 * the other CPU is waiting for this CPU to handle the IPI and
754	 * mark it as completed.
755	 *
756	 * If we fail to get the mutex, and we're at high enough IPL,
757	 * call xcallintr() if there is a valid msg.tag.
758	 */
759	pil = (getpsr() & PSR_PIL) >> 8;
760
761	if (cold || pil <= IPL_SCHED)
762		mutex_spin_enter(&xpmsg_mutex);
763	else {
764		/*
765		 * Warn about xcall at high IPL.
766		 *
767		 * XXX This is probably bogus (logging at high IPL),
768		 * XXX so we don't do it by default.
769		 */
770		if (debug_xcall && (void *)func != sparc_noop) {
771			u_int pc;
772
773			__asm("mov %%i7, %0" : "=r" (pc) : );
774			printf_nolog("%d: xcall %p at lvl %u from 0x%x\n",
775			    cpu_number(), func, pil, pc);
776		}
777
778		while (mutex_tryenter(&xpmsg_mutex) == 0) {
779			cpuinfo.ci_xpmsg_mutex_fail.ev_count++;
780			if (cpuinfo.msg.tag) {
781				cpuinfo.ci_xpmsg_mutex_fail_call.ev_count++;
782				xcallintr(xcallintr);
783			}
784		}
785	}
786#endif
787
788	/*
789	 * Firstly, call each CPU.  We do this so that they might have
790	 * finished by the time we start looking.
791	 */
792	fasttrap = trap != NULL ? 1 : 0;
793	for (CPU_INFO_FOREACH(n, cpi)) {
794
795		/* Note: n == cpi->ci_cpuid */
796		if ((cpuset & (1 << n)) == 0)
797			continue;
798
799		/*
800		 * Write msg.tag last - if another CPU is polling above it may
801		 * end up seeing an incomplete message. Not likely but still.
802		 */
803		cpi->msg.complete = 0;
804		p = &cpi->msg.u.xpmsg_func;
805		p->func = func;
806		p->trap = trap;
807		p->arg0 = arg0;
808		p->arg1 = arg1;
809		p->arg2 = arg2;
810		__insn_barrier();
811		cpi->msg.tag = XPMSG_FUNC;
812		__insn_barrier();
813		/* Fast cross calls use interrupt level 14 */
814		raise_ipi(cpi,13+fasttrap);/*xcall_cookie->pil*/
815	}
816
817	/*
818	 * Second, call ourselves.
819	 */
820	if (callself)
821		(*func)(arg0, arg1, arg2);
822
823	/*
824	 * Lastly, start looping, waiting for all CPUs to register that they
825	 * have completed (bailing if it takes "too long", being loud about
826	 * this in the process).
827	 */
828	done = 0;
829	i = 1000000;	/* time-out, not too long, but still an _AGE_ */
830	while (!done) {
831		if (--i < 0) {
832			wrsz = snprintf(bufp, bufsz,
833			    "xcall(cpu%d,%p) from %p: couldn't ping cpus:",
834			    cpu_number(), fasttrap ? trap : func,
835			    __builtin_return_address(0));
836			if (wrsz > bufsz)
837				break;
838			bufsz -= wrsz;
839			bufp += wrsz;
840		}
841
842		done = 1;
843		for (CPU_INFO_FOREACH(n, cpi)) {
844			if ((cpuset & (1 << n)) == 0)
845				continue;
846
847			if (cpi->msg.complete == 0) {
848				if (i < 0) {
849					wrsz = snprintf(bufp, bufsz,
850							" cpu%d", cpi->ci_cpuid);
851					if (wrsz > bufsz)
852						break;
853					bufsz -= wrsz;
854					bufp += wrsz;
855				} else {
856					done = 0;
857					break;
858				}
859			}
860		}
861	}
862
863	if (i >= 0 || debug_xcall == 0) {
864		if (i < 0)
865			aprint_error("%s\n", errbuf);
866		mutex_spin_exit(&xpmsg_mutex);
867		return;
868	}
869
870	/*
871	 * Let's make this a hard panic for now, and figure out why it
872	 * happens.
873	 *
874	 * We call mp_pause_cpus() so we can capture their state *now*
875	 * as opposed to after we've written all the below to the console.
876	 */
877#ifdef DDB
878	mp_pause_cpus_ddb();
879#else
880	mp_pause_cpus();
881#endif
882	printf_nolog("%s\n", errbuf);
883	mutex_spin_exit(&xpmsg_mutex);
884
885	panic("failed to ping cpus");
886}
887
888/*
889 * MD support for MI xcall(9) interface.
890 */
891void
892xc_send_ipi(struct cpu_info *target)
893{
894	u_int cpuset;
895
896	KASSERT(kpreempt_disabled());
897	KASSERT(curcpu() != target);
898
899	if (target)
900		cpuset = 1 << target->ci_cpuid;
901	else
902		cpuset = CPUSET_ALL & ~(1 << cpuinfo.ci_cpuid);
903	XCALL0(xc_ipi_handler, cpuset);
904}
905
906void
907cpu_ipi(struct cpu_info *target)
908{
909	u_int cpuset;
910
911	KASSERT(kpreempt_disabled());
912	KASSERT(curcpu() != target);
913
914	if (target)
915		cpuset = 1 << target->ci_cpuid;
916	else
917		cpuset = CPUSET_ALL & ~(1 << cpuinfo.ci_cpuid);
918	XCALL0(ipi_cpu_handler, cpuset);
919}
920
921/*
922 * Tell all CPUs other than the current one to enter the PROM idle loop.
923 */
924void
925mp_pause_cpus(void)
926{
927	CPU_INFO_ITERATOR n;
928	struct cpu_info *cpi;
929
930	for (CPU_INFO_FOREACH(n, cpi)) {
931		if (cpuinfo.mid == cpi->mid ||
932		    (cpi->flags & CPUFLG_HATCHED) == 0)
933			continue;
934
935		/*
936		 * This PROM utility will put the OPENPROM_MBX_ABORT
937		 * message (0xfc) in the target CPU's mailbox and then
938		 * send it a level 15 soft interrupt.
939		 */
940		if (prom_cpuidle(cpi->node) != 0)
941			printf("cpu%d could not be paused\n", cpi->ci_cpuid);
942	}
943}
944
945/*
946 * Resume all idling CPUs.
947 */
948void
949mp_resume_cpus(void)
950{
951	CPU_INFO_ITERATOR n;
952	struct cpu_info *cpi;
953
954	for (CPU_INFO_FOREACH(n, cpi)) {
955		if (cpuinfo.mid == cpi->mid ||
956		    (cpi->flags & CPUFLG_HATCHED) == 0)
957			continue;
958
959		/*
960		 * This PROM utility makes the target CPU return
961		 * from its prom_cpuidle(0) call (see intr.c:nmi_soft()).
962		 */
963		if (prom_cpuresume(cpi->node) != 0)
964			printf("cpu%d could not be resumed\n", cpi->ci_cpuid);
965	}
966}
967
968/*
969 * Tell all CPUs except the current one to hurry back into the prom
970 */
971void
972mp_halt_cpus(void)
973{
974	CPU_INFO_ITERATOR n;
975	struct cpu_info *cpi;
976
977	for (CPU_INFO_FOREACH(n, cpi)) {
978		int r;
979
980		if (cpuinfo.mid == cpi->mid)
981			continue;
982
983		/*
984		 * This PROM utility will put the OPENPROM_MBX_STOP
985		 * message (0xfb) in the target CPU's mailbox and then
986		 * send it a level 15 soft interrupt.
987		 */
988		r = prom_cpustop(cpi->node);
989		printf("cpu%d %shalted\n", cpi->ci_cpuid,
990			r == 0 ? "" : "(boot CPU?) can not be ");
991	}
992}
993
994#if defined(DDB)
995void
996mp_pause_cpus_ddb(void)
997{
998	CPU_INFO_ITERATOR n;
999	struct cpu_info *cpi;
1000
1001	for (CPU_INFO_FOREACH(n, cpi)) {
1002		if (cpi == NULL || cpi->mid == cpuinfo.mid ||
1003		    (cpi->flags & CPUFLG_HATCHED) == 0)
1004			continue;
1005
1006		cpi->msg_lev15.tag = XPMSG15_PAUSECPU;
1007		raise_ipi(cpi,15);	/* high priority intr */
1008	}
1009}
1010
1011void
1012mp_resume_cpus_ddb(void)
1013{
1014	CPU_INFO_ITERATOR n;
1015	struct cpu_info *cpi;
1016
1017	for (CPU_INFO_FOREACH(n, cpi)) {
1018		if (cpi == NULL || cpuinfo.mid == cpi->mid ||
1019		    (cpi->flags & CPUFLG_PAUSED) == 0)
1020			continue;
1021
1022		/* tell it to continue */
1023		cpi->flags &= ~CPUFLG_PAUSED;
1024	}
1025}
1026#endif /* DDB */
1027#endif /* MULTIPROCESSOR */
1028
1029/*
1030 * fpu_init() must be run on associated CPU.
1031 */
1032void
1033fpu_init(struct cpu_info *sc)
1034{
1035	struct fpstate fpstate;
1036	int fpuvers;
1037
1038	/*
1039	 * Get the FSR and clear any exceptions.  If we do not unload
1040	 * the queue here and it is left over from a previous crash, we
1041	 * will panic in the first loadfpstate(), due to a sequence
1042	 * error, so we need to dump the whole state anyway.
1043	 *
1044	 * If there is no FPU, trap.c will advance over all the stores,
1045	 * so we initialize fs_fsr here.
1046	 */
1047
1048	/* 7 is reserved for "none" */
1049	fpstate.fs_fsr = 7 << FSR_VER_SHIFT;
1050	savefpstate(&fpstate);
1051	sc->fpuvers = fpuvers =
1052		(fpstate.fs_fsr >> FSR_VER_SHIFT) & (FSR_VER >> FSR_VER_SHIFT);
1053
1054	if (fpuvers == 7) {
1055		sc->fpu_name = "no";
1056		return;
1057	}
1058
1059	sc->fpupresent = 1;
1060	sc->fpu_name = fsrtoname(sc->cpu_impl, sc->cpu_vers, fpuvers);
1061	if (sc->fpu_name == NULL) {
1062		snprintf(sc->fpu_namebuf, sizeof(sc->fpu_namebuf),
1063		    "version 0x%x", fpuvers);
1064		sc->fpu_name = sc->fpu_namebuf;
1065	}
1066}
1067
1068static void
1069cache_print(struct cpu_softc *sc)
1070{
1071	struct cacheinfo *ci = &sc->sc_cpuinfo->cacheinfo;
1072
1073	cache_printf_backend(ci, device_xname(sc->sc_dev));
1074}
1075
1076/*------------*/
1077
1078
1079void cpumatch_unknown(struct cpu_info *, struct module_info *, int);
1080void cpumatch_sun4(struct cpu_info *, struct module_info *, int);
1081void cpumatch_sun4c(struct cpu_info *, struct module_info *, int);
1082void cpumatch_ms1(struct cpu_info *, struct module_info *, int);
1083void cpumatch_viking(struct cpu_info *, struct module_info *, int);
1084void cpumatch_hypersparc(struct cpu_info *, struct module_info *, int);
1085void cpumatch_turbosparc(struct cpu_info *, struct module_info *, int);
1086
1087void getcacheinfo_sun4(struct cpu_info *, int node);
1088void getcacheinfo_sun4c(struct cpu_info *, int node);
1089void getcacheinfo_obp(struct cpu_info *, int node);
1090void getcacheinfo_sun4d(struct cpu_info *, int node);
1091
1092void sun4_hotfix(struct cpu_info *);
1093void viking_hotfix(struct cpu_info *);
1094void turbosparc_hotfix(struct cpu_info *);
1095void swift_hotfix(struct cpu_info *);
1096
1097void ms1_mmu_enable(void);
1098void viking_mmu_enable(void);
1099void swift_mmu_enable(void);
1100void hypersparc_mmu_enable(void);
1101
1102void srmmu_get_syncflt(void);
1103void ms1_get_syncflt(void);
1104void viking_get_syncflt(void);
1105void swift_get_syncflt(void);
1106void turbosparc_get_syncflt(void);
1107void hypersparc_get_syncflt(void);
1108void cypress_get_syncflt(void);
1109
1110int srmmu_get_asyncflt(u_int *, u_int *);
1111int hypersparc_get_asyncflt(u_int *, u_int *);
1112int cypress_get_asyncflt(u_int *, u_int *);
1113int no_asyncflt_regs(u_int *, u_int *);
1114
1115int hypersparc_getmid(void);
1116/* cypress and hypersparc can share this function, see ctlreg.h */
1117#define cypress_getmid	hypersparc_getmid
1118int viking_getmid(void);
1119
1120#if (defined(SUN4M) && !defined(MSIIEP)) || defined(SUN4D)
1121int viking_module_error(void);
1122#endif
1123
1124struct module_info module_unknown = {
1125	CPUTYP_UNKNOWN,
1126	VAC_UNKNOWN,
1127	cpumatch_unknown
1128};
1129
1130
1131void
1132cpumatch_unknown(struct cpu_info *sc, struct module_info *mp, int node)
1133{
1134
1135	panic("Unknown CPU type: "
1136	      "cpu: impl %d, vers %d; mmu: impl %d, vers %d",
1137		sc->cpu_impl, sc->cpu_vers,
1138		sc->mmu_impl, sc->mmu_vers);
1139}
1140
1141#if defined(SUN4)
1142struct module_info module_sun4 = {
1143	CPUTYP_UNKNOWN,
1144	VAC_WRITETHROUGH,
1145	cpumatch_sun4,
1146	getcacheinfo_sun4,
1147	sun4_hotfix,
1148	0,
1149	sun4_cache_enable,
1150	0,
1151	0,			/* ncontext set in `match' function */
1152	0,			/* get_syncflt(); unused in sun4c */
1153	0,			/* get_asyncflt(); unused in sun4c */
1154	sun4_cache_flush,
1155	sun4_vcache_flush_page, NULL,
1156	sun4_vcache_flush_segment, NULL,
1157	sun4_vcache_flush_region, NULL,
1158	sun4_vcache_flush_context, NULL,
1159	NULL, NULL,
1160	noop_pcache_flush_page,
1161	noop_pure_vcache_flush,
1162	noop_cache_flush_all,
1163	0,
1164	pmap_zero_page4_4c,
1165	pmap_copy_page4_4c
1166};
1167
1168void
1169getcacheinfo_sun4(struct cpu_info *sc, int node)
1170{
1171	struct cacheinfo *ci = &sc->cacheinfo;
1172
1173	switch (sc->cpu_type) {
1174	case CPUTYP_4_100:
1175		ci->c_vactype = VAC_NONE;
1176		ci->c_totalsize = 0;
1177		ci->c_hwflush = 0;
1178		ci->c_linesize = 0;
1179		ci->c_l2linesize = 0;
1180		ci->c_split = 0;
1181		ci->c_nlines = 0;
1182
1183		/* Override cache flush functions */
1184		sc->cache_flush = noop_cache_flush;
1185		sc->sp_vcache_flush_page = noop_vcache_flush_page;
1186		sc->sp_vcache_flush_segment = noop_vcache_flush_segment;
1187		sc->sp_vcache_flush_region = noop_vcache_flush_region;
1188		sc->sp_vcache_flush_context = noop_vcache_flush_context;
1189		break;
1190	case CPUTYP_4_200:
1191		ci->c_vactype = VAC_WRITEBACK;
1192		ci->c_totalsize = 128*1024;
1193		ci->c_hwflush = 0;
1194		ci->c_linesize = 16;
1195		ci->c_l2linesize = 4;
1196		ci->c_split = 0;
1197		ci->c_nlines = ci->c_totalsize >> ci->c_l2linesize;
1198		break;
1199	case CPUTYP_4_300:
1200		ci->c_vactype = VAC_WRITEBACK;
1201		ci->c_totalsize = 128*1024;
1202		ci->c_hwflush = 0;
1203		ci->c_linesize = 16;
1204		ci->c_l2linesize = 4;
1205		ci->c_split = 0;
1206		ci->c_nlines = ci->c_totalsize >> ci->c_l2linesize;
1207		sc->cacheinfo.c_flags |= CACHE_TRAPPAGEBUG;
1208		break;
1209	case CPUTYP_4_400:
1210		ci->c_vactype = VAC_WRITEBACK;
1211		ci->c_totalsize = 128 * 1024;
1212		ci->c_hwflush = 0;
1213		ci->c_linesize = 32;
1214		ci->c_l2linesize = 5;
1215		ci->c_split = 0;
1216		ci->c_nlines = ci->c_totalsize >> ci->c_l2linesize;
1217		break;
1218	}
1219}
1220
1221void
1222cpumatch_sun4(struct cpu_info *sc, struct module_info *mp, int node)
1223{
1224	struct idprom *idp = prom_getidprom();
1225
1226	switch (idp->idp_machtype) {
1227	case ID_SUN4_100:
1228		sc->cpu_type = CPUTYP_4_100;
1229		sc->classlvl = 100;
1230		sc->mmu_ncontext = 8;
1231		sc->mmu_nsegment = 256;
1232/*XXX*/		sc->hz = 14280000;
1233		break;
1234	case ID_SUN4_200:
1235		sc->cpu_type = CPUTYP_4_200;
1236		sc->classlvl = 200;
1237		sc->mmu_nsegment = 512;
1238		sc->mmu_ncontext = 16;
1239/*XXX*/		sc->hz = 16670000;
1240		break;
1241	case ID_SUN4_300:
1242		sc->cpu_type = CPUTYP_4_300;
1243		sc->classlvl = 300;
1244		sc->mmu_nsegment = 256;
1245		sc->mmu_ncontext = 16;
1246/*XXX*/		sc->hz = 25000000;
1247		break;
1248	case ID_SUN4_400:
1249		sc->cpu_type = CPUTYP_4_400;
1250		sc->classlvl = 400;
1251		sc->mmu_nsegment = 1024;
1252		sc->mmu_ncontext = 64;
1253		sc->mmu_nregion = 256;
1254/*XXX*/		sc->hz = 33000000;
1255		sc->sun4_mmu3l = 1;
1256		break;
1257	}
1258
1259}
1260#endif /* SUN4 */
1261
1262#if defined(SUN4C)
1263struct module_info module_sun4c = {
1264	CPUTYP_UNKNOWN,
1265	VAC_WRITETHROUGH,
1266	cpumatch_sun4c,
1267	getcacheinfo_sun4c,
1268	sun4_hotfix,
1269	0,
1270	sun4_cache_enable,
1271	0,
1272	0,			/* ncontext set in `match' function */
1273	0,			/* get_syncflt(); unused in sun4c */
1274	0,			/* get_asyncflt(); unused in sun4c */
1275	sun4_cache_flush,
1276	sun4_vcache_flush_page, NULL,
1277	sun4_vcache_flush_segment, NULL,
1278	sun4_vcache_flush_region, NULL,
1279	sun4_vcache_flush_context, NULL,
1280	NULL, NULL,
1281	noop_pcache_flush_page,
1282	noop_pure_vcache_flush,
1283	noop_cache_flush_all,
1284	0,
1285	pmap_zero_page4_4c,
1286	pmap_copy_page4_4c
1287};
1288
1289void
1290cpumatch_sun4c(struct cpu_info *sc, struct module_info *mp, int node)
1291{
1292	int	rnode;
1293
1294	rnode = findroot();
1295	sc->mmu_npmeg = sc->mmu_nsegment =
1296		prom_getpropint(rnode, "mmu-npmg", 128);
1297	sc->mmu_ncontext = prom_getpropint(rnode, "mmu-nctx", 8);
1298
1299	/* Get clock frequency */
1300	sc->hz = prom_getpropint(rnode, "clock-frequency", 0);
1301}
1302
1303void
1304getcacheinfo_sun4c(struct cpu_info *sc, int node)
1305{
1306	struct cacheinfo *ci = &sc->cacheinfo;
1307	int i, l;
1308
1309	if (node == 0)
1310		/* Bootstrapping */
1311		return;
1312
1313	/* Sun4c's have only virtually-addressed caches */
1314	ci->c_physical = 0;
1315	ci->c_totalsize = prom_getpropint(node, "vac-size", 65536);
1316	/*
1317	 * Note: vac-hwflush is spelled with an underscore
1318	 * on the 4/75s.
1319	 */
1320	ci->c_hwflush =
1321		prom_getpropint(node, "vac_hwflush", 0) |
1322		prom_getpropint(node, "vac-hwflush", 0);
1323
1324	ci->c_linesize = l = prom_getpropint(node, "vac-linesize", 16);
1325	for (i = 0; (1 << i) < l; i++)
1326		/* void */;
1327	if ((1 << i) != l)
1328		panic("bad cache line size %d", l);
1329	ci->c_l2linesize = i;
1330	ci->c_associativity = 1;
1331	ci->c_nlines = ci->c_totalsize >> i;
1332
1333	ci->c_vactype = VAC_WRITETHROUGH;
1334
1335	/*
1336	 * Machines with "buserr-type" 1 have a bug in the cache
1337	 * chip that affects traps.  (I wish I knew more about this
1338	 * mysterious buserr-type variable....)
1339	 */
1340	if (prom_getpropint(node, "buserr-type", 0) == 1)
1341		sc->cacheinfo.c_flags |= CACHE_TRAPPAGEBUG;
1342}
1343#endif /* SUN4C */
1344
1345void
1346sun4_hotfix(struct cpu_info *sc)
1347{
1348
1349	if ((sc->cacheinfo.c_flags & CACHE_TRAPPAGEBUG) != 0)
1350		kvm_uncache((char *)trapbase, 1);
1351
1352	/* Use the hardware-assisted page flush routine, if present */
1353	if (sc->cacheinfo.c_hwflush)
1354		sc->vcache_flush_page = sun4_vcache_flush_page_hw;
1355}
1356
1357#if defined(SUN4M)
1358void
1359getcacheinfo_obp(struct cpu_info *sc, int node)
1360{
1361	struct cacheinfo *ci = &sc->cacheinfo;
1362	int i, l;
1363
1364#if defined(MULTIPROCESSOR)
1365	/*
1366	 * We really really want the cache info early for MP systems,
1367	 * so figure out the boot node, if we can.
1368	 *
1369	 * XXX this loop stolen from mainbus_attach()
1370	 */
1371	if (node == 0 && CPU_ISSUN4M && bootmid != 0) {
1372		const char *cp;
1373		char namebuf[32];
1374		int mid, node2;
1375
1376		for (node2 = firstchild(findroot());
1377		     node2;
1378		     node2 = nextsibling(node2)) {
1379			cp = prom_getpropstringA(node2, "device_type",
1380					    namebuf, sizeof namebuf);
1381			if (strcmp(cp, "cpu") != 0)
1382				continue;
1383
1384			mid = prom_getpropint(node2, "mid", -1);
1385			if (mid == bootmid) {
1386				node = node2;
1387				break;
1388			}
1389		}
1390	}
1391#endif
1392
1393	if (node == 0)
1394		/* Bootstrapping */
1395		return;
1396
1397	/*
1398	 * Determine the Sun4m cache organization.
1399	 */
1400	ci->c_physical = node_has_property(node, "cache-physical?");
1401
1402	if (prom_getpropint(node, "ncaches", 1) == 2)
1403		ci->c_split = 1;
1404	else
1405		ci->c_split = 0;
1406
1407	/* hwflush is used only by sun4/4c code */
1408	ci->c_hwflush = 0;
1409
1410	if (node_has_property(node, "icache-nlines") &&
1411	    node_has_property(node, "dcache-nlines") &&
1412	    ci->c_split) {
1413		/* Harvard architecture: get I and D cache sizes */
1414		ci->ic_nlines = prom_getpropint(node, "icache-nlines", 0);
1415		ci->ic_linesize = l =
1416			prom_getpropint(node, "icache-line-size", 0);
1417		for (i = 0; (1 << i) < l && l; i++)
1418			/* void */;
1419		if ((1 << i) != l && l)
1420			panic("bad icache line size %d", l);
1421		ci->ic_l2linesize = i;
1422		ci->ic_associativity =
1423			prom_getpropint(node, "icache-associativity", 1);
1424		ci->ic_totalsize = l * ci->ic_nlines * ci->ic_associativity;
1425
1426		ci->dc_nlines = prom_getpropint(node, "dcache-nlines", 0);
1427		ci->dc_linesize = l =
1428			prom_getpropint(node, "dcache-line-size",0);
1429		for (i = 0; (1 << i) < l && l; i++)
1430			/* void */;
1431		if ((1 << i) != l && l)
1432			panic("bad dcache line size %d", l);
1433		ci->dc_l2linesize = i;
1434		ci->dc_associativity =
1435			prom_getpropint(node, "dcache-associativity", 1);
1436		ci->dc_totalsize = l * ci->dc_nlines * ci->dc_associativity;
1437
1438		ci->c_l2linesize = uimin(ci->ic_l2linesize, ci->dc_l2linesize);
1439		ci->c_linesize = uimin(ci->ic_linesize, ci->dc_linesize);
1440		ci->c_totalsize = uimax(ci->ic_totalsize, ci->dc_totalsize);
1441		ci->c_nlines = ci->c_totalsize >> ci->c_l2linesize;
1442	} else {
1443		/* unified I/D cache */
1444		ci->c_nlines = prom_getpropint(node, "cache-nlines", 128);
1445		ci->c_linesize = l =
1446			prom_getpropint(node, "cache-line-size", 0);
1447		for (i = 0; (1 << i) < l && l; i++)
1448			/* void */;
1449		if ((1 << i) != l && l)
1450			panic("bad cache line size %d", l);
1451		ci->c_l2linesize = i;
1452		ci->c_associativity =
1453			prom_getpropint(node, "cache-associativity", 1);
1454		ci->dc_associativity = ci->ic_associativity =
1455			ci->c_associativity;
1456		ci->c_totalsize = l * ci->c_nlines * ci->c_associativity;
1457	}
1458
1459	if (node_has_property(node, "ecache-nlines")) {
1460		/* we have a L2 "e"xternal cache */
1461		ci->ec_nlines = prom_getpropint(node, "ecache-nlines", 32768);
1462		ci->ec_linesize = l = prom_getpropint(node, "ecache-line-size", 0);
1463		for (i = 0; (1 << i) < l && l; i++)
1464			/* void */;
1465		if ((1 << i) != l && l)
1466			panic("bad ecache line size %d", l);
1467		ci->ec_l2linesize = i;
1468		ci->ec_associativity =
1469			prom_getpropint(node, "ecache-associativity", 1);
1470		ci->ec_totalsize = l * ci->ec_nlines * ci->ec_associativity;
1471	}
1472	if (ci->c_totalsize == 0)
1473		printf("warning: couldn't identify cache\n");
1474}
1475
1476/*
1477 * We use the max. number of contexts on the micro and
1478 * hyper SPARCs. The SuperSPARC would let us use up to 65536
1479 * contexts (by powers of 2), but we keep it at 4096 since
1480 * the table must be aligned to #context*4. With 4K contexts,
1481 * we waste at most 16K of memory. Note that the context
1482 * table is *always* page-aligned, so there can always be
1483 * 1024 contexts without sacrificing memory space (given
1484 * that the chip supports 1024 contexts).
1485 *
1486 * Currently known limits: MS1=64, MS2=256, HS=4096, SS=65536
1487 * 	some old SS's=4096
1488 */
1489
1490/* TI Microsparc I */
1491struct module_info module_ms1 = {
1492	CPUTYP_MS1,
1493	VAC_NONE,
1494	cpumatch_ms1,
1495	getcacheinfo_obp,
1496	0,
1497	ms1_mmu_enable,
1498	ms1_cache_enable,
1499	0,
1500	64,
1501	ms1_get_syncflt,
1502	no_asyncflt_regs,
1503	ms1_cache_flush,
1504	noop_vcache_flush_page, NULL,
1505	noop_vcache_flush_segment, NULL,
1506	noop_vcache_flush_region, NULL,
1507	noop_vcache_flush_context, NULL,
1508	noop_vcache_flush_range, NULL,
1509	noop_pcache_flush_page,
1510	noop_pure_vcache_flush,
1511	ms1_cache_flush_all,
1512	memerr4m,
1513	pmap_zero_page4m,
1514	pmap_copy_page4m
1515};
1516
1517void
1518cpumatch_ms1(struct cpu_info *sc, struct module_info *mp, int node)
1519{
1520}
1521
1522void
1523ms1_mmu_enable(void)
1524{
1525}
1526
1527/* TI Microsparc II */
1528struct module_info module_ms2 = {		/* UNTESTED */
1529	CPUTYP_MS2,
1530	VAC_WRITETHROUGH,
1531	0,
1532	getcacheinfo_obp,
1533	0,
1534	0,
1535	swift_cache_enable,
1536	0,
1537	256,
1538	srmmu_get_syncflt,
1539	srmmu_get_asyncflt,
1540	srmmu_cache_flush,
1541	srmmu_vcache_flush_page, NULL,
1542	srmmu_vcache_flush_segment, NULL,
1543	srmmu_vcache_flush_region, NULL,
1544	srmmu_vcache_flush_context, NULL,
1545	srmmu_vcache_flush_range, NULL,
1546	noop_pcache_flush_page,
1547	noop_pure_vcache_flush,
1548	srmmu_cache_flush_all,
1549	memerr4m,
1550	pmap_zero_page4m,
1551	pmap_copy_page4m
1552};
1553
1554
1555struct module_info module_swift = {
1556	CPUTYP_MS2,
1557	VAC_WRITETHROUGH,
1558	0,
1559	getcacheinfo_obp,
1560	swift_hotfix,
1561	0,
1562	swift_cache_enable,
1563	0,
1564	256,
1565	swift_get_syncflt,
1566	no_asyncflt_regs,
1567	srmmu_cache_flush,
1568	srmmu_vcache_flush_page, NULL,
1569	srmmu_vcache_flush_segment, NULL,
1570	srmmu_vcache_flush_region, NULL,
1571	srmmu_vcache_flush_context, NULL,
1572	srmmu_vcache_flush_range, NULL,
1573	noop_pcache_flush_page,
1574	noop_pure_vcache_flush,
1575	srmmu_cache_flush_all,
1576	memerr4m,
1577	pmap_zero_page4m,
1578	pmap_copy_page4m
1579};
1580
1581void
1582swift_hotfix(struct cpu_info *sc)
1583{
1584	int pcr = lda(SRMMU_PCR, ASI_SRMMU);
1585
1586	/* Turn off branch prediction */
1587	pcr &= ~SWIFT_PCR_BF;
1588	sta(SRMMU_PCR, ASI_SRMMU, pcr);
1589}
1590
1591void
1592swift_mmu_enable(void)
1593{
1594}
1595
1596
1597/* ROSS Hypersparc */
1598struct module_info module_hypersparc = {
1599	CPUTYP_UNKNOWN,
1600	VAC_WRITEBACK,
1601	cpumatch_hypersparc,
1602	getcacheinfo_obp,
1603	0,
1604	hypersparc_mmu_enable,
1605	hypersparc_cache_enable,
1606	hypersparc_getmid,
1607	4096,
1608	hypersparc_get_syncflt,
1609	hypersparc_get_asyncflt,
1610	srmmu_cache_flush,
1611	srmmu_vcache_flush_page, ft_srmmu_vcache_flush_page,
1612	srmmu_vcache_flush_segment, ft_srmmu_vcache_flush_segment,
1613	srmmu_vcache_flush_region, ft_srmmu_vcache_flush_region,
1614	srmmu_vcache_flush_context, ft_srmmu_vcache_flush_context,
1615	srmmu_vcache_flush_range, ft_srmmu_vcache_flush_range,
1616	noop_pcache_flush_page,
1617	hypersparc_pure_vcache_flush,
1618	hypersparc_cache_flush_all,
1619	hypersparc_memerr,
1620	pmap_zero_page4m,
1621	pmap_copy_page4m
1622};
1623
1624void
1625cpumatch_hypersparc(struct cpu_info *sc, struct module_info *mp, int node)
1626{
1627
1628	sc->cpu_type = CPUTYP_HS_MBUS;/*XXX*/
1629
1630	if (node == 0) {
1631		/* Flush I-cache */
1632		sta(0, ASI_HICACHECLR, 0);
1633
1634		/* Disable `unimplemented flush' traps during boot-up */
1635		wrasr(rdasr(HYPERSPARC_ASRNUM_ICCR) | HYPERSPARC_ICCR_FTD,
1636			HYPERSPARC_ASRNUM_ICCR);
1637	}
1638}
1639
1640void
1641hypersparc_mmu_enable(void)
1642{
1643#if 0
1644	int pcr;
1645
1646	pcr = lda(SRMMU_PCR, ASI_SRMMU);
1647	pcr |= HYPERSPARC_PCR_C;
1648	pcr &= ~HYPERSPARC_PCR_CE;
1649
1650	sta(SRMMU_PCR, ASI_SRMMU, pcr);
1651#endif
1652}
1653
1654int
1655hypersparc_getmid(void)
1656{
1657	u_int pcr = lda(SRMMU_PCR, ASI_SRMMU);
1658	return ((pcr & HYPERSPARC_PCR_MID) >> 15);
1659}
1660
1661
1662/* Cypress 605 */
1663struct module_info module_cypress = {
1664	CPUTYP_CYPRESS,
1665	VAC_WRITEBACK,
1666	0,
1667	getcacheinfo_obp,
1668	0,
1669	0,
1670	cypress_cache_enable,
1671	cypress_getmid,
1672	4096,
1673	cypress_get_syncflt,
1674	cypress_get_asyncflt,
1675	srmmu_cache_flush,
1676	srmmu_vcache_flush_page, ft_srmmu_vcache_flush_page,
1677	srmmu_vcache_flush_segment, ft_srmmu_vcache_flush_segment,
1678	srmmu_vcache_flush_region, ft_srmmu_vcache_flush_region,
1679	srmmu_vcache_flush_context, ft_srmmu_vcache_flush_context,
1680	srmmu_vcache_flush_range, ft_srmmu_vcache_flush_range,
1681	noop_pcache_flush_page,
1682	noop_pure_vcache_flush,
1683	cypress_cache_flush_all,
1684	memerr4m,
1685	pmap_zero_page4m,
1686	pmap_copy_page4m
1687};
1688
1689
1690/* Fujitsu Turbosparc */
1691struct module_info module_turbosparc = {
1692	CPUTYP_MS2,
1693	VAC_WRITEBACK,
1694	cpumatch_turbosparc,
1695	getcacheinfo_obp,
1696	turbosparc_hotfix,
1697	0,
1698	turbosparc_cache_enable,
1699	0,
1700	256,
1701	turbosparc_get_syncflt,
1702	no_asyncflt_regs,
1703	srmmu_cache_flush,
1704	srmmu_vcache_flush_page, NULL,
1705	srmmu_vcache_flush_segment, NULL,
1706	srmmu_vcache_flush_region, NULL,
1707	srmmu_vcache_flush_context, NULL,
1708	srmmu_vcache_flush_range, NULL,
1709	noop_pcache_flush_page,
1710	noop_pure_vcache_flush,
1711	srmmu_cache_flush_all,
1712	memerr4m,
1713	pmap_zero_page4m,
1714	pmap_copy_page4m
1715};
1716
1717void
1718cpumatch_turbosparc(struct cpu_info *sc, struct module_info *mp, int node)
1719{
1720	int i;
1721
1722	if (node == 0 || sc->master == 0)
1723		return;
1724
1725	i = getpsr();
1726	if (sc->cpu_vers == IU_VERS(i))
1727		return;
1728
1729	/*
1730	 * A cloaked Turbosparc: clear any items in cpuinfo that
1731	 * might have been set to uS2 versions during bootstrap.
1732	 */
1733	sc->cpu_longname = 0;
1734	sc->mmu_ncontext = 0;
1735	sc->cpu_type = 0;
1736	sc->cacheinfo.c_vactype = 0;
1737	sc->hotfix = 0;
1738	sc->mmu_enable = 0;
1739	sc->cache_enable = 0;
1740	sc->get_syncflt = 0;
1741	sc->cache_flush = 0;
1742	sc->sp_vcache_flush_page = 0;
1743	sc->sp_vcache_flush_segment = 0;
1744	sc->sp_vcache_flush_region = 0;
1745	sc->sp_vcache_flush_context = 0;
1746	sc->pcache_flush_page = 0;
1747}
1748
1749void
1750turbosparc_hotfix(struct cpu_info *sc)
1751{
1752	int pcf;
1753
1754	pcf = lda(SRMMU_PCFG, ASI_SRMMU);
1755	if (pcf & TURBOSPARC_PCFG_US2) {
1756		/* Turn off uS2 emulation bit */
1757		pcf &= ~TURBOSPARC_PCFG_US2;
1758		sta(SRMMU_PCFG, ASI_SRMMU, pcf);
1759	}
1760}
1761#endif /* SUN4M */
1762
1763#if defined(SUN4M)
1764struct module_info module_viking = {
1765	CPUTYP_UNKNOWN,		/* set in cpumatch() */
1766	VAC_NONE,
1767	cpumatch_viking,
1768	getcacheinfo_obp,
1769	viking_hotfix,
1770	viking_mmu_enable,
1771	viking_cache_enable,
1772	viking_getmid,
1773	4096,
1774	viking_get_syncflt,
1775	no_asyncflt_regs,
1776	/* supersparcs use cached DVMA, no need to flush */
1777	noop_cache_flush,
1778	noop_vcache_flush_page, NULL,
1779	noop_vcache_flush_segment, NULL,
1780	noop_vcache_flush_region, NULL,
1781	noop_vcache_flush_context, NULL,
1782	noop_vcache_flush_range, NULL,
1783	viking_pcache_flush_page,
1784	noop_pure_vcache_flush,
1785	noop_cache_flush_all,
1786	viking_memerr,
1787	pmap_zero_page4m,
1788	pmap_copy_page4m
1789};
1790#endif /* SUN4M */
1791
1792#if defined(SUN4M) || defined(SUN4D)
1793void
1794cpumatch_viking(struct cpu_info *sc, struct module_info *mp, int node)
1795{
1796
1797	if (node == 0)
1798		viking_hotfix(sc);
1799}
1800
1801void
1802viking_hotfix(struct cpu_info *sc)
1803{
1804static	int mxcc = -1;
1805	int pcr = lda(SRMMU_PCR, ASI_SRMMU);
1806
1807	/* Test if we're directly on the MBus */
1808	if ((pcr & VIKING_PCR_MB) == 0) {
1809		sc->mxcc = 1;
1810		sc->cacheinfo.c_flags |= CACHE_MANDATORY;
1811		sc->zero_page = pmap_zero_page_viking_mxcc;
1812		sc->copy_page = pmap_copy_page_viking_mxcc;
1813#if !defined(MSIIEP)
1814		moduleerr_handler = viking_module_error;
1815#endif
1816
1817		/*
1818		 * Ok to cache PTEs; set the flag here, so we don't
1819		 * uncache in pmap_bootstrap().
1820		 */
1821		if ((pcr & VIKING_PCR_TC) == 0)
1822			printf("[viking: PCR_TC is off]");
1823		else
1824			sc->cacheinfo.c_flags |= CACHE_PAGETABLES;
1825	} else {
1826#ifdef MULTIPROCESSOR
1827		if (sparc_ncpus > 1 && sc->cacheinfo.ec_totalsize == 0)
1828			sc->cache_flush = srmmu_cache_flush;
1829#endif
1830	}
1831	/* Check all modules have the same MXCC configuration */
1832	if (mxcc != -1 && sc->mxcc != mxcc)
1833		panic("MXCC module mismatch");
1834
1835	mxcc = sc->mxcc;
1836
1837	/* XXX! */
1838	if (sc->mxcc)
1839		sc->cpu_type = CPUTYP_SS1_MBUS_MXCC;
1840	else
1841		sc->cpu_type = CPUTYP_SS1_MBUS_NOMXCC;
1842}
1843
1844void
1845viking_mmu_enable(void)
1846{
1847	int pcr;
1848
1849	pcr = lda(SRMMU_PCR, ASI_SRMMU);
1850
1851	if (cpuinfo.mxcc) {
1852		if ((pcr & VIKING_PCR_TC) == 0) {
1853			printf("[viking: turn on PCR_TC]");
1854		}
1855		pcr |= VIKING_PCR_TC;
1856		CACHEINFO.c_flags |= CACHE_PAGETABLES;
1857	} else
1858		pcr &= ~VIKING_PCR_TC;
1859	sta(SRMMU_PCR, ASI_SRMMU, pcr);
1860}
1861
1862int
1863viking_getmid(void)
1864{
1865
1866	if (cpuinfo.mxcc) {
1867		u_int v = ldda(MXCC_MBUSPORT, ASI_CONTROL) & 0xffffffff;
1868		return ((v >> 24) & 0xf);
1869	}
1870	return (0);
1871}
1872
1873#if !defined(MSIIEP)
1874int
1875viking_module_error(void)
1876{
1877	uint64_t v;
1878	int fatal = 0;
1879	CPU_INFO_ITERATOR n;
1880	struct cpu_info *cpi;
1881
1882	/* Report on MXCC error registers in each module */
1883	for (CPU_INFO_FOREACH(n, cpi)) {
1884		if (cpi->ci_mxccregs == 0) {
1885			printf("\tMXCC registers not mapped\n");
1886			continue;
1887		}
1888
1889		printf("module%d:\n", cpi->ci_cpuid);
1890		v = *((uint64_t *)(cpi->ci_mxccregs + 0xe00));
1891		printf("\tmxcc error 0x%llx\n", v);
1892		v = *((uint64_t *)(cpi->ci_mxccregs + 0xb00));
1893		printf("\tmxcc status 0x%llx\n", v);
1894		v = *((uint64_t *)(cpi->ci_mxccregs + 0xc00));
1895		printf("\tmxcc reset 0x%llx", v);
1896		if (v & MXCC_MRST_WD)
1897			printf(" (WATCHDOG RESET)"), fatal = 1;
1898		if (v & MXCC_MRST_SI)
1899			printf(" (SOFTWARE RESET)"), fatal = 1;
1900		printf("\n");
1901	}
1902	return (fatal);
1903}
1904#endif /* MSIIEP */
1905#endif /* SUN4M || SUN4D */
1906
1907#if defined(SUN4D)
1908void
1909getcacheinfo_sun4d(struct cpu_info *sc, int node)
1910{
1911	struct cacheinfo *ci = &sc->cacheinfo;
1912	int i, l;
1913
1914	if (node == 0)
1915		/* Bootstrapping */
1916		return;
1917
1918	/*
1919	 * The Sun4d always has TI TMS390Z55 Viking CPUs; we hard-code
1920	 * much of the cache information here.
1921	 */
1922
1923	ci->c_physical = 1;
1924	ci->c_split = 1;
1925
1926	/* hwflush is used only by sun4/4c code */
1927	ci->c_hwflush = 0;
1928
1929	ci->ic_nlines = 0x00000040;
1930	ci->ic_linesize = 0x00000040;
1931	ci->ic_l2linesize = 6;
1932	ci->ic_associativity = 0x00000005;
1933	ci->ic_totalsize = ci->ic_linesize * ci->ic_nlines *
1934	    ci->ic_associativity;
1935
1936	ci->dc_nlines = 0x00000080;
1937	ci->dc_linesize = 0x00000020;
1938	ci->dc_l2linesize = 5;
1939	ci->dc_associativity = 0x00000004;
1940	ci->dc_totalsize = ci->dc_linesize * ci->dc_nlines *
1941	    ci->dc_associativity;
1942
1943	ci->c_l2linesize = uimin(ci->ic_l2linesize, ci->dc_l2linesize);
1944	ci->c_linesize = uimin(ci->ic_linesize, ci->dc_linesize);
1945	ci->c_totalsize = uimax(ci->ic_totalsize, ci->dc_totalsize);
1946	ci->c_nlines = ci->c_totalsize >> ci->c_l2linesize;
1947
1948	if (node_has_property(node, "ecache-nlines")) {
1949		/* we have a L2 "e"xternal cache */
1950		ci->ec_nlines = prom_getpropint(node, "ecache-nlines", 32768);
1951		ci->ec_linesize = l = prom_getpropint(node, "ecache-line-size", 0);
1952		for (i = 0; (1 << i) < l && l; i++)
1953			/* void */;
1954		if ((1 << i) != l && l)
1955			panic("bad ecache line size %d", l);
1956		ci->ec_l2linesize = i;
1957		ci->ec_associativity =
1958			prom_getpropint(node, "ecache-associativity", 1);
1959		ci->ec_totalsize = l * ci->ec_nlines * ci->ec_associativity;
1960	}
1961}
1962
1963struct module_info module_viking_sun4d = {
1964	CPUTYP_UNKNOWN,		/* set in cpumatch() */
1965	VAC_NONE,
1966	cpumatch_viking,
1967	getcacheinfo_sun4d,
1968	viking_hotfix,
1969	viking_mmu_enable,
1970	viking_cache_enable,
1971	viking_getmid,
1972	4096,
1973	viking_get_syncflt,
1974	no_asyncflt_regs,
1975	/* supersparcs use cached DVMA, no need to flush */
1976	noop_cache_flush,
1977	noop_vcache_flush_page, NULL,
1978	noop_vcache_flush_segment, NULL,
1979	noop_vcache_flush_region, NULL,
1980	noop_vcache_flush_context, NULL,
1981	noop_vcache_flush_range, NULL,
1982	viking_pcache_flush_page,
1983	noop_pure_vcache_flush,
1984	noop_cache_flush_all,
1985	viking_memerr,
1986	pmap_zero_page4m,
1987	pmap_copy_page4m
1988};
1989#endif /* SUN4D */
1990
1991#define	ANY	-1	/* match any version */
1992
1993struct cpu_conf {
1994	int	arch;
1995	int	cpu_impl;
1996	int	cpu_vers;
1997	int	mmu_impl;
1998	int	mmu_vers;
1999	const char	*name;
2000	struct	module_info *minfo;
2001} cpu_conf[] = {
2002#if defined(SUN4)
2003	{ CPU_SUN4, 0, 0, ANY, ANY, "MB86900/1A or L64801", &module_sun4 },
2004	{ CPU_SUN4, 1, 0, ANY, ANY, "L64811", &module_sun4 },
2005	{ CPU_SUN4, 1, 1, ANY, ANY, "CY7C601", &module_sun4 },
2006#endif
2007
2008#if defined(SUN4C)
2009	{ CPU_SUN4C, 0, 0, ANY, ANY, "MB86900/1A or L64801", &module_sun4c },
2010	{ CPU_SUN4C, 1, 0, ANY, ANY, "L64811", &module_sun4c },
2011	{ CPU_SUN4C, 1, 1, ANY, ANY, "CY7C601", &module_sun4c },
2012	{ CPU_SUN4C, 9, 0, ANY, ANY, "W8601/8701 or MB86903", &module_sun4c },
2013#endif
2014
2015#if defined(SUN4M)
2016	{ CPU_SUN4M, 0, 4, 0, 4, "MB86904", &module_swift },
2017	{ CPU_SUN4M, 0, 5, 0, 5, "MB86907", &module_turbosparc },
2018	{ CPU_SUN4M, 1, 1, 1, 0, "CY7C601/604", &module_cypress },
2019	{ CPU_SUN4M, 1, 1, 1, 0xb, "CY7C601/605 (v.b)", &module_cypress },
2020	{ CPU_SUN4M, 1, 1, 1, 0xc, "CY7C601/605 (v.c)", &module_cypress },
2021	{ CPU_SUN4M, 1, 1, 1, 0xf, "CY7C601/605 (v.f)", &module_cypress },
2022	{ CPU_SUN4M, 1, 3, 1, ANY, "CY7C611", &module_cypress },
2023	{ CPU_SUN4M, 1, 0xe, 1, 7, "RT620/625", &module_hypersparc },
2024	{ CPU_SUN4M, 1, 0xf, 1, 7, "RT620/625", &module_hypersparc },
2025	{ CPU_SUN4M, 4, 0, 0, 1, "SuperSPARC v3", &module_viking },
2026	{ CPU_SUN4M, 4, 0, 0, 2, "SuperSPARC v4", &module_viking },
2027	{ CPU_SUN4M, 4, 0, 0, 3, "SuperSPARC v5", &module_viking },
2028	{ CPU_SUN4M, 4, 0, 0, 8, "SuperSPARC II v1", &module_viking },
2029	{ CPU_SUN4M, 4, 0, 0, 10, "SuperSPARC II v2", &module_viking },
2030	{ CPU_SUN4M, 4, 0, 0, 12, "SuperSPARC II v3", &module_viking },
2031	{ CPU_SUN4M, 4, 0, 0, ANY, "TMS390Z50 v0 or TMS390Z55", &module_viking },
2032	{ CPU_SUN4M, 4, 1, 0, ANY, "TMS390Z50 v1", &module_viking },
2033	{ CPU_SUN4M, 4, 1, 4, ANY, "TMS390S10", &module_ms1 },
2034	{ CPU_SUN4M, 4, 2, 0, ANY, "TI_MS2", &module_ms2 },
2035	{ CPU_SUN4M, 4, 3, ANY, ANY, "TI_4_3", &module_viking },
2036	{ CPU_SUN4M, 4, 4, ANY, ANY, "TI_4_4", &module_viking },
2037#endif
2038
2039#if defined(SUN4D)
2040	{ CPU_SUN4D, 4, 0, 0, ANY, "TMS390Z50 v0 or TMS390Z55",
2041	  &module_viking_sun4d },
2042#endif
2043
2044	{ ANY, ANY, ANY, ANY, ANY, "Unknown", &module_unknown }
2045};
2046
2047void
2048getcpuinfo(struct cpu_info *sc, int node)
2049{
2050	struct cpu_conf *mp;
2051	int i;
2052	int cpu_impl, cpu_vers;
2053	int mmu_impl, mmu_vers;
2054
2055	/*
2056	 * Set up main criteria for selection from the CPU configuration
2057	 * table: the CPU implementation/version fields from the PSR
2058	 * register, and -- on sun4m machines -- the MMU
2059	 * implementation/version from the SCR register.
2060	 */
2061	if (sc->master) {
2062		i = getpsr();
2063		if (node == 0 ||
2064		    (cpu_impl =
2065		     prom_getpropint(node, "psr-implementation", -1)) == -1)
2066			cpu_impl = IU_IMPL(i);
2067
2068		if (node == 0 ||
2069		    (cpu_vers = prom_getpropint(node, "psr-version", -1)) == -1)
2070			cpu_vers = IU_VERS(i);
2071
2072		if (CPU_HAS_SRMMU) {
2073			i = lda(SRMMU_PCR, ASI_SRMMU);
2074			if (node == 0 ||
2075			    (mmu_impl =
2076			     prom_getpropint(node, "implementation", -1)) == -1)
2077				mmu_impl = SRMMU_IMPL(i);
2078
2079			if (node == 0 ||
2080			    (mmu_vers = prom_getpropint(node, "version", -1)) == -1)
2081				mmu_vers = SRMMU_VERS(i);
2082		} else {
2083			mmu_impl = ANY;
2084			mmu_vers = ANY;
2085		}
2086	} else {
2087		/*
2088		 * Get CPU version/implementation from ROM. If not
2089		 * available, assume same as boot CPU.
2090		 */
2091		cpu_impl = prom_getpropint(node, "psr-implementation",
2092					   cpuinfo.cpu_impl);
2093		cpu_vers = prom_getpropint(node, "psr-version",
2094					   cpuinfo.cpu_vers);
2095
2096		/* Get MMU version/implementation from ROM always */
2097		mmu_impl = prom_getpropint(node, "implementation", -1);
2098		mmu_vers = prom_getpropint(node, "version", -1);
2099	}
2100
2101	if (node != 0) {
2102		char *cpu_name;
2103		char namebuf[64];
2104
2105		cpu_name = prom_getpropstringA(node, "name", namebuf,
2106					       sizeof namebuf);
2107		if (cpu_name && cpu_name[0])
2108			sc->cpu_longname = kmem_strdupsize(cpu_name, NULL,
2109							   KM_SLEEP);
2110	}
2111
2112	for (mp = cpu_conf; ; mp++) {
2113		if (mp->arch != cputyp && mp->arch != ANY)
2114			continue;
2115
2116#define MATCH(x)	(mp->x == x || mp->x == ANY)
2117		if (!MATCH(cpu_impl) ||
2118		    !MATCH(cpu_vers) ||
2119		    !MATCH(mmu_impl) ||
2120		    !MATCH(mmu_vers))
2121			continue;
2122#undef MATCH
2123
2124		/*
2125		 * Got CPU type.
2126		 */
2127		sc->cpu_impl = cpu_impl;
2128		sc->cpu_vers = cpu_vers;
2129		sc->mmu_impl = mmu_impl;
2130		sc->mmu_vers = mmu_vers;
2131
2132		if (mp->minfo->cpu_match) {
2133			/* Additional fixups */
2134			mp->minfo->cpu_match(sc, mp->minfo, node);
2135		}
2136		if (sc->cpu_longname == 0)
2137			sc->cpu_longname = mp->name;
2138
2139		if (sc->mmu_ncontext == 0)
2140			sc->mmu_ncontext = mp->minfo->ncontext;
2141
2142		if (sc->cpu_type == 0)
2143			sc->cpu_type = mp->minfo->cpu_type;
2144
2145		if (sc->cacheinfo.c_vactype == VAC_UNKNOWN)
2146			sc->cacheinfo.c_vactype = mp->minfo->vactype;
2147
2148		if (sc->master && mp->minfo->getmid != NULL)
2149			bootmid = mp->minfo->getmid();
2150
2151		mp->minfo->getcacheinfo(sc, node);
2152
2153		if (node && sc->hz == 0 && !CPU_ISSUN4/*XXX*/) {
2154			sc->hz = prom_getpropint(node, "clock-frequency", 0);
2155			if (sc->hz == 0) {
2156				/*
2157				 * Try to find it in the OpenPROM root...
2158				 */
2159				sc->hz = prom_getpropint(findroot(),
2160						    "clock-frequency", 0);
2161			}
2162		}
2163
2164		/*
2165		 * Copy CPU/MMU/Cache specific routines into cpu_info.
2166		 */
2167#define MPCOPY(x)	if (sc->x == 0) sc->x = mp->minfo->x;
2168		MPCOPY(hotfix);
2169		MPCOPY(mmu_enable);
2170		MPCOPY(cache_enable);
2171		MPCOPY(get_syncflt);
2172		MPCOPY(get_asyncflt);
2173		MPCOPY(cache_flush);
2174		MPCOPY(sp_vcache_flush_page);
2175		MPCOPY(sp_vcache_flush_segment);
2176		MPCOPY(sp_vcache_flush_region);
2177		MPCOPY(sp_vcache_flush_context);
2178		MPCOPY(sp_vcache_flush_range);
2179		MPCOPY(ft_vcache_flush_page);
2180		MPCOPY(ft_vcache_flush_segment);
2181		MPCOPY(ft_vcache_flush_region);
2182		MPCOPY(ft_vcache_flush_context);
2183		MPCOPY(ft_vcache_flush_range);
2184		MPCOPY(pcache_flush_page);
2185		MPCOPY(pure_vcache_flush);
2186		MPCOPY(cache_flush_all);
2187		MPCOPY(memerr);
2188		MPCOPY(zero_page);
2189		MPCOPY(copy_page);
2190#undef MPCOPY
2191		/*
2192		 * Use the single-processor cache flush functions until
2193		 * all CPUs are initialized.
2194		 */
2195		sc->vcache_flush_page = sc->sp_vcache_flush_page;
2196		sc->vcache_flush_segment = sc->sp_vcache_flush_segment;
2197		sc->vcache_flush_region = sc->sp_vcache_flush_region;
2198		sc->vcache_flush_context = sc->sp_vcache_flush_context;
2199		(*sc->cache_flush_all)();
2200		return;
2201	}
2202	panic("Out of CPUs");
2203}
2204
2205/*
2206 * The following tables convert <IU impl, IU version, FPU version> triples
2207 * into names for the CPU and FPU chip.  In most cases we do not need to
2208 * inspect the FPU version to name the IU chip, but there is one exception
2209 * (for Tsunami), and this makes the tables the same.
2210 *
2211 * The table contents (and much of the structure here) are from Guy Harris.
2212 *
2213 */
2214struct info {
2215	int	valid;
2216	int	iu_impl;
2217	int	iu_vers;
2218	int	fpu_vers;
2219	const char	*name;
2220};
2221
2222/* XXX trim this table on a per-ARCH basis */
2223/* NB: table order matters here; specific numbers must appear before ANY. */
2224static struct info fpu_types[] = {
2225	/*
2226	 * Vendor 0, IU Fujitsu0.
2227	 */
2228	{ 1, 0x0, ANY, 0, "MB86910 or WTL1164/5" },
2229	{ 1, 0x0, ANY, 1, "MB86911 or WTL1164/5" },
2230	{ 1, 0x0, ANY, 2, "L64802 or ACT8847" },
2231	{ 1, 0x0, ANY, 3, "WTL3170/2" },
2232	{ 1, 0x0, 4,   4, "on-chip" },		/* Swift */
2233	{ 1, 0x0, 5,   5, "on-chip" },		/* TurboSparc */
2234	{ 1, 0x0, ANY, 4, "L64804" },
2235
2236	/*
2237	 * Vendor 1, IU ROSS0/1 or Pinnacle.
2238	 */
2239	{ 1, 0x1, 0xf, 0, "on-chip" },		/* Pinnacle */
2240	{ 1, 0x1, 0xe, 0, "on-chip" },		/* Hypersparc RT 625/626 */
2241	{ 1, 0x1, ANY, 0, "L64812 or ACT8847" },
2242	{ 1, 0x1, ANY, 1, "L64814" },
2243	{ 1, 0x1, ANY, 2, "TMS390C602A" },
2244	{ 1, 0x1, ANY, 3, "RT602 or WTL3171" },
2245
2246	/*
2247	 * Vendor 2, IU BIT0.
2248	 */
2249	{ 1, 0x2, ANY, 0, "B5010 or B5110/20 or B5210" },
2250
2251	/*
2252	 * Vendor 4, Texas Instruments.
2253	 */
2254	{ 1, 0x4, ANY, 0, "on-chip" },		/* Viking */
2255	{ 1, 0x4, ANY, 4, "on-chip" },		/* Tsunami */
2256
2257	/*
2258	 * Vendor 5, IU Matsushita0.
2259	 */
2260	{ 1, 0x5, ANY, 0, "on-chip" },
2261
2262	/*
2263	 * Vendor 9, Weitek.
2264	 */
2265	{ 1, 0x9, ANY, 3, "on-chip" },
2266
2267	{ 0 }
2268};
2269
2270static const char *
2271fsrtoname(int impl, int vers, int fver)
2272{
2273	struct info *p;
2274
2275	for (p = fpu_types; p->valid; p++) {
2276		if (p->iu_impl == impl &&
2277		    (p->iu_vers == vers || p->iu_vers == ANY) &&
2278		    (p->fpu_vers == fver))
2279			return (p->name);
2280	}
2281	return (NULL);
2282}
2283
2284#ifdef DDB
2285
2286#include <ddb/db_output.h>
2287#include <machine/db_machdep.h>
2288
2289#include "ioconf.h"
2290
2291/*
2292 * Dump CPU information from ddb.
2293 */
2294void
2295cpu_debug_dump(void)
2296{
2297	struct cpu_info *ci;
2298	CPU_INFO_ITERATOR cii;
2299
2300	db_printf("%-4s %-10s %-8s %-10s %-10s %-10s %-10s\n",
2301	    "CPU#", "CPUINFO", "FLAGS", "CURLWP", "CURPROC", "FPLWP", "CPCB");
2302	for (CPU_INFO_FOREACH(cii, ci)) {
2303		db_printf("%-4d %-10p %-8x %-10p %-10p %-10p %-10p\n",
2304		    ci->ci_cpuid,
2305		    ci,
2306		    ci->flags,
2307		    ci->ci_curlwp,
2308		    ci->ci_curlwp == NULL ? NULL : ci->ci_curlwp->l_proc,
2309		    ci->fplwp,
2310		    ci->curpcb);
2311	}
2312}
2313
2314#if defined(MULTIPROCESSOR)
2315/*
2316 * Dump CPU xcall from ddb.
2317 */
2318void
2319cpu_xcall_dump(void)
2320{
2321	struct cpu_info *ci;
2322	CPU_INFO_ITERATOR cii;
2323
2324	db_printf("%-4s %-10s %-10s %-10s %-10s %-10s "
2325		    "%-4s %-4s %-4s\n",
2326	          "CPU#", "FUNC", "TRAP", "ARG0", "ARG1", "ARG2",
2327	            "TAG", "RECV", "COMPL");
2328	for (CPU_INFO_FOREACH(cii, ci)) {
2329		db_printf("%-4d %-10p %-10p 0x%-8x 0x%-8x 0x%-8x "
2330			    "%-4d %-4d %-4d\n",
2331		    ci->ci_cpuid,
2332		    ci->msg.u.xpmsg_func.func,
2333		    ci->msg.u.xpmsg_func.trap,
2334		    ci->msg.u.xpmsg_func.arg0,
2335		    ci->msg.u.xpmsg_func.arg1,
2336		    ci->msg.u.xpmsg_func.arg2,
2337		    ci->msg.tag,
2338		    ci->msg.received,
2339		    ci->msg.complete);
2340	}
2341}
2342#endif
2343
2344#endif
2345