xref: /netbsd/sys/arch/hpcmips/hpcmips/machdep.c (revision 6550d01e)
1 /*	$NetBSD: machdep.c,v 1.112 2010/11/15 06:25:42 uebayasi Exp $	*/
2 
3 /*-
4  * Copyright (c) 1999 Shin Takemura, All rights reserved.
5  * Copyright (c) 1999-2001 SATO Kazumi, All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  */
31 
32 /*
33  * Copyright (c) 1992, 1993
34  *	The Regents of the University of California.  All rights reserved.
35  *
36  * This code is derived from software contributed to Berkeley by
37  * the Systems Programming Group of the University of Utah Computer
38  * Science Department, The Mach Operating System project at
39  * Carnegie-Mellon University and Ralph Campbell.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  *
65  * from: Utah Hdr: machdep.c 1.63 91/04/24
66  *
67  *	@(#)machdep.c	8.3 (Berkeley) 1/12/94
68  */
69 /*
70  * Copyright (c) 1988 University of Utah.
71  *
72  * This code is derived from software contributed to Berkeley by
73  * the Systems Programming Group of the University of Utah Computer
74  * Science Department, The Mach Operating System project at
75  * Carnegie-Mellon University and Ralph Campbell.
76  *
77  * Redistribution and use in source and binary forms, with or without
78  * modification, are permitted provided that the following conditions
79  * are met:
80  * 1. Redistributions of source code must retain the above copyright
81  *    notice, this list of conditions and the following disclaimer.
82  * 2. Redistributions in binary form must reproduce the above copyright
83  *    notice, this list of conditions and the following disclaimer in the
84  *    documentation and/or other materials provided with the distribution.
85  * 3. All advertising materials mentioning features or use of this software
86  *    must display the following acknowledgement:
87  *	This product includes software developed by the University of
88  *	California, Berkeley and its contributors.
89  * 4. Neither the name of the University nor the names of its contributors
90  *    may be used to endorse or promote products derived from this software
91  *    without specific prior written permission.
92  *
93  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
94  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
95  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
96  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
97  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
98  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
99  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
101  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
102  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
103  * SUCH DAMAGE.
104  *
105  * from: Utah Hdr: machdep.c 1.63 91/04/24
106  *
107  *	@(#)machdep.c	8.3 (Berkeley) 1/12/94
108  */
109 
110 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
111 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.112 2010/11/15 06:25:42 uebayasi Exp $");
112 
113 #include "opt_vr41xx.h"
114 #include "opt_tx39xx.h"
115 #include "opt_boot_standalone.h"
116 #include "opt_modular.h"
117 #include "opt_spec_platform.h"
118 #include "biconsdev.h"
119 #include "opt_ddb.h"
120 #include "opt_kgdb.h"
121 #include "opt_rtc_offset.h"
122 #include "opt_kloader.h"
123 #include "opt_kloader_kernel_path.h"
124 #include "debug_hpc.h"
125 #include "opt_md.h"
126 #include "opt_memsize.h"
127 #include "opt_no_symbolsz_entry.h"
128 
129 #include <sys/param.h>
130 #include <sys/systm.h>
131 #include <sys/kernel.h>
132 #include <sys/buf.h>
133 #include <sys/reboot.h>
134 #include <sys/mount.h>
135 #include <sys/boot_flag.h>
136 #include <sys/ksyms.h>
137 #include <sys/device.h>
138 #include <sys/lwp.h>
139 
140 #include <uvm/uvm_extern.h>
141 
142 #include <ufs/mfs/mfs_extern.h>	/* mfs_initminiroot() */
143 #include <dev/cons.h>		/* cntab access (cpu_reboot) */
144 
145 #include <machine/psl.h>
146 #include <machine/sysconf.h>
147 #include <machine/platid.h>
148 #include <machine/platid_mask.h>
149 #include <machine/kloader.h>
150 #include <machine/debug.h>
151 
152 #ifdef KGDB
153 #include <sys/kgdb.h>
154 #endif
155 
156 #include "ksyms.h"
157 
158 #if NKSYMS || defined(DDB) || defined(MODULAR)
159 #include <machine/db_machdep.h>
160 #include <ddb/db_sym.h>
161 #include <ddb/db_extern.h>
162 #ifndef DB_ELFSIZE
163 #error Must define DB_ELFSIZE!
164 #endif
165 #define ELFSIZE         DB_ELFSIZE
166 #include <sys/exec_elf.h>
167 #endif
168 
169 #if NBICONSDEV > 0
170 #include <sys/conf.h>
171 #include <dev/hpc/biconsvar.h>
172 #include <dev/hpc/bicons.h>
173 #define biconscnpollc	nullcnpollc
174 cons_decl(bicons);
175 static struct consdev bicons __attribute((__unused__)) = cons_init(bicons);
176 static int __bicons_enable;
177 #define DPRINTF(arg)	{ if (__bicons_enable) printf arg; }
178 #else /* NBICONSDEV > 0 */
179 #define DPRINTF(arg)
180 #endif /* NBICONSDEV > 0 */
181 
182 #include <nfs/rpcv2.h>
183 #include <nfs/nfsproto.h>
184 #include <nfs/nfs.h>
185 #include <nfs/nfsmount.h>
186 
187 #ifdef MEMORY_DISK_DYNAMIC
188 #include <dev/md.h>
189 #endif
190 
191 /* the following is used externally (sysctl_hw) */
192 char	hpcmips_cpuname[40];		/* set CPU depend xx_init() */
193 
194 struct cpu_info cpu_info_store;		/* only one CPU */
195 int	cpuspeed = 1;			/* approx # instr per usec. */
196 
197 /* CPU core switch table */
198 struct platform platform;
199 #ifdef VR41XX
200 extern void	vr_init(void);
201 #endif
202 #ifdef TX39XX
203 extern void	tx_init(void);
204 #endif
205 
206 /* boot environment */
207 static struct bootinfo bi_copy;
208 struct bootinfo *bootinfo;
209 char booted_kernel[128];
210 extern void makebootdev(const char *);
211 #ifdef KLOADER
212 #if !defined(KLOADER_KERNEL_PATH)
213 #define KLOADER_KERNEL_PATH	"/netbsd"
214 #endif /* !KLOADER_KERNEL_PATH */
215 static char kernel_path[] = KLOADER_KERNEL_PATH;
216 #endif /* KLOADER */
217 
218 /* maps for VM objects */
219 struct vm_map *phys_map;
220 
221 /* physical memory */
222 int	physmem;		/* max supported memory, changes to actual */
223 int	mem_cluster_cnt;
224 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
225 
226 /*
227  * safepri is a safe priority for sleep to set for a spin-wait
228  * during autoconfiguration or after a panic.
229  * Used as an argument to splx().
230  * XXX disables interrupt 5 to disable mips3 on-chip clock, which also
231  * disables mips1 FPU interrupts.
232  */
233 int	safepri = MIPS3_PSL_LOWIPL;	/* XXX */
234 
235 void mach_init(int, char *[], struct bootinfo *);
236 
237 #ifdef DEBUG
238 /* stacktrace code violates prototypes to get callee's registers */
239 extern void stacktrace(void); /*XXX*/
240 #endif
241 
242 /*
243  * Do all the stuff that locore normally does before calling main().
244  * Process arguments passed to us by the boot loader.
245  * Return the first page address following the system.
246  */
247 void
248 mach_init(int argc, char *argv[], struct bootinfo *bi)
249 {
250 	/*
251 	 * this routines stack is never polluted since stack pointer
252 	 * is lower than kernel text segment, and at exiting, stack pointer
253 	 * is changed to proc0.
254 	 */
255 #ifdef KLOADER
256 	struct kloader_bootinfo kbi;
257 #endif
258 	extern char edata[], end[];
259 #if NKSYMS || defined(DDB) || defined(MODULAR)
260 	extern void *esym;
261 #endif
262 	void *kernend;
263 	char *cp;
264 	int i;
265 
266 	/* clear the BSS segment */
267 #if NKSYMS || defined(DDB) || defined(MODULAR)
268 	size_t symbolsz = 0;
269 	Elf_Ehdr *eh = (void *)end;
270 	if (memcmp(eh->e_ident, ELFMAG, SELFMAG) == 0 &&
271 	    eh->e_ident[EI_CLASS] == ELFCLASS) {
272 		esym = end;
273 #ifndef NO_SYMBOLSZ_ENTRY
274 		if (eh->e_entry != 0) {
275 			/* pbsdboot */
276 			symbolsz = eh->e_entry;
277 		} else
278 #endif
279 		{
280 			/* hpcboot */
281 			Elf_Shdr *sh = (void *)(end + eh->e_shoff);
282 			for(i = 0; i < eh->e_shnum; i++, sh++)
283 				if (sh->sh_offset > 0 &&
284 				    (sh->sh_offset + sh->sh_size) > symbolsz)
285 					symbolsz = sh->sh_offset + sh->sh_size;
286 		}
287 		esym = (char*)esym + symbolsz;
288 		kernend = (void *)mips_round_page(esym);
289 		memset(edata, 0, end - edata);
290 	} else
291 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */
292 	{
293 		kernend = (void *)mips_round_page(end);
294 		memset(edata, 0, (char *)kernend - edata);
295 	}
296 
297 #if defined(BOOT_STANDALONE)
298 #if !defined (SPEC_PLATFORM) || SPEC_PLATFORM == 1
299 #error specify SPEC_PLATFORM=platid_mask_MACH_xxx_yyy in BOOT_STANDALONE case.
300 #error see platid_mask.c for platid_mask_MACH_xxx_yyy.
301 #else
302 	memcpy(&platid, &SPEC_PLATFORM, sizeof(platid));
303 #endif
304 #endif /* defined(BOOT_STANDALONE) && defined(SPEC_PLATFORM) */
305 	/*
306 	 *  Arguments are set up by boot loader.
307 	 */
308 	if (bi && bi->magic == BOOTINFO_MAGIC) {
309 		memset(&bi_copy, 0, sizeof(struct bootinfo));
310 		memcpy(&bi_copy, bi, min(bi->length, sizeof(struct bootinfo)));
311 		bootinfo = &bi_copy;
312 		if (bootinfo->platid_cpu != 0) {
313 			platid.dw.dw0 = bootinfo->platid_cpu;
314 		}
315 		if (bootinfo->platid_machine != 0) {
316 			platid.dw.dw1 = bootinfo->platid_machine;
317 		}
318 	}
319 	/* copy boot parameter for kloader */
320 #ifdef KLOADER
321 	kloader_bootinfo_set(&kbi, argc, argv, bi, false);
322 #endif
323 
324 	/*
325 	 * CPU core Specific Function Hooks
326 	 */
327 #if defined(VR41XX) && defined(TX39XX)
328 	if (platid_match(&platid, &platid_mask_CPU_MIPS_VR_41XX))
329 		vr_init();
330 	else if (platid_match(&platid, &platid_mask_CPU_MIPS_TX_3900) ||
331 	    platid_match(&platid, &platid_mask_CPU_MIPS_TX_3920))
332 		tx_init();
333 #elif defined(VR41XX)
334 	vr_init();
335 #elif defined(TX39XX)
336 	tx_init();
337 #else
338 #error "define TX39XX and/or VR41XX"
339 #endif
340 
341 #if NBICONSDEV > 0
342 	/*
343 	 *  bicons don't need actual device initialize.  only bootinfo needed.
344 	 */
345 	__bicons_enable = (bicons_init(&bicons) == 0);
346 	if (__bicons_enable)
347 		cn_tab = &bicons;
348 #endif
349 
350 	/* Initialize frame buffer (to steal DMA buffer, stay here.) */
351 #ifdef HPC_DEBUG_LCD
352 	dbg_lcd_test();
353 #endif
354 	(*platform.fb_init)(&kernend);
355 	kernend = (void *)mips_round_page(kernend);
356 
357 	/*
358 	 * Set the VM page size.
359 	 */
360 	uvmexp.pagesize = NBPG; /* Notify the VM system of our page size. */
361 	uvm_setpagesize();
362 
363 	/*
364 	 * Copy exception-dispatch code down to exception vector.
365 	 * Initialize locore-function vector.
366 	 * Clear out the I and D caches.
367 	 */
368 	mips_vector_init();
369 	intr_init();
370 
371 #ifdef DEBUG
372 	/*
373 	 * Look at arguments passed to us and compute boothowto.
374 	 */
375 	if (bootinfo) {
376 		DPRINTF(("Bootinfo. available, "));
377 	}
378 	DPRINTF(("args: "));
379 	for (i = 0; i < argc; i++) {
380 		DPRINTF(("%s ", argv[i]));
381 	}
382 	DPRINTF(("\n"));
383 	DPRINTF(("platform ID: %08lx %08lx\n", platid.dw.dw0, platid.dw.dw1));
384 #endif /* DEBUG */
385 
386 #ifndef RTC_OFFSET
387 	/*
388 	 * rtc_offset from bootinfo.timezone set by pbsdboot.exe
389 	 */
390 	if (rtc_offset == 0 && bootinfo
391 	    && bootinfo->timezone > (-12*60)
392 	    && bootinfo->timezone <= (12*60))
393 		rtc_offset = bootinfo->timezone;
394 #endif /* RTC_OFFSET */
395 
396 	/* Compute bootdev */
397 	makebootdev("wd0"); /* default boot device */
398 
399 	boothowto = 0;
400 #ifdef KADB
401 	boothowto |= RB_KDB;
402 #endif
403 	strncpy(booted_kernel, argv[0], sizeof(booted_kernel));
404 	booted_kernel[sizeof(booted_kernel)-1] = 0;
405 	for (i = 1; i < argc; i++) {
406 		for (cp = argv[i]; *cp; cp++) {
407 			switch (*cp) {
408 			case 'h': /* XXX, serial console */
409 				bootinfo->bi_cnuse |= BI_CNUSE_SERIAL;
410 				break;
411 
412 			case 'b':
413 				/* boot device: -b=sd0 etc. */
414 				if (strcmp(cp+2, "nfs") == 0)
415 					rootfstype = MOUNT_NFS;
416 				else
417 					makebootdev(cp+2);
418 				cp += strlen(cp);
419 				break;
420 			default:
421 				BOOT_FLAG(*cp, boothowto);
422 				break;
423 			}
424 		}
425 	}
426 	/*
427 	 * Check to see if a mini-root was loaded into memory. It resides
428 	 * at the start of the next page just after the end of BSS.
429 	 */
430 	if (boothowto & RB_MINIROOT) {
431 		size_t fssz;
432 		fssz = round_page(mfs_initminiroot(kernend));
433 #ifdef MEMORY_DISK_DYNAMIC
434 		md_root_setconf(kernend, fssz);
435 #endif /* MEMORY_DISK_DYNAMIC */
436 		kernend = (char *)kernend + fssz;
437 	}
438 
439 #if NKSYMS || defined(DDB) || defined(MODULAR)
440 	/* init symbols if present */
441 	if (esym)
442 		ksyms_addsyms_elf(symbolsz, &end, esym);
443 #endif /* DDB */
444 
445 	/* Initialize console and KGDB serial port. */
446 	(*platform.cons_init)();
447 
448 #if defined(DDB) || defined(KGDB)
449 	if (boothowto & RB_KDB) {
450 #ifdef DDB
451 		Debugger();
452 #endif /* DDB */
453 #ifdef KGDB
454 		kgdb_debug_init = 1;
455 		kgdb_connect(1);
456 #endif /* KGDB */
457 	}
458 #endif /* DDB || KGDB */
459 
460 	/* Find physical memory regions. */
461 #ifdef MEMSIZE
462 	mem_clusters[0].start = 0;
463 	mem_clusters[0].size = (paddr_t) kernend - MIPS_KSEG0_START;
464 	mem_clusters[1].start = (paddr_t) kernend - MIPS_KSEG0_START;
465 	mem_clusters[1].size = MEMSIZE * 0x100000 - mem_clusters[1].start;
466 	mem_cluster_cnt = 2;
467 #else
468 	(*platform.mem_init)((paddr_t)kernend - MIPS_KSEG0_START);
469 #endif
470 	/*
471 	 *  Clear currently unused D-RAM area
472 	 *  (For reboot Windows CE clearly)
473 	 */
474 	{
475 		u_int32_t sp;
476 		__asm volatile("move %0, $29" : "=r"(sp));
477 		KDASSERT(sp > KERNBASE + 0x400);
478 		memset((void *)(KERNBASE + 0x400), 0, sp - (KERNBASE + 0x400));
479 	}
480 
481 	printf("mem_cluster_cnt = %d\n", mem_cluster_cnt);
482 	physmem = 0;
483 	for (i = 0; i < mem_cluster_cnt; i++) {
484 		printf("mem_clusters[%d] = {%#"PRIxPADDR",%#"PRIxPSIZE"}\n", i,
485 		    (paddr_t)mem_clusters[i].start,
486 		    (psize_t)mem_clusters[i].size);
487 		physmem += atop(mem_clusters[i].size);
488 	}
489 
490 	/* Cluster 0 is always the kernel, which doesn't get loaded. */
491 	for (i = 1; i < mem_cluster_cnt; i++) {
492 		paddr_t start;
493 		psize_t size;
494 
495 		start = (paddr_t)mem_clusters[i].start;
496 		size = (psize_t)mem_clusters[i].size;
497 
498 		printf("loading %#"PRIxPADDR",%#"PRIxPSIZE"\n", start, size);
499 
500 		memset((void *)MIPS_PHYS_TO_KSEG1(start), 0, size);
501 
502 		uvm_page_physload(atop(start), atop(start + size),
503 		    atop(start), atop(start + size),
504 		    VM_FREELIST_DEFAULT);
505 	}
506 
507 	/*
508 	 * Initialize error message buffer (at end of core).
509 	 */
510 	mips_init_msgbuf();
511 
512 	/*
513 	 * Initialize the virtual memory system.
514 	 */
515 	pmap_bootstrap();
516 
517 	/*
518 	 * Initialize lwp0's uarea.
519 	 */
520 	mips_init_lwp0_uarea();
521 }
522 
523 /*
524  * Machine-dependent startup code.
525  * allocate memory for variable-sized tables, initialize CPU.
526  */
527 void
528 cpu_startup(void)
529 {
530 	vaddr_t minaddr, maxaddr;
531 	char pbuf[9];
532 	size_t i;
533 #ifdef DEBUG
534 	extern int pmapdebug;
535 	int opmapdebug = pmapdebug;
536 
537 	pmapdebug = 0;
538 #endif
539 
540 	/*
541 	 * Good {morning,afternoon,evening,night}.
542 	 */
543 	printf("%s%s", copyright, version);
544 	sprintf(cpu_model, "%s (%s)", platid_name(&platid), hpcmips_cpuname);
545 	printf("%s\n", cpu_model);
546 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
547 	printf("total memory = %s\n", pbuf);
548 	if (bootverbose) {
549 		/* show again when verbose mode */
550 		printf("total memory banks = %d\n", mem_cluster_cnt);
551 		for (i = 0; i < mem_cluster_cnt; i++) {
552 			printf("memory bank %zu = "
553 			    "0x%08"PRIxPADDR" %"PRIdPSIZE"KB(0x%08"PRIxPSIZE")\n", i,
554 			    (paddr_t)mem_clusters[i].start,
555 			    (psize_t)mem_clusters[i].size/1024,
556 			    (psize_t)mem_clusters[i].size);
557 		}
558 	}
559 
560 	minaddr = 0;
561 
562 	/*
563 	 * Allocate a submap for physio
564 	 */
565 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
566 	    VM_PHYS_SIZE, 0, false, NULL);
567 
568 	/*
569 	 * No need to allocate an mbuf cluster submap.  Mbuf clusters
570 	 * are allocated via the pool allocator, and we use KSEG to
571 	 * map those pages.
572 	 */
573 
574 #ifdef DEBUG
575 	pmapdebug = opmapdebug;
576 #endif
577 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
578 	printf("avail memory = %s\n", pbuf);
579 }
580 
581 void
582 cpu_reboot(int howto, char *bootstr)
583 {
584 
585 	/* take a snap shot before clobbering any registers */
586 	if (curlwp)
587 		savectx(curpcb);
588 
589 #ifdef DEBUG
590 	if (panicstr)
591 		stacktrace();
592 #endif
593 
594 	/* If system is cold, just halt. */
595 	if (cold) {
596 		howto |= RB_HALT;
597 		goto haltsys;
598 	}
599 
600 	/* If "always halt" was specified as a boot flag, obey. */
601 	if ((boothowto & RB_HALT) != 0) {
602 		howto |= RB_HALT;
603 	}
604 
605 #ifdef KLOADER
606 	if ((howto & RB_HALT) == 0) {
607 		if (howto & RB_STRING)
608 			kloader_reboot_setup(bootstr);
609 		else
610 			kloader_reboot_setup(kernel_path);
611 	}
612 #endif
613 
614 	boothowto = howto;
615 	if ((howto & RB_NOSYNC) == 0) {
616 		/*
617 		 * Synchronize the disks....
618 		 */
619 		vfs_shutdown();
620 
621 		/*
622 		 * If we've been adjusting the clock, the todr
623 		 * will be out of synch; adjust it now.
624 		 */
625 		resettodr();
626 	}
627 
628 	/* Disable interrupts. */
629 	splhigh();
630 
631 	/* If rebooting and a dump is requested do it. */
632 	if (howto & RB_DUMP)
633 		dumpsys();
634 
635  haltsys:
636 
637 	/* run any shutdown hooks */
638 	doshutdownhooks();
639 
640 	pmf_system_shutdown(boothowto);
641 
642 	/* Finally, halt/reboot the system. */
643 	if (howto & RB_HALT) {
644 		printf("halted.\n");
645 	} else {
646 #ifdef KLOADER
647 		kloader_reboot();
648 		/* NOTREACHED */
649 #endif
650 	}
651 
652 	(*platform.reboot)(howto, bootstr);
653 	while(1)
654 		;
655 	/*NOTREACHED*/
656 }
657 
658 void
659 consinit(void)
660 {
661 	/* platform.cons_init() do it */
662 }
663