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