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