xref: /netbsd-src/sys/arch/sgimips/sgimips/machdep.c (revision 6914ee8e71d447d84cdc30c48462d00816f52a6b)
1 /*	$NetBSD: machdep.c,v 1.156 2024/05/23 06:14:12 skrll Exp $	*/
2 
3 /*
4  * Copyright (c) 2000 Soren S. Jorvang
5  * Copyright (c) 2001, 2002, 2003 Rafal K. Boni
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *          This product includes software developed for the
19  *          NetBSD Project.  See http://www.NetBSD.org/ for
20  *          information about NetBSD.
21  * 4. The name of the author may not be used to endorse or promote products
22  *    derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.156 2024/05/23 06:14:12 skrll Exp $");
38 
39 #include "opt_ddb.h"
40 #include "opt_kgdb.h"
41 #include "opt_execfmt.h"
42 #include "opt_cputype.h"
43 #include "opt_mips_cache.h"
44 #include "opt_modular.h"
45 
46 #define __INTR_PRIVATE
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/proc.h>
52 #include <sys/buf.h>
53 #include <sys/bus.h>
54 #include <sys/reboot.h>
55 #include <sys/conf.h>
56 #include <sys/file.h>
57 #include <sys/intr.h>
58 #include <sys/mbuf.h>
59 #include <sys/msgbuf.h>
60 #include <sys/device.h>
61 #include <sys/exec.h>
62 #include <sys/mount.h>
63 #include <sys/syscallargs.h>
64 #include <sys/kcore.h>
65 #include <sys/boot_flag.h>
66 #include <sys/ksyms.h>
67 #include <sys/cpu.h>
68 
69 #include <uvm/uvm_extern.h>
70 
71 #include <mips/locore.h>
72 
73 #include <machine/reg.h>
74 #include <machine/psl.h>
75 #include <machine/autoconf.h>
76 #include <machine/machtype.h>
77 #include <machine/sysconf.h>
78 #include <machine/bootinfo.h>
79 
80 #include <mips/cache.h>
81 #include <mips/cache_r5k.h>
82 #ifdef ENABLE_MIPS4_CACHE_R10K
83 #include <mips/cache_r10k.h>
84 #endif
85 
86 #include <sgimips/dev/int2reg.h>
87 #include <sgimips/dev/crimevar.h>
88 #include <sgimips/sgimips/arcemu.h>
89 
90 #include <dev/arcbios/arcbios.h>
91 #include <dev/arcbios/arcbiosvar.h>
92 
93 #include "ksyms.h"
94 
95 #if NKSYMS || defined(DDB) || defined(MODULAR) || defined(KGDB)
96 #include <machine/db_machdep.h>
97 #include <ddb/db_access.h>
98 #include <ddb/db_sym.h>
99 #include <ddb/db_extern.h>
100 #include <sys/exec_elf.h>
101 #endif
102 
103 #include "mcclock_mace.h"
104 #include "crime.h"
105 
106 #if NMCCLOCK_MACE > 0
107 void mcclock_poweroff(void);
108 #endif
109 
110 struct sgimips_intrhand intrtab[NINTR];
111 
112 /* Maps for VM objects. */
113 struct vm_map *phys_map = NULL;
114 
115 int mach_type = 0;	/* IPxx type */
116 int mach_subtype = 0;	/* subtype: eg., Guinness/Fullhouse for IP22 */
117 int mach_boardrev = 0;	/* machine board revision, in case it matters */
118 
119 int arcsmem;		/* Memory used by the ARCS firmware */
120 
121 int ncpus;
122 
123 #define IPL2SPL_TABLE_COMMON					\
124 	[IPL_NONE] =		0,				\
125 	[IPL_SOFTCLOCK] =	MIPS_SOFT_INT_MASK_0,		\
126 	[IPL_SOFTNET] =		MIPS_SOFT_INT_MASK,		\
127 	[IPL_DDB] =		MIPS_INT_MASK,			\
128 	[IPL_HIGH] =		MIPS_INT_MASK
129 
130 /* CPU interrupt sr maps */
131 #if defined(MIPS1)
132 static const struct ipl_sr_map sgi_ip6_ipl_sr_map = {
133     .sr_bits = {
134 	IPL2SPL_TABLE_COMMON,
135 	[IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK,
136 	[IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_2|
137 	    MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK,
138     },
139 };
140 static const struct ipl_sr_map sgi_ip12_ipl_sr_map = {
141     .sr_bits = {
142 	IPL2SPL_TABLE_COMMON,
143 	[IPL_VM] = MIPS_INT_MASK_2|MIPS_INT_MASK_1|MIPS_INT_MASK_0|
144 	    MIPS_SOFT_INT_MASK,
145 	[IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_3|MIPS_INT_MASK_2|
146 	    MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK,
147     },
148 };
149 #endif /* defined(MIPS1) */
150 
151 #if defined(MIPS3)
152 static const struct ipl_sr_map sgi_ip2x_ipl_sr_map = {
153     .sr_bits = {
154 	IPL2SPL_TABLE_COMMON,
155 	[IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK,
156 	[IPL_SCHED] = MIPS_INT_MASK,
157     },
158 };
159 static const struct ipl_sr_map sgi_ip3x_ipl_sr_map = {
160     .sr_bits = {
161 	IPL2SPL_TABLE_COMMON,
162 	[IPL_VM] = MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK,
163 	[IPL_SCHED] = MIPS_INT_MASK_5|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK,
164     },
165 };
166 #endif /* defined(MIPS3) */
167 
168 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
169 int mem_cluster_cnt;
170 
171 #if defined(INDY_R4600_CACHE)
172 extern void	ip22_sdcache_disable(void);
173 extern void	ip22_sdcache_enable(void);
174 #endif
175 
176 #if defined(MIPS3)
177 extern void mips3_clock_intr(vaddr_t, uint32_t, uint32_t);
178 #endif
179 
180 void	mach_init(int, int32_t *, uintptr_t, int32_t);
181 
182 void	sgimips_count_cpus(struct arcbios_component *,
183 	    struct arcbios_treewalk_context *);
184 
185 #ifdef KGDB
186 void kgdb_port_init(void);
187 void kgdb_connect(int);
188 #endif
189 
190 void mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc);
191 
192 /* Motherboard or system-specific initialization vector */
193 static void	unimpl_bus_reset(void);
194 static void	unimpl_cons_init(void);
195 static void	*unimpl_intr_establish(int, int, int (*)(void *), void *);
196 static void	unimpl_intr(vaddr_t, uint32_t, uint32_t);
197 static unsigned	long nulllong(void);
198 static void	nullvoid(void);
199 
200 void ddb_trap_hook(int where);
201 
202 static int badaddr_workaround(void *, size_t);
203 
204 struct platform platform = {
205 	.badaddr		= badaddr_workaround,
206 	.bus_reset		= unimpl_bus_reset,
207 	.cons_init		= unimpl_cons_init,
208 	.intr_establish		= unimpl_intr_establish,
209 	.clkread		= nulllong,
210 	.watchdog_reset		= nullvoid,
211 	.watchdog_disable	= nullvoid,
212 	.watchdog_enable	= nullvoid,
213 	.intr0			= unimpl_intr,
214 	.intr1			= unimpl_intr,
215 	.intr2			= unimpl_intr,
216 	.intr3			= unimpl_intr,
217 	.intr4			= unimpl_intr,
218 	.intr5			= unimpl_intr
219 };
220 
221 extern u_int32_t ssir;
222 extern char kernel_text[], edata[], end[];
223 
224 uint8_t *bootinfo;			/* pointer to bootinfo structure */
225 static uint8_t bi_buf[BOOTINFO_SIZE];	/* buffer to store bootinfo data */
226 static const char *bootinfo_msg = NULL;
227 
228 #define ARCS_VECTOR MIPS_PHYS_TO_KSEG0(0x00001000)
229 
230 /*
231  * Do all the stuff that locore normally does before calling main().
232  * Process arguments passed to us by the ARCS firmware.
233  */
234 void
mach_init(int argc,int32_t argv32[],uintptr_t magic,int32_t bip32)235 mach_init(int argc, int32_t argv32[], uintptr_t magic, int32_t bip32)
236 {
237 	paddr_t first, last;
238 	vsize_t size;
239 	void *bip = (void *)(intptr_t)bip32;
240 	struct arcbios_mem *mem;
241 	const char *cpufreq, *osload;
242 	char *bootpath = NULL;
243 	vaddr_t kernend;
244 	u_int i;
245 	int rv;
246 #if NKSYMS || defined(DDB) || defined(MODULAR)
247 	int nsym = 0;
248 	char *ssym = NULL;
249 	char *esym = NULL;
250 	struct btinfo_symtab *bi_syms;
251 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */
252 #ifdef _LP64
253 	char *argv[20];
254 
255 	if (argc >= __arraycount(argv))
256 		panic("too many args");
257 
258 	for (i = 0; i < argc; i++) {
259 		argv[i] = (void *)(intptr_t)argv32[i];
260 	}
261 #else
262 	char **argv = (void *)argv32;
263 #endif
264 
265 	/*
266 	 * Initialize firmware.  This will set up the bootstrap console.
267 	 * At this point we do not yet know the machine type, so we
268 	 * try to init real arcbios, and if that fails (return value 1),
269 	 * fall back to the emulator.  If the latter fails also we
270 	 * don't have much to panic with.
271 	 *
272 	 * The third argument (magic) is the environment variable array if
273 	 * there's no bootinfo.
274 	 */
275 	if (arcbios_init(ARCS_VECTOR) == 1) {
276 #ifdef _LP64
277 		panic("no ARCS firmware");
278 #else
279 		if (magic == BOOTINFO_MAGIC)
280 			arcemu_init(NULL);	/* XXX - need some prom env */
281 		else
282 			arcemu_init((const char **)magic);
283 #endif
284 	}
285 
286 	cpu_setmodel("%s", arcbios_system_identifier);
287 
288 	/*
289 	 * Copy exception-dispatch code down to exception vector.
290 	 * Initialize locore-function vector.
291 	 * Clear out the I and D caches.
292 	 */
293 	mips_vector_init(NULL, false);
294 
295 	uvm_md_init();
296 
297 	/* set up bootinfo structures */
298 	if (magic == BOOTINFO_MAGIC && bip != NULL) {
299 		struct btinfo_magic *bi_magic;
300 		struct btinfo_bootpath *bi_path;
301 
302 		memcpy(bi_buf, bip, BOOTINFO_SIZE);
303 		bootinfo = bi_buf;
304 		bi_magic = lookup_bootinfo(BTINFO_MAGIC);
305 		if (bi_magic != NULL && bi_magic->magic == BOOTINFO_MAGIC) {
306 			bootinfo_msg = "bootinfo found.\n";
307 			bi_path = lookup_bootinfo(BTINFO_BOOTPATH);
308 			if (bi_path != NULL)
309 				bootpath = bi_path->bootpath;
310 		} else
311 			bootinfo_msg =
312 			    "invalid magic number in bootinfo structure.\n";
313 	} else
314 		bootinfo_msg = "no bootinfo found. (old bootblocks?)\n";
315 
316 #if NKSYMS || defined(DDB) || defined(MODULAR)
317 	bi_syms = lookup_bootinfo(BTINFO_SYMTAB);
318 
319 	/* check whether there is valid bootinfo symtab info */
320 	if (bi_syms != NULL) {
321 		nsym = bi_syms->nsym;
322 		ssym = (char *)bi_syms->ssym;
323 		esym = (char *)bi_syms->esym;
324 		kernend = mips_round_page(esym);
325 	} else
326 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */
327 	{
328 		kernend = mips_round_page(end);
329 	}
330 
331 	cpufreq = arcbios_GetEnvironmentVariable("cpufreq");
332 
333 	if (cpufreq == 0)
334 		panic("no $cpufreq");
335 
336 	/*
337 	 * Note initial estimate of CPU speed... If we care enough, we'll
338 	 * use the RTC to get a better estimate later.
339 	 */
340 	curcpu()->ci_cpu_freq = strtoul(cpufreq, NULL, 10) * 1000000;
341 
342 	/*
343 	 * Also initialize ci members for delay and clock by the temporary
344 	 * ci_cpu_freq value for early use of delay(9).
345 	 * These values will be calibrated later in MD code:
346 	 *  - int_attach() in dev/int.c for IP6/10/12/20/22
347 	 *  - crime_attach() in dev/crime.c for IP32
348 	 *
349 	 * XXX: ci_divisor_delay is for mips3_delay() in mips/mips3_clock.c
350 	 *      but sgimips abuse it as "instructions per microsecond"
351 	 *      for traditional delay(9) implementation derived from
352 	 *      4.4BSD/mips (also used in pmax and news3400).
353 	 *	(see sys/arch/mips/mips/mips_mcclock.c etc.)
354 	 *
355 	 * Note ci_cycles_per_hz is for mips3_clockintr.c for MIPS3 so
356 	 * there is no early use, but initialize it as a sane default.
357 	 */
358 	curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / (2 * hz);
359 	curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / (2 * 1000000);
360 
361 	/*
362 	 * Check machine (IPn) type.
363 	 *
364 	 * Note even on IP12 (which doesn't have ARCBIOS),
365 	 * arcbios_system_identifiler[] has been initilialized
366 	 * in arcemu_ip12_init().
367 	 */
368 	for (i = 0; arcbios_system_identifier[i] != '\0'; i++) {
369 		if (mach_type == 0 &&
370 		    arcbios_system_identifier[i] >= '0' &&
371 		    arcbios_system_identifier[i] <= '9') {
372 			mach_type = strtoul(&arcbios_system_identifier[i],
373 			    NULL, 10);
374 			break;
375 		}
376 	}
377 	if (mach_type <= 0)
378 		panic("invalid architecture");
379 
380 	/*
381 	 * Get boot device information.
382 	 */
383 
384 	/* Try to get the boot device information from bootinfo first. */
385 	if (bootpath != NULL)
386 		makebootdev(bootpath);
387 	else {
388 		/*
389 		 * The old bootloader prior to 5.0 doesn't pass bootinfo.
390 		 * If argv[0] is the bootloader, then argv[1] might be
391 		 * the kernel that was loaded.
392 		 * If argv[1] isn't an environment string, try to use it
393 		 * to set the boot device.
394 		 */
395 		if (argc > 1 && strchr(argv[1], '=') != 0)
396 			makebootdev(argv[1]);
397 
398 		/*
399 		 * If we are loaded directly by ARCBIOS,
400 		 * argv[0] is the path of the loaded kernel,
401 		 * but booted_partition could be SGIVOLHDR in such case,
402 		 * so assume root is partition a.
403 		 */
404 		if (argc > 0 && argv[0] != NULL) {
405 			makebootdev(argv[0]);
406 			booted_partition = 0;
407 		}
408 	}
409 
410 	/*
411 	 * Also try to get the default bootpath from ARCBIOS environment
412 	 * because bootpath is not set properly by old bootloaders and
413 	 * argv[0] might be invalid on some machine.
414 	 */
415 	osload = arcbios_GetEnvironmentVariable("OSLoadPartition");
416 	if (osload != NULL)
417 		makebootdev(osload);
418 
419 	/*
420 	 * The case where the kernel has been loaded by a
421 	 * boot loader will usually have been caught by
422 	 * the first makebootdev() case earlier on, but
423 	 * we still use OSLoadPartition to get the preferred
424 	 * root filesystem location, even if it's not
425 	 * actually the location of the loaded kernel.
426 	 */
427 	for (i = 0; i < argc; i++) {
428 		if (strncmp(argv[i], "OSLoadPartition=", 15) == 0)
429 			makebootdev(argv[i] + 16);
430 	}
431 
432 	/*
433 	 * When the kernel is loaded directly by the firmware, and
434 	 * no explicit OSLoadPartition is set, we fall back on
435 	 * SystemPartition for the boot device.
436 	 */
437 	for (i = 0; i < argc; i++) {
438 		if (strncmp(argv[i], "SystemPartition", 15) == 0)
439 			makebootdev(argv[i] + 16);
440 	}
441 
442 	/*
443 	 * Single- or multi-user ('auto' in SGI terms).
444 	 *
445 	 * Query ARCBIOS first, then default to environment variables.
446 	 */
447 
448 	/* Set default to single user. */
449 	boothowto = RB_SINGLE;
450 
451 	osload = arcbios_GetEnvironmentVariable("OSLoadOptions");
452 	if (osload != NULL && strcmp(osload, "auto") == 0)
453 		boothowto &= ~RB_SINGLE;
454 
455 	for (i = 0; i < argc; i++) {
456 		if (strcmp(argv[i], "OSLoadOptions=auto") == 0)
457 			boothowto &= ~RB_SINGLE;
458 	}
459 
460 	/*
461 	 * Pass the args again to check for flags -- This is done
462 	 * AFTER checking for OSLoadOptions to ensure that "auto"
463 	 * does not override the "-s" flag.
464 	 */
465 
466 	for (i = 0; i < argc; i++) {
467 		/*
468 		 * Unfortunately, it appears that IP12's prom passes a '-a'
469 		 * flag when booting a kernel directly from a disk volume
470 		 * header. This corresponds to RB_ASKNAME in NetBSD, but
471 		 * appears to mean 'autoboot' in prehistoric SGI-speak.
472 		 */
473 		if (mach_type < MACH_SGI_IP20 && bootinfo == NULL &&
474 		    strcmp(argv[i], "-a") == 0)
475 			continue;
476 
477 		/*
478 		 * Extract out any flags passed for the kernel in the
479 		 * argument string.  Warn for unknown/invalid flags,
480 		 * but silently skip non-flag arguments, as they are
481 		 * likely PROM environment values (if I knew those
482 		 * would always precede *any* flags, then I'd say we
483 		 * should warn about *all* unexpected values, but for
484 		 * now this should be fine).
485 		 *
486 		 * Use the MI boot-flag extractor since we don't use
487 		 * any special MD flags and to make sure we're up-to
488 		 * date with new MI flags whenever they're added.
489 		 */
490 		if (argv[i][0] == '-') {
491 			rv = 0;
492 			BOOT_FLAG(argv[i][1], rv);
493 
494 			if (rv == 0) {
495 				printf("Unexpected option '%s' ignored",
496 				    argv[i]);
497 			} else {
498 				boothowto |= rv;
499 			}
500 		}
501 	}
502 
503 #ifdef DEBUG
504 	boothowto |= AB_DEBUG;
505 #endif
506 	aprint_debug("argc = %d\n", argc);
507 	for (i = 0; i < argc; i++)
508 		aprint_debug("argv[%d] = %s\n", i, argv[i]);
509 
510 #if NKSYMS || defined(DDB) || defined(MODULAR)
511 	/* init symbols if present */
512 	if (esym)
513 		ksyms_addsyms_elf(nsym, ssym, esym);
514 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */
515 
516 #if defined(KGDB) || defined(DDB)
517 	/* Set up DDB hook to turn off watchdog on entry */
518 	db_trap_callback = ddb_trap_hook;
519 
520 #ifdef DDB
521 	if (boothowto & RB_KDB)
522 		Debugger();
523 #endif
524 
525 #ifdef KGDB
526 	kgdb_port_init();
527 
528 	if (boothowto & RB_KDB)
529 		kgdb_connect(0);
530 #endif
531 #endif
532 
533 	switch (mach_type) {
534 #if defined(MIPS1)
535 	case MACH_SGI_IP6 | MACH_SGI_IP10:
536 		platform.intr3 = mips1_fpu_intr;
537 		ipl_sr_map = sgi_ip6_ipl_sr_map;
538 		break;
539 
540 	case MACH_SGI_IP12:
541 		i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000);
542         	mach_boardrev = (i & 0x7000) >> 12;
543 
544 		if ((i & 0x8000) == 0) {
545 			if (mach_boardrev < 7)
546 				mach_subtype = MACH_SGI_IP12_4D_3X;
547 			else
548 				mach_subtype = MACH_SGI_IP12_VIP12;
549 		} else {
550 			if (mach_boardrev < 6)
551 				mach_subtype = MACH_SGI_IP12_HP1;
552 			else
553 				mach_subtype = MACH_SGI_IP12_HPLC;
554                 }
555 
556 		ipl_sr_map = sgi_ip12_ipl_sr_map;
557 		platform.intr0 = mips1_fpu_intr;
558 		break;
559 #endif /* MIPS1 */
560 
561 #if defined(MIPS3)
562 	case MACH_SGI_IP20:
563 		i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000);
564 		mach_boardrev = (i & 0x7000) >> 12;
565 		ipl_sr_map = sgi_ip2x_ipl_sr_map;
566 		platform.intr5 = mips3_clock_intr;
567 		break;
568 	case MACH_SGI_IP22:
569 		ipl_sr_map = sgi_ip2x_ipl_sr_map;
570 		platform.intr5 = mips3_clock_intr;
571 		break;
572 	case MACH_SGI_IP30:
573 		ipl_sr_map = sgi_ip3x_ipl_sr_map;
574 		platform.intr5 = mips3_clock_intr;
575 		break;
576 	case MACH_SGI_IP32:
577 		ipl_sr_map = sgi_ip3x_ipl_sr_map;
578 		platform.intr5 = mips3_clock_intr;
579 		break;
580 #endif /* MIPS3 */
581 	default:
582 		panic("IP%d architecture not supported", mach_type);
583 		break;
584 	}
585 
586 	physmem = arcsmem = 0;
587 	mem_cluster_cnt = 0;
588 	mem = NULL;
589 
590 #ifdef DEBUG
591 	i = 0;
592 	mem = NULL;
593 
594 	do {
595 		if ((mem = arcbios_GetMemoryDescriptor(mem)) != NULL) {
596 			i++;
597 			printf("Mem block %d: type %d, "
598 			    "base 0x%04"PRIx32", size 0x%04"PRIx32"\n",
599 			    i, mem->Type, mem->BasePage, mem->PageCount);
600 		}
601 	} while (mem != NULL);
602 #endif
603 
604 	/*
605 	 * XXX This code assumes that ARCS provides the memory
606 	 * XXX sorted in ascending order.
607 	 */
608 	mem = NULL;
609 	for (i = 0; mem_cluster_cnt < VM_PHYSSEG_MAX; i++) {
610 		mem = arcbios_GetMemoryDescriptor(mem);
611 
612 		if (mem == NULL)
613 			break;
614 
615 		first = round_page(mem->BasePage * ARCBIOS_PAGESIZE);
616 		last = trunc_page(first + mem->PageCount * ARCBIOS_PAGESIZE);
617 		size = last - first;
618 
619 		switch (mem->Type) {
620 		case ARCBIOS_MEM_FreeContiguous:
621 		case ARCBIOS_MEM_FreeMemory:
622 		case ARCBIOS_MEM_LoadedProgram:
623 			mem_clusters[mem_cluster_cnt].start = first;
624 			mem_clusters[mem_cluster_cnt].size = size;
625 			mem_cluster_cnt++;
626 			break;
627 
628 		case ARCBIOS_MEM_FirmwareTemporary:
629 		case ARCBIOS_MEM_FirmwarePermanent:
630 			arcsmem += btoc(size);
631 			break;
632 
633 		case ARCBIOS_MEM_ExceptionBlock:
634 		case ARCBIOS_MEM_SystemParameterBlock:
635 		case ARCBIOS_MEM_BadMemory:
636 			break;
637 
638 		default:
639 			panic("unknown memory descriptor %d type %d",
640 				i, mem->Type);
641 		}
642 
643 		physmem += btoc(size);
644 
645 	}
646 
647 	if (mem_cluster_cnt == 0)
648 		panic("no free memory descriptors found");
649 
650 	/* Leave 1 page before kernel untouched as that's where our initial
651 	 * kernel stack is */
652 	/* XXX We could free it in cpu_startup() though XXX */
653 	mips_page_physload((vaddr_t)kernel_text - PAGE_SIZE, (vaddr_t)kernend,
654 	    mem_clusters, mem_cluster_cnt, NULL, 0);
655 
656 	/* We can now no longer use bootinfo. */
657 	bootinfo = NULL;
658 
659 	/*
660 	 * Initialize mips version-dependent DMA handlers.
661 	 */
662 	sgimips_bus_dma_init();
663 
664 	/*
665 	 * Walk the component tree and count the number of CPUs
666 	 * present in the system.
667 	 */
668 	arcbios_tree_walk(sgimips_count_cpus, NULL);
669 
670 	/*
671 	 * Initialize error message buffer (at end of core).
672 	 */
673 	mips_init_msgbuf();
674 
675 	pmap_bootstrap();
676 
677 	/*
678 	 * Allocate uarea for lwp0 and set it.
679 	 */
680 	mips_init_lwp0_uarea();
681 }
682 
683 void
sgimips_count_cpus(struct arcbios_component * node,struct arcbios_treewalk_context * atc)684 sgimips_count_cpus(struct arcbios_component *node,
685     struct arcbios_treewalk_context *atc)
686 {
687 
688 	switch (node->Class) {
689 	case COMPONENT_CLASS_ProcessorClass:
690 		if (node->Type == COMPONENT_TYPE_CPU)
691 			ncpus++;
692 		break;
693 
694 	default:
695 		break;
696 	}
697 }
698 
699 /*
700  * Allocate memory for variable-sized tables.
701  */
702 void
cpu_startup(void)703 cpu_startup(void)
704 {
705 	vaddr_t minaddr, maxaddr;
706 	char pbuf[9];
707 
708 #ifdef BOOTINFO_DEBUG
709 	if (bootinfo_msg)
710 		printf(bootinfo_msg);
711 #endif
712 
713 	printf("%s%s", copyright, version);
714 
715 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
716 	printf("total memory = %s\n", pbuf);
717 	format_bytes(pbuf, sizeof(pbuf), ctob(arcsmem));
718 	printf("(%s reserved for ARCS)\n", pbuf);
719 
720 	minaddr = 0;
721 	/*
722 	 * Allocate a submap for physio.
723 	 */
724 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
725 				    VM_PHYS_SIZE, 0, false, NULL);
726 
727 	/*
728 	 * (No need to allocate an mbuf cluster submap.  Mbuf clusters
729 	 * are allocated via the pool allocator, and we use KSEG to
730 	 * map those pages.)
731 	 */
732 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
733 	printf("avail memory = %s\n", pbuf);
734 }
735 
736 int	waittime = -1;
737 
738 void
cpu_reboot(int howto,char * bootstr)739 cpu_reboot(int howto, char *bootstr)
740 {
741 	/* Take a snapshot before clobbering any registers. */
742 	savectx(curpcb);
743 
744 	if (cold) {
745 		howto |= RB_HALT;
746 		goto haltsys;
747 	}
748 
749 	/* If "always halt" was specified as a boot flag, obey. */
750 	if (boothowto & RB_HALT)
751 		howto |= RB_HALT;
752 
753 	boothowto = howto;
754 	if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) {
755 		waittime = 0;
756 		vfs_shutdown();
757 	}
758 
759 	/* Clear and disable watchdog timer. */
760 	(void)(*platform.watchdog_disable)();
761 
762 	splhigh();
763 
764 	if (howto & RB_DUMP)
765 		dumpsys();
766 
767 haltsys:
768 
769 	doshutdownhooks();
770 
771 	pmf_system_shutdown(boothowto);
772 
773 	/*
774 	 * Calling arcbios_PowerDown() results in a "CP1 unusable trap"
775 	 * which lands me back in DDB, at least on my Indy.  So, enable
776 	 * the FPU before asking the PROM to power down to avoid this..
777 	 * It seems to want the FPU to play the `poweroff tune' 8-/
778 	 */
779 	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
780 		/* Set CP1 usable bit in SR */
781 	 	mips_cp0_status_write(mips_cp0_status_read() |
782 					MIPS_SR_COP_1_BIT);
783 
784 		printf("powering off...\n\n");
785 		delay(500000);
786 #if NMCCLOCK_MACE > 0
787 		if (mach_type == MACH_SGI_IP32) {
788 			mcclock_poweroff();
789 		} else
790 #endif
791 			arcbios_PowerDown();
792 		printf("WARNING: powerdown failed\n");
793 		/*
794 		 * RB_POWERDOWN implies RB_HALT... fall into it...
795 		 */
796 	}
797 
798 	if (howto & RB_HALT) {
799 		printf("halting...\n\n");
800 		arcbios_EnterInteractiveMode();
801 	}
802 
803 	printf("rebooting...\n\n");
804 #if NCRIME > 0
805 	if (mach_type == MACH_SGI_IP32) {
806 		crime_reboot();
807 	} else
808 #endif
809 		arcbios_Reboot();
810 
811 	for (;;);
812 }
813 
delay(unsigned long n)814 void delay(unsigned long n)
815 {
816 	register int __N = curcpu()->ci_divisor_delay * n;
817 
818 	do {
819 		__asm("addiu %0,%1,-1" : "=r" (__N) : "0" (__N));
820 	} while (__N > 0);
821 }
822 
823 /*
824  * IP12 appears to be buggy and unable to reliably support badaddr.
825  * Approximately 1.8% of the time a false negative (bad address said to
826  * be good) is generated and we stomp on invalid registers. Testing has
827  * not shown false positives, nor consecutive false negatives to occur.
828  */
829 static int
badaddr_workaround(void * addr,size_t size)830 badaddr_workaround(void *addr, size_t size)
831 {
832 	int i, bad;
833 
834 	for (i = bad = 0; i < 100; i++) {
835 		if (badaddr(addr, size))
836 			bad++;
837 	}
838 
839 	/* false positives appear not to occur */
840 	return (bad != 0);
841 }
842 
843 /*
844  *  Ensure all platform vectors are always initialized.
845  */
846 static void
unimpl_bus_reset(void)847 unimpl_bus_reset(void)
848 {
849 
850 	panic("target init didn't set bus_reset");
851 }
852 
853 static void
unimpl_cons_init(void)854 unimpl_cons_init(void)
855 {
856 
857 	panic("target init didn't set cons_init");
858 }
859 
860 static void *
unimpl_intr_establish(int level,int ipl,int (* handler)(void *),void * arg)861 unimpl_intr_establish(int level, int ipl, int (*handler) (void *), void *arg)
862 {
863 	panic("target init didn't set intr_establish");
864 	return NULL;
865 }
866 
867 static void
unimpl_intr(vaddr_t pc,uint32_t status,uint32_t pending)868 unimpl_intr(vaddr_t pc, uint32_t status, uint32_t pending)
869 {
870 	printf("spurious interrupt pending %#x\n", pending);
871 }
872 
873 static unsigned long
nulllong(void)874 nulllong(void)
875 {
876 	printf("nulllong\n");
877 	return (0);
878 }
879 
880 static void
nullvoid(void)881 nullvoid(void)
882 {
883 	printf("nullvoid\n");
884 	return;
885 }
886 
887 void *
lookup_bootinfo(int type)888 lookup_bootinfo(int type)
889 {
890 	struct btinfo_common *bt;
891 	uint8_t *bip;
892 
893 	/* check for a bootinfo record first */
894 	if (bootinfo == NULL)
895 		return NULL;
896 
897 	bip = bootinfo;
898 	do {
899 		bt = (struct btinfo_common *)bip;
900 		if (bt->type == type)
901 			return (void *)bt;
902 		bip += bt->next;
903 	} while (bt->next != 0 &&
904 	    bt->next < BOOTINFO_SIZE /* sanity */ &&
905 	    (size_t)bip < (size_t)bootinfo + BOOTINFO_SIZE);
906 
907 	return NULL;
908 }
909 
910 #if defined(DDB) || defined(KGDB)
911 
ddb_trap_hook(int where)912 void ddb_trap_hook(int where)
913 {
914 	switch (where) {
915 	case 1:		/* Entry to DDB, turn watchdog off */
916 		(void)(*platform.watchdog_disable)();
917 		break;
918 
919 	case 0:		/* Exit from DDB, turn watchdog back on */
920 		(void)(*platform.watchdog_enable)();
921 		break;
922 	}
923 }
924 
925 #endif
926 
mips_machdep_cache_config(void)927 void mips_machdep_cache_config(void)
928 {
929 
930 	arcbios_tree_walk(mips_machdep_find_l2cache, NULL);
931 
932 	switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
933 #if defined(INDY_R4600_CACHE)
934 	case MIPS_R4600:
935 		/*
936 		 * R4600 is on Indy-class machines only.  Disable and
937 		 * flush pcache.
938 		 */
939 		mips_cache_info.mci_sdcache_size = 0;
940 		mips_cache_info.mci_sdcache_line_size = 0;
941 		ip22_sdcache_disable();
942 		break;
943 #endif
944 #if defined(MIPS3)
945 	case MIPS_R5000:
946 	case MIPS_RM5200:
947 		r5k_enable_sdcache();
948 		break;
949 #endif
950 	}
951 }
952 
953 void
mips_machdep_find_l2cache(struct arcbios_component * comp,struct arcbios_treewalk_context * atc)954 mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc)
955 {
956 	struct mips_cache_info * const mci = &mips_cache_info;
957 	device_t self = atc->atc_cookie;
958 
959 	if (comp->Class != COMPONENT_CLASS_CacheClass)
960 		return;
961 
962 	switch (comp->Type) {
963 	case COMPONENT_TYPE_SecondaryICache:
964 		panic("%s: split L2 cache", device_xname(self));
965 	case COMPONENT_TYPE_SecondaryDCache:
966 	case COMPONENT_TYPE_SecondaryCache:
967 		mci->mci_sdcache_size = COMPONENT_KEY_Cache_CacheSize(comp->Key);
968 		mci->mci_sdcache_line_size =
969 		    COMPONENT_KEY_Cache_LineSize(comp->Key);
970 		/* XXX */
971 		mci->mci_sdcache_ways = 1;
972 		break;
973 	}
974 }
975