1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1992 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department, The Mach Operating System project at
9  * Carnegie-Mellon University, Ralph Campbell, Sony Corp. and Kazumasa
10  * Utashiro of Software Research Associates, Inc.
11  *
12  * %sccs.include.redist.c%
13  *
14  *	@(#)machdep.c	7.10 (Berkeley) 04/08/93
15  */
16 
17 /* from: Utah $Hdr: machdep.c 1.63 91/04/24$ */
18 
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/signalvar.h>
22 #include <sys/kernel.h>
23 #include <sys/map.h>
24 #include <sys/proc.h>
25 #include <sys/buf.h>
26 #include <sys/reboot.h>
27 #include <sys/conf.h>
28 #include <sys/file.h>
29 #include <sys/clist.h>
30 #include <sys/callout.h>
31 #include <sys/malloc.h>
32 #include <sys/mbuf.h>
33 #include <sys/msgbuf.h>
34 #include <sys/user.h>
35 #include <sys/exec.h>
36 #ifdef SYSVSHM
37 #include <sys/shm.h>
38 #endif
39 
40 #include <vm/vm.h>
41 #include <vm/vm_kern.h>
42 #include <vm/vm_page.h>
43 
44 #include <machine/cpu.h>
45 #include <machine/reg.h>
46 #include <machine/psl.h>
47 #include <machine/pte.h>
48 
49 #include <machine/adrsmap.h>
50 
51 vm_map_t buffer_map;
52 
53 /* the following is used externally (sysctl_hw) */
54 char	machine[] = "SONY";	/* cpu "architecture" */
55 char	cpu_model[30];
56 
57 /*
58  * Declare these as initialized data so we can patch them.
59  */
60 int	nswbuf = 0;
61 #ifdef	NBUF
62 int	nbuf = NBUF;
63 #else
64 int	nbuf = 0;
65 #endif
66 #ifdef	BUFPAGES
67 int	bufpages = BUFPAGES;
68 #else
69 int	bufpages = 0;
70 #endif
71 int	msgbufmapped = 0;	/* set when safe to use msgbuf */
72 int	maxmem;			/* max memory per process */
73 int	physmem;		/* max supported memory, changes to actual */
74 /*
75  * safepri is a safe priority for sleep to set for a spin-wait
76  * during autoconfiguration or after a panic.
77  */
78 int	safepri = PSL_LOWIPL;
79 
80 struct	user *proc0paddr;
81 struct	proc nullproc;		/* for use by swtch_exit() */
82 
83 /*
84  * Do all the stuff that locore normally does before calling main().
85  * Process arguments passed to us by the prom monitor.
86  * Return the first page address following the system.
87  */
88 mach_init(x_boothowto, x_unkown, x_bootdev, x_maxmem)
89 	int x_boothowto;
90 	int x_unkown;
91 	int x_bootdev;
92 	int x_maxmem;
93 {
94 	register char *cp;
95 	register int i;
96 	register unsigned firstaddr;
97 	register caddr_t v;
98 	caddr_t start;
99 	extern u_long bootdev;
100 	extern char edata[], end[];
101 	extern char MachUTLBMiss[], MachUTLBMissEnd[];
102 	extern char MachException[], MachExceptionEnd[];
103 #ifdef ATTR
104 	extern char *pmap_attributes;
105 #endif
106 
107 	/*
108 	 * Save parameters into kernel work area.
109 	 */
110 	*(int *)(MACH_CACHED_TO_UNCACHED(MACH_MAXMEMSIZE_ADDR)) = x_maxmem;
111 	*(int *)(MACH_CACHED_TO_UNCACHED(MACH_BOOTDEV_ADDR)) = x_bootdev;
112 	*(int *)(MACH_CACHED_TO_UNCACHED(MACH_BOOTSW_ADDR)) = x_boothowto;
113 
114 	/* clear the BSS segment */
115 	v = (caddr_t)pmax_round_page(end);
116 	bzero(edata, v - edata);
117 
118 	boothowto = x_boothowto;
119 	bootdev = x_bootdev;
120 	maxmem = physmem = pmax_btop(x_maxmem);
121 
122 	/*
123 	 * Look at arguments passed to us and compute boothowto.
124 	 */
125 #ifdef GENERIC
126 	boothowto |= RB_SINGLE | RB_ASKNAME;
127 #endif
128 #ifdef KADB
129 	boothowto |= RB_KDB;
130 #endif
131 
132 #ifdef MFS
133 	/*
134 	 * Check to see if a mini-root was loaded into memory. It resides
135 	 * at the start of the next page just after the end of BSS.
136 	 */
137 	if (boothowto & RB_MINIROOT) {
138 		boothowto |= RB_DFLTROOT;
139 		v += mfs_initminiroot(v);
140 	}
141 #endif
142 
143 	/*
144 	 * Init mapping for u page(s) for proc[0], pm_tlbpid 1.
145 	 */
146 	start = v;
147 	curproc->p_addr = proc0paddr = (struct user *)v;
148 	curproc->p_md.md_regs = proc0paddr->u_pcb.pcb_regs;
149 	firstaddr = MACH_CACHED_TO_PHYS(v);
150 	for (i = 0; i < UPAGES; i++) {
151 		MachTLBWriteIndexed(i,
152 			(UADDR + (i << PGSHIFT)) | (1 << VMMACH_TLB_PID_SHIFT),
153 			curproc->p_md.md_upte[i] = firstaddr | PG_V | PG_M);
154 		firstaddr += NBPG;
155 	}
156 	v += UPAGES * NBPG;
157 	MachSetPID(1);
158 
159 	/*
160 	 * init nullproc for swtch_exit().
161 	 * init mapping for u page(s), pm_tlbpid 0
162 	 * This could be used for an idle process.
163 	 */
164 	nullproc.p_addr = (struct user *)v;
165 	nullproc.p_md.md_regs = ((struct user *)v)->u_pcb.pcb_regs;
166 	for (i = 0; i < UPAGES; i++) {
167 		nullproc.p_md.md_upte[i] = firstaddr | PG_V | PG_M;
168 		firstaddr += NBPG;
169 	}
170 	v += UPAGES * NBPG;
171 
172 	/* clear pages for u areas */
173 	bzero(start, v - start);
174 
175 	/*
176 	 * Copy down exception vector code.
177 	 */
178 	if (MachUTLBMissEnd - MachUTLBMiss > 0x80)
179 		panic("startup: UTLB code too large");
180 	bcopy(MachUTLBMiss, (char *)MACH_UTLB_MISS_EXC_VEC,
181 		MachUTLBMissEnd - MachUTLBMiss);
182 	bcopy(MachException, (char *)MACH_GEN_EXC_VEC,
183 		MachExceptionEnd - MachException);
184 
185 	/*
186 	 * Clear out the I and D caches.
187 	 */
188 	MachConfigCache();
189 	MachFlushCache();
190 
191 	/*
192 	 * Initialize error message buffer (at end of core).
193 	 */
194 	maxmem -= btoc(sizeof (struct msgbuf));
195 	msgbufp = (struct msgbuf *)(MACH_PHYS_TO_CACHED(maxmem << PGSHIFT));
196 	msgbufmapped = 1;
197 
198 	/*
199 	 * Allocate space for system data structures.
200 	 * The first available kernel virtual address is in "v".
201 	 * As pages of kernel virtual memory are allocated, "v" is incremented.
202 	 *
203 	 * These data structures are allocated here instead of cpu_startup()
204 	 * because physical memory is directly addressable. We don't have
205 	 * to map these into virtual address space.
206 	 */
207 	start = v;
208 
209 #define	valloc(name, type, num) \
210 	    (name) = (type *)v; v = (caddr_t)((name)+(num))
211 #define	valloclim(name, type, num, lim) \
212 	    (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
213 	valloc(cfree, struct cblock, nclist);
214 	valloc(callout, struct callout, ncallout);
215 	valloc(swapmap, struct map, nswapmap = maxproc * 2);
216 #ifdef SYSVSHM
217 	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
218 #endif
219 #ifdef ATTR
220 	/* this is allocated here just to save a few bytes */
221 	valloc(pmap_attributes, char, physmem);
222 #endif
223 
224 	/*
225 	 * Determine how many buffers to allocate.
226 	 * We allocate more buffer space than the BSD standard of
227 	 * using 10% of memory for the first 2 Meg, 5% of remaining.
228 	 * We just allocate a flat 10%.  Insure a minimum of 16 buffers.
229 	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
230 	 */
231 	if (bufpages == 0)
232 		bufpages = physmem / 10 / CLSIZE;
233 	if (nbuf == 0) {
234 		nbuf = bufpages;
235 		if (nbuf < 16)
236 			nbuf = 16;
237 	}
238 	if (nswbuf == 0) {
239 		nswbuf = (nbuf / 2) &~ 1;	/* force even */
240 		if (nswbuf > 256)
241 			nswbuf = 256;		/* sanity */
242 	}
243 	valloc(swbuf, struct buf, nswbuf);
244 	valloc(buf, struct buf, nbuf);
245 
246 	/*
247 	 * Clear allocated memory.
248 	 */
249 	v = (caddr_t)pmax_round_page(v);
250 	bzero(start, v - start);
251 
252 	/*
253 	 * Initialize the virtual memory system.
254 	 */
255 	pmap_bootstrap((vm_offset_t)MACH_CACHED_TO_PHYS(v));
256 }
257 
258 /*
259  * Console initialization: called early on from main,
260  * before vm init or startup.  Do enough configuration
261  * to choose and initialize a console.
262  * XXX need something better here.
263  */
264 #define	SCC_CONSOLE	0
265 #define	SW_CONSOLE	0x07
266 #define	SW_NWB512	0x04
267 #define	SW_NWB225	0x01
268 #define	SW_FBPOP	0x02
269 #define	SW_FBPOP1	0x06
270 #define	SW_FBPOP2	0x03
271 #define	SW_AUTOSEL	0x07
272 consinit()
273 {
274 	extern dev_t consdev;
275 	extern struct tty *constty, *cn_tty, *rs_tty;
276 	int dipsw = (int)*(volatile u_char *)DIP_SWITCH;
277 
278 #include "bm.h"
279 #if NBM > 0
280 #if defined(news3200) || defined(news3400)	/* KU:XXX */
281 	fbbm_probe(dipsw|2);
282 #else
283 	fbbm_probe(dipsw);
284 #endif
285 	vt100_open();
286 	setup_fnt();
287 	setup_fnt24();
288 #else
289 	dipsw &= SW_CONSOLE;
290 #endif
291 
292 	switch (dipsw & SW_CONSOLE) {
293 	    case 0:
294 		scc_open(SCC_CONSOLE);
295 		consdev = makedev(1, 0);
296 		constty = rs_tty;
297 		break;
298 
299 	    default:
300 #if NBM > 0
301 		consdev = makedev(22, 0);
302 		constty = cn_tty;
303 #endif
304 		break;
305 	}
306 	return(0);
307 }
308 
309 /*
310  * cpu_startup: allocate memory for variable-sized tables,
311  * initialize cpu, and do autoconfiguration.
312  */
313 cpu_startup()
314 {
315 	register unsigned i;
316 	register caddr_t v;
317 	int base, residual;
318 	extern long Usrptsize;
319 	extern struct map *useriomap;
320 #ifdef DEBUG
321 	extern int pmapdebug;
322 	int opmapdebug = pmapdebug;
323 #endif
324 	vm_offset_t minaddr, maxaddr;
325 	vm_size_t size;
326 
327 #ifdef DEBUG
328 	pmapdebug = 0;
329 #endif
330 
331 	/*
332 	 * Good {morning,afternoon,evening,night}.
333 	 */
334 	printf(version);
335 	printf("real mem = %d\n", ctob(physmem));
336 
337 	/*
338 	 * Allocate virtual address space for file I/O buffers.
339 	 * Note they are different than the array of headers, 'buf',
340 	 * and usually occupy more virtual memory than physical.
341 	 */
342 	size = MAXBSIZE * nbuf;
343 	buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
344 				   &maxaddr, size, FALSE);
345 	minaddr = (vm_offset_t)buffers;
346 	if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
347 			&minaddr, size, FALSE) != KERN_SUCCESS)
348 		panic("startup: cannot allocate buffers");
349 	base = bufpages / nbuf;
350 	residual = bufpages % nbuf;
351 	for (i = 0; i < nbuf; i++) {
352 		vm_size_t curbufsize;
353 		vm_offset_t curbuf;
354 
355 		/*
356 		 * First <residual> buffers get (base+1) physical pages
357 		 * allocated for them.  The rest get (base) physical pages.
358 		 *
359 		 * The rest of each buffer occupies virtual space,
360 		 * but has no physical memory allocated for it.
361 		 */
362 		curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
363 		curbufsize = CLBYTES * (i < residual ? base+1 : base);
364 		vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
365 		vm_map_simplify(buffer_map, curbuf);
366 	}
367 	/*
368 	 * Allocate a submap for exec arguments.  This map effectively
369 	 * limits the number of processes exec'ing at any time.
370 	 */
371 	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
372 				 16*NCARGS, TRUE);
373 	/*
374 	 * Allocate a submap for physio
375 	 */
376 	phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
377 				 VM_PHYS_SIZE, TRUE);
378 
379 	/*
380 	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
381 	 * we use the more space efficient malloc in place of kmem_alloc.
382 	 */
383 	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
384 				   M_MBUF, M_NOWAIT);
385 	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
386 	mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
387 			       VM_MBUF_SIZE, FALSE);
388 	/*
389 	 * Initialize callouts
390 	 */
391 	callfree = callout;
392 	for (i = 1; i < ncallout; i++)
393 		callout[i-1].c_next = &callout[i];
394 	callout[i-1].c_next = NULL;
395 
396 #ifdef DEBUG
397 	pmapdebug = opmapdebug;
398 #endif
399 	printf("avail mem = %d\n", ptoa(cnt.v_free_count));
400 	printf("using %d buffers containing %d bytes of memory\n",
401 		nbuf, bufpages * CLBYTES);
402 	/*
403 	 * Set up CPU-specific registers, cache, etc.
404 	 */
405 	initcpu();
406 
407 	/*
408 	 * Set up buffers, so they can be used to read disk labels.
409 	 */
410 	bufinit();
411 
412 	/*
413 	 * Configure the system.
414 	 */
415 	configure();
416 }
417 
418 /*
419  * Set registers on exec.
420  * Clear all registers except sp, pc.
421  */
422 setregs(p, entry, retval)
423 	register struct proc *p;
424 	u_long entry;
425 	int retval[2];
426 {
427 	int sp = p->p_md.md_regs[SP];
428 	extern struct proc *machFPCurProcPtr;
429 
430 	bzero((caddr_t)p->p_md.md_regs, (FSR + 1) * sizeof(int));
431 	p->p_md.md_regs[SP] = sp;
432 	p->p_md.md_regs[PC] = entry & ~3;
433 	p->p_md.md_regs[PS] = PSL_USERSET;
434 	p->p_md.md_flags & ~MDP_FPUSED;
435 	if (machFPCurProcPtr == p)
436 		machFPCurProcPtr = (struct proc *)0;
437 }
438 
439 /*
440  * WARNING: code in locore.s assumes the layout shown for sf_signum
441  * thru sf_handler so... don't screw with them!
442  */
443 struct sigframe {
444 	int	sf_signum;		/* signo for handler */
445 	int	sf_code;		/* additional info for handler */
446 	struct	sigcontext *sf_scp;	/* context ptr for handler */
447 	sig_t	sf_handler;		/* handler addr for u_sigc */
448 	struct	sigcontext sf_sc;	/* actual context */
449 };
450 
451 #ifdef DEBUG
452 int sigdebug = 0;
453 int sigpid = 0;
454 #define SDB_FOLLOW	0x01
455 #define SDB_KSTACK	0x02
456 #define SDB_FPSTATE	0x04
457 #endif
458 
459 /*
460  * Send an interrupt to process.
461  */
462 void
463 sendsig(catcher, sig, mask, code)
464 	sig_t catcher;
465 	int sig, mask;
466 	unsigned code;
467 {
468 	register struct proc *p = curproc;
469 	register struct sigframe *fp;
470 	register int *regs;
471 	register struct sigacts *psp = p->p_sigacts;
472 	int oonstack, fsize;
473 	struct sigcontext ksc;
474 	extern char sigcode[], esigcode[];
475 
476 	regs = p->p_md.md_regs;
477 	oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
478 	/*
479 	 * Allocate and validate space for the signal handler
480 	 * context. Note that if the stack is in data space, the
481 	 * call to grow() is a nop, and the copyout()
482 	 * will fail if the process has not already allocated
483 	 * the space with a `brk'.
484 	 */
485 	fsize = sizeof(struct sigframe);
486 	if ((psp->ps_flags & SAS_ALTSTACK) &&
487 	    (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
488 	    (psp->ps_sigonstack & sigmask(sig))) {
489 		fp = (struct sigframe *)(psp->ps_sigstk.ss_base +
490 					 psp->ps_sigstk.ss_size - fsize);
491 		psp->ps_sigstk.ss_flags |= SA_ONSTACK;
492 	} else
493 		fp = (struct sigframe *)(regs[SP] - fsize);
494 	if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
495 		(void)grow(p, (unsigned)fp);
496 #ifdef DEBUG
497 	if ((sigdebug & SDB_FOLLOW) ||
498 	    (sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
499 		printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n",
500 		       p->p_pid, sig, &oonstack, fp, &fp->sf_sc);
501 #endif
502 	/*
503 	 * Build the signal context to be used by sigreturn.
504 	 */
505 	ksc.sc_onstack = oonstack;
506 	ksc.sc_mask = mask;
507 	ksc.sc_pc = regs[PC];
508 	ksc.sc_regs[ZERO] = 0xACEDBADE;		/* magic number */
509 	bcopy((caddr_t)&regs[1], (caddr_t)&ksc.sc_regs[1],
510 		sizeof(ksc.sc_regs) - sizeof(int));
511 	ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED;
512 	if (ksc.sc_fpused) {
513 		extern struct proc *machFPCurProcPtr;
514 
515 		/* if FPU has current state, save it first */
516 		if (p == machFPCurProcPtr)
517 			MachSaveCurFPState(p);
518 		bcopy((caddr_t)&p->p_md.md_regs[F0], (caddr_t)ksc.sc_fpregs,
519 			sizeof(ksc.sc_fpregs));
520 	}
521 	if (copyout((caddr_t)&ksc, (caddr_t)&fp->sf_sc, sizeof(ksc))) {
522 		/*
523 		 * Process has trashed its stack; give it an illegal
524 		 * instruction to halt it in its tracks.
525 		 */
526 		SIGACTION(p, SIGILL) = SIG_DFL;
527 		sig = sigmask(SIGILL);
528 		p->p_sigignore &= ~sig;
529 		p->p_sigcatch &= ~sig;
530 		p->p_sigmask &= ~sig;
531 		psignal(p, SIGILL);
532 		return;
533 	}
534 	/*
535 	 * Build the argument list for the signal handler.
536 	 */
537 	regs[A0] = sig;
538 	regs[A1] = code;
539 	regs[A2] = (int)&fp->sf_sc;
540 	regs[A3] = (int)catcher;
541 
542 	regs[PC] = (int)catcher;
543 	regs[SP] = (int)fp;
544 	/*
545 	 * Signal trampoline code is at base of user stack.
546 	 */
547 	regs[RA] = (int)PS_STRINGS - (esigcode - sigcode);
548 #ifdef DEBUG
549 	if ((sigdebug & SDB_FOLLOW) ||
550 	    (sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
551 		printf("sendsig(%d): sig %d returns\n",
552 		       p->p_pid, sig);
553 #endif
554 }
555 
556 /*
557  * System call to cleanup state after a signal
558  * has been taken.  Reset signal mask and
559  * stack state from context left by sendsig (above).
560  * Return to previous pc and psl as specified by
561  * context left by sendsig. Check carefully to
562  * make sure that the user has not modified the
563  * psl to gain improper priviledges or to cause
564  * a machine fault.
565  */
566 struct sigreturn_args {
567 	struct sigcontext *sigcntxp;
568 };
569 /* ARGSUSED */
570 sigreturn(p, uap, retval)
571 	struct proc *p;
572 	struct sigreturn_args *uap;
573 	int *retval;
574 {
575 	register struct sigcontext *scp;
576 	register int *regs;
577 	struct sigcontext ksc;
578 	int error;
579 
580 	scp = uap->sigcntxp;
581 #ifdef DEBUG
582 	if (sigdebug & SDB_FOLLOW)
583 		printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
584 #endif
585 	regs = p->p_md.md_regs;
586 	/*
587 	 * Test and fetch the context structure.
588 	 * We grab it all at once for speed.
589 	 */
590 	error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof(ksc));
591 	if (error || ksc.sc_regs[ZERO] != 0xACEDBADE) {
592 #ifdef DEBUG
593 		if (!(sigdebug & SDB_FOLLOW))
594 			printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
595 		printf("  old sp %x ra %x pc %x\n",
596 			regs[SP], regs[RA], regs[PC]);
597 		printf("  new sp %x ra %x pc %x err %d z %x\n",
598 			ksc.sc_regs[SP], ksc.sc_regs[RA], ksc.sc_regs[PC],
599 			error, ksc.sc_regs[ZERO]);
600 #endif
601 		return (EINVAL);
602 	}
603 	scp = &ksc;
604 	/*
605 	 * Restore the user supplied information
606 	 */
607 	if (scp->sc_onstack & 01)
608 		p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
609 	else
610 		p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
611 	p->p_sigmask = scp->sc_mask &~ sigcantmask;
612 	regs[PC] = scp->sc_pc;
613 	bcopy((caddr_t)&scp->sc_regs[1], (caddr_t)&regs[1],
614 		sizeof(scp->sc_regs) - sizeof(int));
615 	if (scp->sc_fpused)
616 		bcopy((caddr_t)scp->sc_fpregs, (caddr_t)&p->p_md.md_regs[F0],
617 			sizeof(scp->sc_fpregs));
618 	return (EJUSTRETURN);
619 }
620 
621 int	waittime = -1;
622 
623 boot(howto)
624 	register int howto;
625 {
626 
627 	/* take a snap shot before clobbering any registers */
628 	if (curproc)
629 		savectx(curproc->p_addr, 0);
630 
631 #ifdef DEBUG
632 	if (panicstr)
633 		traceback();
634 #endif
635 
636 	boothowto = howto;
637 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
638 		register struct buf *bp;
639 		int iter, nbusy;
640 
641 		waittime = 0;
642 		(void) spl0();
643 		printf("syncing disks... ");
644 		/*
645 		 * Release vnodes held by texts before sync.
646 		 */
647 		if (panicstr == 0)
648 			vnode_pager_umount(NULL);
649 #ifdef notyet
650 #include "fd.h"
651 #if NFD > 0
652 		fdshutdown();
653 #endif
654 #endif
655 		sync(&proc0, (void *)NULL, (int *)NULL);
656 
657 		for (iter = 0; iter < 20; iter++) {
658 			nbusy = 0;
659 			for (bp = &buf[nbuf]; --bp >= buf; )
660 				if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
661 					nbusy++;
662 			if (nbusy == 0)
663 				break;
664 			printf("%d ", nbusy);
665 			DELAY(40000 * iter);
666 		}
667 		if (nbusy)
668 			printf("giving up\n");
669 		else
670 			printf("done\n");
671 		/*
672 		 * If we've been adjusting the clock, the todr
673 		 * will be out of synch; adjust it now.
674 		 */
675 		resettodr();
676 	}
677 	(void) splhigh();		/* extreme priority */
678 	if (howto & RB_HALT) {
679 		halt(howto);
680 		/*NOTREACHED*/
681 	} else {
682 		if (howto & RB_DUMP)
683 			dumpsys();
684 		halt(howto);
685 		/*NOTREACHED*/
686 	}
687 	/*NOTREACHED*/
688 }
689 
690 halt(howto)
691 	int howto;
692 {
693 	if (*(volatile u_char *)DIP_SWITCH & 0x20)
694 		howto |= RB_HALT;
695 	to_monitor(howto);
696 	/*NOTREACHED*/
697 }
698 
699 int	dumpmag = 0x8fca0101;	/* magic number for savecore */
700 int	dumpsize = 0;		/* also for savecore */
701 long	dumplo = 0;
702 
703 dumpconf()
704 {
705 	int nblks;
706 
707 	dumpsize = physmem;
708 	if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
709 		nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
710 		if (dumpsize > btoc(dbtob(nblks - dumplo)))
711 			dumpsize = btoc(dbtob(nblks - dumplo));
712 		else if (dumplo == 0)
713 			dumplo = nblks - btodb(ctob(physmem));
714 	}
715 	/*
716 	 * Don't dump on the first CLBYTES (why CLBYTES?)
717 	 * in case the dump device includes a disk label.
718 	 */
719 	if (dumplo < btodb(CLBYTES))
720 		dumplo = btodb(CLBYTES);
721 }
722 
723 /*
724  * Doadump comes here after turning off memory management and
725  * getting on the dump stack, either when called above, or by
726  * the auto-restart code.
727  */
728 dumpsys()
729 {
730 	int error;
731 
732 	msgbufmapped = 0;
733 	if (dumpdev == NODEV)
734 		return;
735 	/*
736 	 * For dumps during autoconfiguration,
737 	 * if dump device has already configured...
738 	 */
739 	if (dumpsize == 0)
740 		dumpconf();
741 	if (dumplo < 0)
742 		return;
743 	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
744 	printf("dump ");
745 	switch (error = (*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
746 
747 	case ENXIO:
748 		printf("device bad\n");
749 		break;
750 
751 	case EFAULT:
752 		printf("device not ready\n");
753 		break;
754 
755 	case EINVAL:
756 		printf("area improper\n");
757 		break;
758 
759 	case EIO:
760 		printf("i/o error\n");
761 		break;
762 
763 	default:
764 		printf("error %d\n", error);
765 		break;
766 
767 	case 0:
768 		printf("succeeded\n");
769 	}
770 }
771 
772 /*
773  * Return the best possible estimate of the time in the timeval
774  * to which tvp points.  Unfortunately, we can't read the hardware registers.
775  * We guarantee that the time will be greater than the value obtained by a
776  * previous call.
777  */
778 microtime(tvp)
779 	register struct timeval *tvp;
780 {
781 	int s = splclock();
782 	static struct timeval lasttime;
783 
784 	*tvp = time;
785 #ifdef notdef
786 	tvp->tv_usec += clkread();
787 	while (tvp->tv_usec > 1000000) {
788 		tvp->tv_sec++;
789 		tvp->tv_usec -= 1000000;
790 	}
791 #endif
792 	if (tvp->tv_sec == lasttime.tv_sec &&
793 	    tvp->tv_usec <= lasttime.tv_usec &&
794 	    (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
795 		tvp->tv_sec++;
796 		tvp->tv_usec -= 1000000;
797 	}
798 	lasttime = *tvp;
799 	splx(s);
800 }
801 
802 initcpu()
803 {
804 
805 	/*
806 	 * clear LEDs
807 	 */
808 	*(char*)DEBUG_PORT = (char)DP_WRITE|DP_LED0|DP_LED1|DP_LED2|DP_LED3;
809 
810 	/*
811 	 * clear all interrupts
812 	 */
813 	*(char*)INTCLR0 = 0;
814 	*(char*)INTCLR1 = 0;
815 
816 	/*
817 	 * It's not a time to enable timer yet.
818 	 *
819 	 *	INTEN0:  PERR ABORT BERR TIMER KBD  MS    CFLT CBSY
820 	 *		  o     o    o     x    o    o     x    x
821 	 *	INTEN1:  BEEP SCC  LANCE DMA  SLOT1 SLOT3 EXT1 EXT3
822 	 *		  x     o    o     o    o    o     x    x
823 	 */
824 
825 	*(char*)INTEN0 = (char) INTEN0_PERR|INTEN0_ABORT|INTEN0_BERR|
826 				INTEN0_KBDINT|INTEN0_MSINT;
827 
828 	*(char*)INTEN1 = (char) INTEN1_SCC|INTEN1_LANCE|INTEN1_DMA|
829 				INTEN1_SLOT1|INTEN1_SLOT3;
830 
831 	spl0();		/* safe to turn interrupts on now */
832 }
833 
834 /*
835  * Convert an ASCII string into an integer.
836  */
837 int
838 atoi(s)
839 	char *s;
840 {
841 	int c;
842 	unsigned base = 10, d;
843 	int neg = 0, val = 0;
844 
845 	if (s == 0 || (c = *s++) == 0)
846 		goto out;
847 
848 	/* skip spaces if any */
849 	while (c == ' ' || c == '\t')
850 		c = *s++;
851 
852 	/* parse sign, allow more than one (compat) */
853 	while (c == '-') {
854 		neg = !neg;
855 		c = *s++;
856 	}
857 
858 	/* parse base specification, if any */
859 	if (c == '0') {
860 		c = *s++;
861 		switch (c) {
862 		case 'X':
863 		case 'x':
864 			base = 16;
865 			break;
866 		case 'B':
867 		case 'b':
868 			base = 2;
869 			break;
870 		default:
871 			base = 8;
872 			break;
873 		}
874 	}
875 
876 	/* parse number proper */
877 	for (;;) {
878 		if (c >= '0' && c <= '9')
879 			d = c - '0';
880 		else if (c >= 'a' && c <= 'z')
881 			d = c - 'a' + 10;
882 		else if (c >= 'A' && c <= 'Z')
883 			d = c - 'A' + 10;
884 		else
885 			break;
886 		val *= base;
887 		val += d;
888 		c = *s++;
889 	}
890 	if (neg)
891 		val = -val;
892 out:
893 	return val;
894 }
895 
896 #ifdef CPU_SINGLE
897 /*
898  * small ring buffers for keyboard/mouse
899  */
900 struct ring_buf {
901 	u_char head;
902 	u_char tail;
903 	u_char count;
904 	u_char buf[13];
905 } ring_buf[2];
906 
907 xputc(c, chan)
908 	u_char c;
909 	int chan;
910 {
911 	register struct ring_buf *p = &ring_buf[chan];
912 	int s = splhigh();
913 
914 	if (p->count >= sizeof (p->buf)) {
915 		(void) splx(s);
916 		return (-1);
917 	}
918 	p->buf[p->head] = c;
919 	if (++p->head >= sizeof (p->buf))
920 		p->head = 0;
921 	p->count++;
922 	(void) splx(s);
923 	return (c);
924 }
925 
926 xgetc(chan)
927 	int chan;
928 {
929 	register struct ring_buf *p = &ring_buf[chan];
930 	int c;
931 	int s = splhigh();
932 
933 	if (p->count == 0) {
934 		(void) splx(s);
935 		return (-1);
936 	}
937 	c = p->buf[p->tail];
938 	if (++p->tail >= sizeof (p->buf))
939 		p->tail = 0;
940 	p->count--;
941 	(void) splx(s);
942 	return (c);
943 }
944 #endif /* CPU_SINGLE */
945