xref: /original-bsd/sys/hp300/hp300/machdep.c (revision a6d8c59f)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1982, 1986, 1990 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.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: machdep.c 1.68 92/01/20$
13  *
14  *	@(#)machdep.c	7.33 (Berkeley) 10/11/92
15  */
16 
17 #include <sys/param.h>
18 #include <sys/systm.h>
19 #include <sys/signalvar.h>
20 #include <sys/kernel.h>
21 #include <sys/map.h>
22 #include <sys/proc.h>
23 #include <sys/buf.h>
24 #include <sys/reboot.h>
25 #include <sys/conf.h>
26 #include <sys/file.h>
27 #include <sys/clist.h>
28 #include <sys/callout.h>
29 #include <sys/malloc.h>
30 #include <sys/mbuf.h>
31 #include <sys/msgbuf.h>
32 #include <sys/mount.h>
33 #include <sys/user.h>
34 #include <sys/exec.h>
35 #ifdef SYSVSHM
36 #include <sys/shm.h>
37 #endif
38 #ifdef HPUXCOMPAT
39 #include <hp/hpux/hpux.h>
40 #endif
41 
42 #include <machine/cpu.h>
43 #include <machine/reg.h>
44 #include <machine/psl.h>
45 #include <hp300/hp300/isr.h>
46 #include <hp300/hp300/pte.h>
47 #include <net/netisr.h>
48 
49 #define	MAXMEM	64*1024*CLSIZE	/* XXX - from cmap.h */
50 #include <vm/vm_kern.h>
51 
52 vm_map_t buffer_map;
53 extern vm_offset_t avail_end;
54 
55 /*
56  * Declare these as initialized data so we can patch them.
57  */
58 int	nswbuf = 0;
59 #ifdef	NBUF
60 int	nbuf = NBUF;
61 #else
62 int	nbuf = 0;
63 #endif
64 #ifdef	BUFPAGES
65 int	bufpages = BUFPAGES;
66 #else
67 int	bufpages = 0;
68 #endif
69 int	msgbufmapped;		/* set when safe to use msgbuf */
70 int	maxmem;			/* max memory per process */
71 int	physmem = MAXMEM;	/* max supported memory, changes to actual */
72 /*
73  * safepri is a safe priority for sleep to set for a spin-wait
74  * during autoconfiguration or after a panic.
75  */
76 int	safepri = PSL_LOWIPL;
77 
78 extern	u_int lowram;
79 
80 /*
81  * Console initialization: called early on from main,
82  * before vm init or startup.  Do enough configuration
83  * to choose and initialize a console.
84  */
85 consinit()
86 {
87 
88 	/*
89 	 * Set cpuspeed immediately since cninit() called routines
90 	 * might use delay.
91 	 */
92 	switch (machineid) {
93 	case HP_320:
94 	case HP_330:
95 	case HP_340:
96 		cpuspeed = MHZ_16;
97 		break;
98 	case HP_350:
99 	case HP_360:
100 		cpuspeed = MHZ_25;
101 		break;
102 	case HP_370:
103 		cpuspeed = MHZ_33;
104 		break;
105 	case HP_375:
106 		cpuspeed = MHZ_50;
107 		break;
108 	case HP_380:
109 		cpuspeed = MHZ_25 * 2;	/* XXX */
110 		break;
111 	}
112 	/*
113          * Find what hardware is attached to this machine.
114          */
115 	find_devs();
116 
117 	/*
118 	 * Initialize the console before we print anything out.
119 	 */
120 	cninit();
121 }
122 
123 /*
124  * cpu_startup: allocate memory for variable-sized tables,
125  * initialize cpu, and do autoconfiguration.
126  */
127 cpu_startup()
128 {
129 	register unsigned i;
130 	register caddr_t v, firstaddr;
131 	int base, residual;
132 	vm_offset_t minaddr, maxaddr;
133 	vm_size_t size;
134 #ifdef DEBUG
135 	extern int pmapdebug;
136 	int opmapdebug = pmapdebug;
137 
138 	pmapdebug = 0;
139 #endif
140 
141 	/*
142 	 * Initialize error message buffer (at end of core).
143 	 * avail_end was pre-decremented in pmap_bootstrap to compensate.
144 	 */
145 	for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
146 		pmap_enter(kernel_pmap, (vm_offset_t)msgbufp,
147 		    avail_end + i * NBPG, VM_PROT_ALL, TRUE);
148 	msgbufmapped = 1;
149 
150 	/*
151 	 * Good {morning,afternoon,evening,night}.
152 	 */
153 	printf(version);
154 	identifycpu();
155 	printf("real mem = %d\n", ctob(physmem));
156 
157 	/*
158 	 * Allocate space for system data structures.
159 	 * The first available real memory address is in "firstaddr".
160 	 * The first available kernel virtual address is in "v".
161 	 * As pages of kernel virtual memory are allocated, "v" is incremented.
162 	 * As pages of memory are allocated and cleared,
163 	 * "firstaddr" is incremented.
164 	 * An index into the kernel page table corresponding to the
165 	 * virtual memory address maintained in "v" is kept in "mapaddr".
166 	 */
167 	/*
168 	 * Make two passes.  The first pass calculates how much memory is
169 	 * needed and allocates it.  The second pass assigns virtual
170 	 * addresses to the various data structures.
171 	 */
172 	firstaddr = 0;
173 again:
174 	v = (caddr_t)firstaddr;
175 
176 #define	valloc(name, type, num) \
177 	    (name) = (type *)v; v = (caddr_t)((name)+(num))
178 #define	valloclim(name, type, num, lim) \
179 	    (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
180 	valloc(cfree, struct cblock, nclist);
181 	valloc(callout, struct callout, ncallout);
182 	valloc(swapmap, struct map, nswapmap = maxproc * 2);
183 #ifdef SYSVSHM
184 	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
185 #endif
186 
187 	/*
188 	 * Determine how many buffers to allocate.
189 	 * Since HPs tend to be long on memory and short on disk speed,
190 	 * we allocate more buffer space than the BSD standard of
191 	 * use 10% of memory for the first 2 Meg, 5% of remaining.
192 	 * We just allocate a flat 10%.  Insure a minimum of 16 buffers.
193 	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
194 	 */
195 	if (bufpages == 0)
196 		bufpages = physmem / 10 / CLSIZE;
197 	if (nbuf == 0) {
198 		nbuf = bufpages;
199 		if (nbuf < 16)
200 			nbuf = 16;
201 	}
202 	if (nswbuf == 0) {
203 		nswbuf = (nbuf / 2) &~ 1;	/* force even */
204 		if (nswbuf > 256)
205 			nswbuf = 256;		/* sanity */
206 	}
207 	valloc(swbuf, struct buf, nswbuf);
208 	valloc(buf, struct buf, nbuf);
209 	/*
210 	 * End of first pass, size has been calculated so allocate memory
211 	 */
212 	if (firstaddr == 0) {
213 		size = (vm_size_t)(v - firstaddr);
214 		firstaddr = (caddr_t) kmem_alloc(kernel_map, round_page(size));
215 		if (firstaddr == 0)
216 			panic("startup: no room for tables");
217 		goto again;
218 	}
219 	/*
220 	 * End of second pass, addresses have been assigned
221 	 */
222 	if ((vm_size_t)(v - firstaddr) != size)
223 		panic("startup: table size inconsistency");
224 	/*
225 	 * Now allocate buffers proper.  They are different than the above
226 	 * in that they usually occupy more virtual memory than physical.
227 	 */
228 	size = MAXBSIZE * nbuf;
229 	buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
230 				   &maxaddr, size, FALSE);
231 	minaddr = (vm_offset_t)buffers;
232 	if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
233 			&minaddr, size, FALSE) != KERN_SUCCESS)
234 		panic("startup: cannot allocate buffers");
235 	base = bufpages / nbuf;
236 	residual = bufpages % nbuf;
237 	for (i = 0; i < nbuf; i++) {
238 		vm_size_t curbufsize;
239 		vm_offset_t curbuf;
240 
241 		/*
242 		 * First <residual> buffers get (base+1) physical pages
243 		 * allocated for them.  The rest get (base) physical pages.
244 		 *
245 		 * The rest of each buffer occupies virtual space,
246 		 * but has no physical memory allocated for it.
247 		 */
248 		curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
249 		curbufsize = CLBYTES * (i < residual ? base+1 : base);
250 		vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
251 		vm_map_simplify(buffer_map, curbuf);
252 	}
253 	/*
254 	 * Allocate a submap for exec arguments.  This map effectively
255 	 * limits the number of processes exec'ing at any time.
256 	 */
257 	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
258 				 16*NCARGS, TRUE);
259 	/*
260 	 * Allocate a submap for physio
261 	 */
262 	phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
263 				 VM_PHYS_SIZE, TRUE);
264 
265 	/*
266 	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
267 	 * we use the more space efficient malloc in place of kmem_alloc.
268 	 */
269 	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
270 				   M_MBUF, M_NOWAIT);
271 	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
272 	mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
273 			       VM_MBUF_SIZE, FALSE);
274 	/*
275 	 * Initialize callouts
276 	 */
277 	callfree = callout;
278 	for (i = 1; i < ncallout; i++)
279 		callout[i-1].c_next = &callout[i];
280 	callout[i-1].c_next = NULL;
281 
282 #ifdef DEBUG
283 	pmapdebug = opmapdebug;
284 #endif
285 	printf("avail mem = %d\n", ptoa(cnt.v_free_count));
286 	printf("using %d buffers containing %d bytes of memory\n",
287 		nbuf, bufpages * CLBYTES);
288 	/*
289 	 * Set up CPU-specific registers, cache, etc.
290 	 */
291 	initcpu();
292 
293 	/*
294 	 * Set up buffers, so they can be used to read disk labels.
295 	 */
296 	bufinit();
297 
298 	/*
299 	 * Configure the system.
300 	 */
301 	configure();
302 }
303 
304 /*
305  * Set registers on exec.
306  * XXX Should clear registers except sp, pc,
307  * but would break init; should be fixed soon.
308  */
309 setregs(p, entry, retval)
310 	register struct proc *p;
311 	u_long entry;
312 	int retval[2];
313 {
314 	p->p_md.md_regs[PC] = entry & ~1;
315 #ifdef FPCOPROC
316 	/* restore a null state frame */
317 	p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
318 	m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
319 #endif
320 #ifdef HPUXCOMPAT
321 	if (p->p_flag & SHPUX) {
322 
323 		p->p_md.md_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */
324 		retval[0] = 0;		/* no float card */
325 #ifdef FPCOPROC
326 		retval[1] = 1;		/* yes 68881 */
327 #else
328 		retval[1] = 0;		/* no 68881 */
329 #endif
330 	}
331 	/*
332 	 * XXX This doesn't have much to do with setting registers but
333 	 * I didn't want to muck up kern_exec.c with this code, so I
334 	 * stuck it here.
335 	 *
336 	 * Ensure we perform the right action on traps type 1 and 2:
337 	 * If our parent is an HPUX process and we are being traced, turn
338 	 * on HPUX style interpretation.  Else if we were using the HPUX
339 	 * style interpretation, revert to the BSD interpretation.
340 	 *
341 	 * Note that we do this by changing the trap instruction in the
342 	 * global "sigcode" array which then gets copied out to the user's
343 	 * sigcode in the stack.  Since we are changing it in the global
344 	 * array we must always reset it, even for non-HPUX processes.
345 	 *
346 	 * Note also that implementing it in this way creates a potential
347 	 * race where we could have tweaked it for process A which then
348 	 * blocks in the copyout to the stack and process B comes along
349 	 * and untweaks it causing A to wind up with the wrong setting
350 	 * when the copyout continues.  However, since we have already
351 	 * copied something out to this user stack page (thereby faulting
352 	 * it in), this scenerio is extremely unlikely.
353 	 */
354 	{
355 		extern short sigcodetrap[];
356 
357 		if ((p->p_pptr->p_flag & SHPUX) && (p->p_flag & STRC)) {
358 			p->p_addr->u_pcb.pcb_flags |= PCB_HPUXTRACE;
359 			*sigcodetrap = 0x4E42;
360 		} else {
361 			p->p_addr->u_pcb.pcb_flags &= ~PCB_HPUXTRACE;
362 			*sigcodetrap = 0x4E41;
363 		}
364 	}
365 #endif
366 }
367 
368 identifycpu()
369 {
370 
371 	printf("HP9000/");
372 	switch (machineid) {
373 	case HP_320:
374 		printf("320 (16.67Mhz");
375 		break;
376 	case HP_330:
377 		printf("318/319/330 (16.67Mhz");
378 		break;
379 	case HP_340:
380 		printf("340 (16.67Mhz");
381 		break;
382 	case HP_350:
383 		printf("350 (25Mhz");
384 		break;
385 	case HP_360:
386 		printf("360 (25Mhz");
387 		break;
388 	case HP_370:
389 		printf("370 (33.33Mhz");
390 		break;
391 	case HP_375:
392 		printf("345/375 (50Mhz");
393 		break;
394 	case HP_380:
395 		printf("380/425 (25Mhz)");
396 		break;
397 	default:
398 		printf("\nunknown machine type %d\n", machineid);
399 		panic("startup");
400 	}
401 	printf(" MC680%s CPU",
402 	       mmutype == MMU_68040 ? "40" :
403 	       (mmutype == MMU_68030 ? "30" : "20"));
404 	switch (mmutype) {
405 	case MMU_68040:
406 	case MMU_68030:
407 		printf("+MMU");
408 		break;
409 	case MMU_68851:
410 		printf(", MC68851 MMU");
411 		break;
412 	case MMU_HP:
413 		printf(", HP MMU");
414 		break;
415 	default:
416 		printf("\nunknown MMU type %d\n", mmutype);
417 		panic("startup");
418 	}
419 	if (mmutype == MMU_68040)
420 		printf("+FPU, 4k on-chip physical I/D caches");
421 	else if (mmutype == MMU_68030)
422 		printf(", %sMhz MC68882 FPU",
423 		       machineid == HP_340 ? "16.67" :
424 		       (machineid == HP_360 ? "25" :
425 			(machineid == HP_370 ? "33.33" : "50")));
426 	else
427 		printf(", %sMhz MC68881 FPU",
428 		       machineid == HP_350 ? "20" : "16.67");
429 	switch (ectype) {
430 	case EC_VIRT:
431 		printf(", %dK virtual-address cache",
432 		       machineid == HP_320 ? 16 : 32);
433 		break;
434 	case EC_PHYS:
435 		printf(", %dK physical-address cache",
436 		       machineid == HP_370 ? 64 : 32);
437 		break;
438 	}
439 	printf(")\n");
440 	/*
441 	 * Now that we have told the user what they have,
442 	 * let them know if that machine type isn't configured.
443 	 */
444 	switch (machineid) {
445 	case -1:		/* keep compilers happy */
446 #if !defined(HP320) && !defined(HP350)
447 	case HP_320:
448 	case HP_350:
449 #endif
450 #ifndef HP330
451 	case HP_330:
452 #endif
453 #if !defined(HP360) && !defined(HP370)
454 	case HP_340:
455 	case HP_360:
456 	case HP_370:
457 #endif
458 #if !defined(HP380)
459 	case HP_380:
460 #endif
461 		panic("CPU type not configured");
462 	default:
463 		break;
464 	}
465 }
466 
467 #define SS_RTEFRAME	1
468 #define SS_FPSTATE	2
469 #define SS_USERREGS	4
470 
471 struct sigstate {
472 	int	ss_flags;		/* which of the following are valid */
473 	struct	frame ss_frame;		/* original exception frame */
474 	struct	fpframe ss_fpstate;	/* 68881/68882 state info */
475 };
476 
477 /*
478  * WARNING: code in locore.s assumes the layout shown for sf_signum
479  * thru sf_handler so... don't screw with them!
480  */
481 struct sigframe {
482 	int	sf_signum;		/* signo for handler */
483 	int	sf_code;		/* additional info for handler */
484 	struct	sigcontext *sf_scp;	/* context ptr for handler */
485 	sig_t	sf_handler;		/* handler addr for u_sigc */
486 	struct	sigstate sf_state;	/* state of the hardware */
487 	struct	sigcontext sf_sc;	/* actual context */
488 };
489 
490 #ifdef HPUXCOMPAT
491 struct	hpuxsigcontext {
492 	int	hsc_syscall;
493 	char	hsc_action;
494 	char	hsc_pad1;
495 	char	hsc_pad2;
496 	char	hsc_onstack;
497 	int	hsc_mask;
498 	int	hsc_sp;
499 	short	hsc_ps;
500 	int	hsc_pc;
501 /* the rest aren't part of the context but are included for our convenience */
502 	short	hsc_pad;
503 	u_int	hsc_magic;		/* XXX sigreturn: cookie */
504 	struct	sigcontext *hsc_realsc;	/* XXX sigreturn: ptr to BSD context */
505 };
506 
507 /*
508  * For an HP-UX process, a partial hpuxsigframe follows the normal sigframe.
509  * Tremendous waste of space, but some HP-UX applications (e.g. LCL) need it.
510  */
511 struct hpuxsigframe {
512 	int	hsf_signum;
513 	int	hsf_code;
514 	struct	sigcontext *hsf_scp;
515 	struct	hpuxsigcontext hsf_sc;
516 	int	hsf_regs[15];
517 };
518 #endif
519 
520 #ifdef DEBUG
521 int sigdebug = 0;
522 int sigpid = 0;
523 #define SDB_FOLLOW	0x01
524 #define SDB_KSTACK	0x02
525 #define SDB_FPSTATE	0x04
526 #endif
527 
528 /*
529  * Send an interrupt to process.
530  */
531 void
532 sendsig(catcher, sig, mask, code)
533 	sig_t catcher;
534 	int sig, mask;
535 	unsigned code;
536 {
537 	register struct proc *p = curproc;
538 	register struct sigframe *fp, *kfp;
539 	register struct frame *frame;
540 	register struct sigacts *psp = p->p_sigacts;
541 	register short ft;
542 	int oonstack, fsize;
543 	extern short exframesize[];
544 	extern char sigcode[], esigcode[];
545 
546 	frame = (struct frame *)p->p_md.md_regs;
547 	ft = frame->f_format;
548 	oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
549 	/*
550 	 * Allocate and validate space for the signal handler
551 	 * context. Note that if the stack is in P0 space, the
552 	 * call to grow() is a nop, and the useracc() check
553 	 * will fail if the process has not already allocated
554 	 * the space with a `brk'.
555 	 */
556 #ifdef HPUXCOMPAT
557 	if (p->p_flag & SHPUX)
558 		fsize = sizeof(struct sigframe) + sizeof(struct hpuxsigframe);
559 	else
560 #endif
561 	fsize = sizeof(struct sigframe);
562 	if ((psp->ps_flags & SAS_ALTSTACK) &&
563 	    (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
564 	    (psp->ps_sigonstack & sigmask(sig))) {
565 		fp = (struct sigframe *)(psp->ps_sigstk.ss_base +
566 					 psp->ps_sigstk.ss_size - fsize);
567 		psp->ps_sigstk.ss_flags |= SA_ONSTACK;
568 	} else
569 		fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
570 	if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
571 		(void)grow(p, (unsigned)fp);
572 #ifdef DEBUG
573 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
574 		printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n",
575 		       p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
576 #endif
577 	if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) {
578 #ifdef DEBUG
579 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
580 			printf("sendsig(%d): useracc failed on sig %d\n",
581 			       p->p_pid, sig);
582 #endif
583 		/*
584 		 * Process has trashed its stack; give it an illegal
585 		 * instruction to halt it in its tracks.
586 		 */
587 		SIGACTION(p, SIGILL) = SIG_DFL;
588 		sig = sigmask(SIGILL);
589 		p->p_sigignore &= ~sig;
590 		p->p_sigcatch &= ~sig;
591 		p->p_sigmask &= ~sig;
592 		psignal(p, SIGILL);
593 		return;
594 	}
595 	kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
596 	/*
597 	 * Build the argument list for the signal handler.
598 	 */
599 	kfp->sf_signum = sig;
600 	kfp->sf_code = code;
601 	kfp->sf_scp = &fp->sf_sc;
602 	kfp->sf_handler = catcher;
603 	/*
604 	 * Save necessary hardware state.  Currently this includes:
605 	 *	- general registers
606 	 *	- original exception frame (if not a "normal" frame)
607 	 *	- FP coprocessor state
608 	 */
609 	kfp->sf_state.ss_flags = SS_USERREGS;
610 	bcopy((caddr_t)frame->f_regs,
611 	      (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
612 	if (ft >= FMT7) {
613 #ifdef DEBUG
614 		if (ft != FMT9 && ft != FMTA && ft != FMTB
615 #if defined(HP380)
616 		    && mmutype != MMU_68040 || mmutype==MMU_68040 && ft != FMT7
617 #endif
618 		    )
619 			panic("sendsig: bogus frame type");
620 #endif
621 		kfp->sf_state.ss_flags |= SS_RTEFRAME;
622 		kfp->sf_state.ss_frame.f_format = frame->f_format;
623 		kfp->sf_state.ss_frame.f_vector = frame->f_vector;
624 		bcopy((caddr_t)&frame->F_u,
625 		      (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]);
626 		/*
627 		 * Leave an indicator that we need to clean up the kernel
628 		 * stack.  We do this by setting the "pad word" above the
629 		 * hardware stack frame to the amount the stack must be
630 		 * adjusted by.
631 		 *
632 		 * N.B. we increment rather than just set f_stackadj in
633 		 * case we are called from syscall when processing a
634 		 * sigreturn.  In that case, f_stackadj may be non-zero.
635 		 */
636 		frame->f_stackadj += exframesize[ft];
637 		frame->f_format = frame->f_vector = 0;
638 #ifdef DEBUG
639 		if (sigdebug & SDB_FOLLOW)
640 			printf("sendsig(%d): copy out %d of frame %d\n",
641 			       p->p_pid, exframesize[ft], ft);
642 #endif
643 	}
644 #ifdef FPCOPROC
645 	kfp->sf_state.ss_flags |= SS_FPSTATE;
646 	m68881_save(&kfp->sf_state.ss_fpstate);
647 #ifdef DEBUG
648 	if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
649 		printf("sendsig(%d): copy out FP state (%x) to %x\n",
650 		       p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
651 		       &kfp->sf_state.ss_fpstate);
652 #endif
653 #endif
654 	/*
655 	 * Build the signal context to be used by sigreturn.
656 	 */
657 	kfp->sf_sc.sc_onstack = oonstack;
658 	kfp->sf_sc.sc_mask = mask;
659 	kfp->sf_sc.sc_sp = frame->f_regs[SP];
660 	kfp->sf_sc.sc_fp = frame->f_regs[A6];
661 	kfp->sf_sc.sc_ap = (int)&fp->sf_state;
662 	kfp->sf_sc.sc_pc = frame->f_pc;
663 	kfp->sf_sc.sc_ps = frame->f_sr;
664 #ifdef HPUXCOMPAT
665 	/*
666 	 * Create an HP-UX style sigcontext structure and associated goo
667 	 */
668 	if (p->p_flag & SHPUX) {
669 		register struct hpuxsigframe *hkfp;
670 
671 		hkfp = (struct hpuxsigframe *)&kfp[1];
672 		hkfp->hsf_signum = bsdtohpuxsig(kfp->sf_signum);
673 		hkfp->hsf_code = kfp->sf_code;
674 		hkfp->hsf_scp = (struct sigcontext *)
675 			&((struct hpuxsigframe *)(&fp[1]))->hsf_sc;
676 		hkfp->hsf_sc.hsc_syscall = 0;		/* XXX */
677 		hkfp->hsf_sc.hsc_action = 0;		/* XXX */
678 		hkfp->hsf_sc.hsc_pad1 = hkfp->hsf_sc.hsc_pad2 = 0;
679 		hkfp->hsf_sc.hsc_onstack = kfp->sf_sc.sc_onstack;
680 		hkfp->hsf_sc.hsc_mask = kfp->sf_sc.sc_mask;
681 		hkfp->hsf_sc.hsc_sp = kfp->sf_sc.sc_sp;
682 		hkfp->hsf_sc.hsc_ps = kfp->sf_sc.sc_ps;
683 		hkfp->hsf_sc.hsc_pc = kfp->sf_sc.sc_pc;
684 		hkfp->hsf_sc.hsc_pad = 0;
685 		hkfp->hsf_sc.hsc_magic = 0xdeadbeef;
686 		hkfp->hsf_sc.hsc_realsc = kfp->sf_scp;
687 		bcopy((caddr_t)frame->f_regs, (caddr_t)hkfp->hsf_regs,
688 		      sizeof (hkfp->hsf_regs));
689 
690 		kfp->sf_signum = hkfp->hsf_signum;
691 		kfp->sf_scp = hkfp->hsf_scp;
692 	}
693 #endif
694 	(void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
695 	frame->f_regs[SP] = (int)fp;
696 #ifdef DEBUG
697 	if (sigdebug & SDB_FOLLOW)
698 		printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n",
699 		       p->p_pid, sig, kfp->sf_scp, fp,
700 		       kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
701 #endif
702 	/*
703 	 * Signal trampoline code is at base of user stack.
704 	 */
705 	frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode);
706 #ifdef DEBUG
707 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
708 		printf("sendsig(%d): sig %d returns\n",
709 		       p->p_pid, sig);
710 #endif
711 	free((caddr_t)kfp, M_TEMP);
712 }
713 
714 /*
715  * System call to cleanup state after a signal
716  * has been taken.  Reset signal mask and
717  * stack state from context left by sendsig (above).
718  * Return to previous pc and psl as specified by
719  * context left by sendsig. Check carefully to
720  * make sure that the user has not modified the
721  * psl to gain improper priviledges or to cause
722  * a machine fault.
723  */
724 struct sigreturn_args {
725 	struct sigcontext *sigcntxp;
726 };
727 /* ARGSUSED */
728 sigreturn(p, uap, retval)
729 	struct proc *p;
730 	struct sigreturn_args *uap;
731 	int *retval;
732 {
733 	register struct sigcontext *scp;
734 	register struct frame *frame;
735 	register int rf;
736 	struct sigcontext tsigc;
737 	struct sigstate tstate;
738 	int flags;
739 	extern short exframesize[];
740 
741 	scp = uap->sigcntxp;
742 #ifdef DEBUG
743 	if (sigdebug & SDB_FOLLOW)
744 		printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
745 #endif
746 	if ((int)scp & 1)
747 		return (EINVAL);
748 #ifdef HPUXCOMPAT
749 	/*
750 	 * Grab context as an HP-UX style context and determine if it
751 	 * was one that we contructed in sendsig.
752 	 */
753 	if (p->p_flag & SHPUX) {
754 		struct hpuxsigcontext *hscp = (struct hpuxsigcontext *)scp;
755 		struct hpuxsigcontext htsigc;
756 
757 		if (useracc((caddr_t)hscp, sizeof (*hscp), B_WRITE) == 0 ||
758 		    copyin((caddr_t)hscp, (caddr_t)&htsigc, sizeof htsigc))
759 			return (EINVAL);
760 		/*
761 		 * If not generated by sendsig or we cannot restore the
762 		 * BSD-style sigcontext, just restore what we can -- state
763 		 * will be lost, but them's the breaks.
764 		 */
765 		hscp = &htsigc;
766 		if (hscp->hsc_magic != 0xdeadbeef ||
767 		    (scp = hscp->hsc_realsc) == 0 ||
768 		    useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
769 		    copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) {
770 			if (hscp->hsc_onstack & 01)
771 				p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
772 			else
773 				p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
774 			p->p_sigmask = hscp->hsc_mask &~ sigcantmask;
775 			frame = (struct frame *) p->p_md.md_regs;
776 			frame->f_regs[SP] = hscp->hsc_sp;
777 			frame->f_pc = hscp->hsc_pc;
778 			frame->f_sr = hscp->hsc_ps &~ PSL_USERCLR;
779 			return (EJUSTRETURN);
780 		}
781 		/*
782 		 * Otherwise, overlay BSD context with possibly modified
783 		 * HP-UX values.
784 		 */
785 		tsigc.sc_onstack = hscp->hsc_onstack;
786 		tsigc.sc_mask = hscp->hsc_mask;
787 		tsigc.sc_sp = hscp->hsc_sp;
788 		tsigc.sc_ps = hscp->hsc_ps;
789 		tsigc.sc_pc = hscp->hsc_pc;
790 	} else
791 #endif
792 	/*
793 	 * Test and fetch the context structure.
794 	 * We grab it all at once for speed.
795 	 */
796 	if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
797 	    copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
798 		return (EINVAL);
799 	scp = &tsigc;
800 	if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
801 		return (EINVAL);
802 	/*
803 	 * Restore the user supplied information
804 	 */
805 	if (scp->sc_onstack & 01)
806 		p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
807 	else
808 		p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
809 	p->p_sigmask = scp->sc_mask &~ sigcantmask;
810 	frame = (struct frame *) p->p_md.md_regs;
811 	frame->f_regs[SP] = scp->sc_sp;
812 	frame->f_regs[A6] = scp->sc_fp;
813 	frame->f_pc = scp->sc_pc;
814 	frame->f_sr = scp->sc_ps;
815 	/*
816 	 * Grab pointer to hardware state information.
817 	 * If zero, the user is probably doing a longjmp.
818 	 */
819 	if ((rf = scp->sc_ap) == 0)
820 		return (EJUSTRETURN);
821 	/*
822 	 * See if there is anything to do before we go to the
823 	 * expense of copying in close to 1/2K of data
824 	 */
825 	flags = fuword((caddr_t)rf);
826 #ifdef DEBUG
827 	if (sigdebug & SDB_FOLLOW)
828 		printf("sigreturn(%d): sc_ap %x flags %x\n",
829 		       p->p_pid, rf, flags);
830 #endif
831 	/*
832 	 * fuword failed (bogus sc_ap value).
833 	 */
834 	if (flags == -1)
835 		return (EINVAL);
836 	if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
837 		return (EJUSTRETURN);
838 #ifdef DEBUG
839 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
840 		printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
841 		       p->p_pid, &flags, scp->sc_sp, uap->sigcntxp,
842 		       (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
843 #endif
844 	/*
845 	 * Restore most of the users registers except for A6 and SP
846 	 * which were handled above.
847 	 */
848 	if (flags & SS_USERREGS)
849 		bcopy((caddr_t)tstate.ss_frame.f_regs,
850 		      (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
851 	/*
852 	 * Restore long stack frames.  Note that we do not copy
853 	 * back the saved SR or PC, they were picked up above from
854 	 * the sigcontext structure.
855 	 */
856 	if (flags & SS_RTEFRAME) {
857 		register int sz;
858 
859 		/* grab frame type and validate */
860 		sz = tstate.ss_frame.f_format;
861 		if (sz > 15 || (sz = exframesize[sz]) < 0)
862 			return (EINVAL);
863 		frame->f_stackadj -= sz;
864 		frame->f_format = tstate.ss_frame.f_format;
865 		frame->f_vector = tstate.ss_frame.f_vector;
866 		bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
867 #ifdef DEBUG
868 		if (sigdebug & SDB_FOLLOW)
869 			printf("sigreturn(%d): copy in %d of frame type %d\n",
870 			       p->p_pid, sz, tstate.ss_frame.f_format);
871 #endif
872 	}
873 #ifdef FPCOPROC
874 	/*
875 	 * Finally we restore the original FP context
876 	 */
877 	if (flags & SS_FPSTATE)
878 		m68881_restore(&tstate.ss_fpstate);
879 #ifdef DEBUG
880 	if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
881 		printf("sigreturn(%d): copied in FP state (%x) at %x\n",
882 		       p->p_pid, *(u_int *)&tstate.ss_fpstate,
883 		       &tstate.ss_fpstate);
884 #endif
885 #endif
886 #ifdef DEBUG
887 	if ((sigdebug & SDB_FOLLOW) ||
888 	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
889 		printf("sigreturn(%d): returns\n", p->p_pid);
890 #endif
891 	return (EJUSTRETURN);
892 }
893 
894 int	waittime = -1;
895 
896 boot(howto)
897 	register int howto;
898 {
899 	/* take a snap shot before clobbering any registers */
900 	if (curproc)
901 		savectx(curproc->p_addr, 0);
902 
903 	boothowto = howto;
904 	if ((howto&RB_NOSYNC) == 0 && waittime < 0) {
905 		register struct buf *bp;
906 		int iter, nbusy;
907 
908 		waittime = 0;
909 		(void) spl0();
910 		printf("syncing disks... ");
911 		/*
912 		 * Release vnodes held by texts before sync.
913 		 */
914 		if (panicstr == 0)
915 			vnode_pager_umount(NULL);
916 #ifdef notdef
917 #include "fd.h"
918 #if NFD > 0
919 		fdshutdown();
920 #endif
921 #endif
922 		sync(&proc0, (void *)NULL, (int *)NULL);
923 
924 		for (iter = 0; iter < 20; iter++) {
925 			nbusy = 0;
926 			for (bp = &buf[nbuf]; --bp >= buf; )
927 				if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
928 					nbusy++;
929 			if (nbusy == 0)
930 				break;
931 			printf("%d ", nbusy);
932 			DELAY(40000 * iter);
933 		}
934 		if (nbusy)
935 			printf("giving up\n");
936 		else
937 			printf("done\n");
938 		/*
939 		 * If we've been adjusting the clock, the todr
940 		 * will be out of synch; adjust it now.
941 		 */
942 		resettodr();
943 	}
944 	splhigh();			/* extreme priority */
945 	if (howto&RB_HALT) {
946 		printf("halted\n\n");
947 		asm("	stop	#0x2700");
948 	} else {
949 		if (howto & RB_DUMP)
950 			dumpsys();
951 		doboot();
952 		/*NOTREACHED*/
953 	}
954 	/*NOTREACHED*/
955 }
956 
957 int	dumpmag = 0x8fca0101;	/* magic number for savecore */
958 int	dumpsize = 0;		/* also for savecore */
959 long	dumplo = 0;
960 
961 dumpconf()
962 {
963 	int nblks;
964 
965 	dumpsize = physmem;
966 	if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
967 		nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
968 		if (dumpsize > btoc(dbtob(nblks - dumplo)))
969 			dumpsize = btoc(dbtob(nblks - dumplo));
970 		else if (dumplo == 0)
971 			dumplo = nblks - btodb(ctob(physmem));
972 	}
973 	/*
974 	 * Don't dump on the first CLBYTES (why CLBYTES?)
975 	 * in case the dump device includes a disk label.
976 	 */
977 	if (dumplo < btodb(CLBYTES))
978 		dumplo = btodb(CLBYTES);
979 }
980 
981 /*
982  * Doadump comes here after turning off memory management and
983  * getting on the dump stack, either when called above, or by
984  * the auto-restart code.
985  */
986 dumpsys()
987 {
988 
989 	msgbufmapped = 0;
990 	if (dumpdev == NODEV)
991 		return;
992 	/*
993 	 * For dumps during autoconfiguration,
994 	 * if dump device has already configured...
995 	 */
996 	if (dumpsize == 0)
997 		dumpconf();
998 	if (dumplo < 0)
999 		return;
1000 	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
1001 	printf("dump ");
1002 	switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
1003 
1004 	case ENXIO:
1005 		printf("device bad\n");
1006 		break;
1007 
1008 	case EFAULT:
1009 		printf("device not ready\n");
1010 		break;
1011 
1012 	case EINVAL:
1013 		printf("area improper\n");
1014 		break;
1015 
1016 	case EIO:
1017 		printf("i/o error\n");
1018 		break;
1019 
1020 	default:
1021 		printf("succeeded\n");
1022 		break;
1023 	}
1024 }
1025 
1026 initcpu()
1027 {
1028 	parityenable();
1029 }
1030 
1031 straytrap(pc, evec)
1032 	int pc;
1033 	u_short evec;
1034 {
1035 	printf("unexpected trap (vector offset %x) from %x\n",
1036 	       evec & 0xFFF, pc);
1037 }
1038 
1039 int	*nofault;
1040 
1041 badaddr(addr)
1042 	register caddr_t addr;
1043 {
1044 	register int i;
1045 	label_t	faultbuf;
1046 
1047 #ifdef lint
1048 	i = *addr; if (i) return(0);
1049 #endif
1050 	nofault = (int *) &faultbuf;
1051 	if (setjmp((label_t *)nofault)) {
1052 		nofault = (int *) 0;
1053 		return(1);
1054 	}
1055 	i = *(volatile short *)addr;
1056 	nofault = (int *) 0;
1057 	return(0);
1058 }
1059 
1060 badbaddr(addr)
1061 	register caddr_t addr;
1062 {
1063 	register int i;
1064 	label_t	faultbuf;
1065 
1066 #ifdef lint
1067 	i = *addr; if (i) return(0);
1068 #endif
1069 	nofault = (int *) &faultbuf;
1070 	if (setjmp((label_t *)nofault)) {
1071 		nofault = (int *) 0;
1072 		return(1);
1073 	}
1074 	i = *(volatile char *)addr;
1075 	nofault = (int *) 0;
1076 	return(0);
1077 }
1078 
1079 netintr()
1080 {
1081 #ifdef INET
1082 	if (netisr & (1 << NETISR_ARP)) {
1083 		netisr &= ~(1 << NETISR_ARP);
1084 		arpintr();
1085 	}
1086 	if (netisr & (1 << NETISR_IP)) {
1087 		netisr &= ~(1 << NETISR_IP);
1088 		ipintr();
1089 	}
1090 #endif
1091 #ifdef NS
1092 	if (netisr & (1 << NETISR_NS)) {
1093 		netisr &= ~(1 << NETISR_NS);
1094 		nsintr();
1095 	}
1096 #endif
1097 #ifdef ISO
1098 	if (netisr & (1 << NETISR_ISO)) {
1099 		netisr &= ~(1 << NETISR_ISO);
1100 		clnlintr();
1101 	}
1102 #endif
1103 }
1104 
1105 intrhand(sr)
1106 	int sr;
1107 {
1108 	register struct isr *isr;
1109 	register int found = 0;
1110 	register int ipl;
1111 	extern struct isr isrqueue[];
1112 
1113 	ipl = (sr >> 8) & 7;
1114 	switch (ipl) {
1115 
1116 	case 3:
1117 	case 4:
1118 	case 5:
1119 		ipl = ISRIPL(ipl);
1120 		isr = isrqueue[ipl].isr_forw;
1121 		for (; isr != &isrqueue[ipl]; isr = isr->isr_forw) {
1122 			if ((isr->isr_intr)(isr->isr_arg)) {
1123 				found++;
1124 				break;
1125 			}
1126 		}
1127 		if (found == 0)
1128 			printf("stray interrupt, sr 0x%x\n", sr);
1129 		break;
1130 
1131 	case 0:
1132 	case 1:
1133 	case 2:
1134 	case 6:
1135 	case 7:
1136 		printf("intrhand: unexpected sr 0x%x\n", sr);
1137 		break;
1138 	}
1139 }
1140 
1141 #if defined(DEBUG) && !defined(PANICBUTTON)
1142 #define PANICBUTTON
1143 #endif
1144 
1145 #ifdef PANICBUTTON
1146 int panicbutton = 1;	/* non-zero if panic buttons are enabled */
1147 int crashandburn = 0;
1148 int candbdelay = 50;	/* give em half a second */
1149 
1150 void
1151 candbtimer(arg)
1152 	void *arg;
1153 {
1154 
1155 	crashandburn = 0;
1156 }
1157 #endif
1158 
1159 /*
1160  * Level 7 interrupts can be caused by the keyboard or parity errors.
1161  */
1162 nmihand(frame)
1163 	struct frame frame;
1164 {
1165 	if (kbdnmi()) {
1166 #ifdef PANICBUTTON
1167 		static int innmihand = 0;
1168 
1169 		/*
1170 		 * Attempt to reduce the window of vulnerability for recursive
1171 		 * NMIs (e.g. someone holding down the keyboard reset button).
1172 		 */
1173 		if (innmihand == 0) {
1174 			innmihand = 1;
1175 			printf("Got a keyboard NMI\n");
1176 			innmihand = 0;
1177 		}
1178 		if (panicbutton) {
1179 			if (crashandburn) {
1180 				crashandburn = 0;
1181 				panic(panicstr ?
1182 				      "forced crash, nosync" : "forced crash");
1183 			}
1184 			crashandburn++;
1185 			timeout(candbtimer, (void *)0, candbdelay);
1186 		}
1187 #endif
1188 		return;
1189 	}
1190 	if (parityerror(&frame))
1191 		return;
1192 	/* panic?? */
1193 	printf("unexpected level 7 interrupt ignored\n");
1194 }
1195 
1196 /*
1197  * Parity error section.  Contains magic.
1198  */
1199 #define PARREG		((volatile short *)IIOV(0x5B0000))
1200 static int gotparmem = 0;
1201 #ifdef DEBUG
1202 int ignorekperr = 0;	/* ignore kernel parity errors */
1203 #endif
1204 
1205 /*
1206  * Enable parity detection
1207  */
1208 parityenable()
1209 {
1210 	label_t	faultbuf;
1211 
1212 	nofault = (int *) &faultbuf;
1213 	if (setjmp((label_t *)nofault)) {
1214 		nofault = (int *) 0;
1215 #ifdef DEBUG
1216 		printf("No parity memory\n");
1217 #endif
1218 		return;
1219 	}
1220 	*PARREG = 1;
1221 	nofault = (int *) 0;
1222 	gotparmem = 1;
1223 #ifdef DEBUG
1224 	printf("Parity detection enabled\n");
1225 #endif
1226 }
1227 
1228 /*
1229  * Determine if level 7 interrupt was caused by a parity error
1230  * and deal with it if it was.  Returns 1 if it was a parity error.
1231  */
1232 parityerror(fp)
1233 	struct frame *fp;
1234 {
1235 	if (!gotparmem)
1236 		return(0);
1237 	*PARREG = 0;
1238 	DELAY(10);
1239 	*PARREG = 1;
1240 	if (panicstr) {
1241 		printf("parity error after panic ignored\n");
1242 		return(1);
1243 	}
1244 	if (!findparerror())
1245 		printf("WARNING: transient parity error ignored\n");
1246 	else if (USERMODE(fp->f_sr)) {
1247 		printf("pid %d: parity error\n", curproc->p_pid);
1248 		uprintf("sorry, pid %d killed due to memory parity error\n",
1249 			curproc->p_pid);
1250 		psignal(curproc, SIGKILL);
1251 #ifdef DEBUG
1252 	} else if (ignorekperr) {
1253 		printf("WARNING: kernel parity error ignored\n");
1254 #endif
1255 	} else {
1256 		regdump(fp->f_regs, 128);
1257 		panic("kernel parity error");
1258 	}
1259 	return(1);
1260 }
1261 
1262 /*
1263  * Yuk!  There has got to be a better way to do this!
1264  * Searching all of memory with interrupts blocked can lead to disaster.
1265  */
1266 findparerror()
1267 {
1268 	static label_t parcatch;
1269 	static int looking = 0;
1270 	volatile struct pte opte;
1271 	volatile int pg, o, s;
1272 	register volatile int *ip;
1273 	register int i;
1274 	int found;
1275 
1276 #ifdef lint
1277 	ip = &found;
1278 	i = o = pg = 0; if (i) return(0);
1279 #endif
1280 	/*
1281 	 * If looking is true we are searching for a known parity error
1282 	 * and it has just occured.  All we do is return to the higher
1283 	 * level invocation.
1284 	 */
1285 	if (looking)
1286 		longjmp(&parcatch);
1287 	s = splhigh();
1288 	/*
1289 	 * If setjmp returns true, the parity error we were searching
1290 	 * for has just occured (longjmp above) at the current pg+o
1291 	 */
1292 	if (setjmp(&parcatch)) {
1293 		printf("Parity error at 0x%x\n", ctob(pg)|o);
1294 		found = 1;
1295 		goto done;
1296 	}
1297 	/*
1298 	 * If we get here, a parity error has occured for the first time
1299 	 * and we need to find it.  We turn off any external caches and
1300 	 * loop thru memory, testing every longword til a fault occurs and
1301 	 * we regain control at setjmp above.  Note that because of the
1302 	 * setjmp, pg and o need to be volatile or their values will be lost.
1303 	 */
1304 	looking = 1;
1305 	ecacheoff();
1306 	for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) {
1307 		pmap_enter(kernel_pmap, (vm_offset_t)vmmap, ctob(pg),
1308 		    VM_PROT_READ, TRUE);
1309 		for (o = 0; o < NBPG; o += sizeof(int))
1310 			i = *(int *)(&vmmap[o]);
1311 	}
1312 	/*
1313 	 * Getting here implies no fault was found.  Should never happen.
1314 	 */
1315 	printf("Couldn't locate parity error\n");
1316 	found = 0;
1317 done:
1318 	looking = 0;
1319 	pmap_remove(kernel_pmap, (vm_offset_t)vmmap,
1320 	    (vm_offset_t)&vmmap[NBPG]);
1321 	ecacheon();
1322 	splx(s);
1323 	return(found);
1324 }
1325 
1326 regdump(rp, sbytes)
1327   int *rp; /* must not be register */
1328   int sbytes;
1329 {
1330 	static int doingdump = 0;
1331 	register int i;
1332 	int s;
1333 	extern char *hexstr();
1334 
1335 	if (doingdump)
1336 		return;
1337 	s = splhigh();
1338 	doingdump = 1;
1339 	printf("pid = %d, pc = %s, ", curproc->p_pid, hexstr(rp[PC], 8));
1340 	printf("ps = %s, ", hexstr(rp[PS], 4));
1341 	printf("sfc = %s, ", hexstr(getsfc(), 4));
1342 	printf("dfc = %s\n", hexstr(getdfc(), 4));
1343 	printf("Registers:\n     ");
1344 	for (i = 0; i < 8; i++)
1345 		printf("        %d", i);
1346 	printf("\ndreg:");
1347 	for (i = 0; i < 8; i++)
1348 		printf(" %s", hexstr(rp[i], 8));
1349 	printf("\nareg:");
1350 	for (i = 0; i < 8; i++)
1351 		printf(" %s", hexstr(rp[i+8], 8));
1352 	if (sbytes > 0) {
1353 		if (rp[PS] & PSL_S) {
1354 			printf("\n\nKernel stack (%s):",
1355 			       hexstr((int)(((int *)&rp)-1), 8));
1356 			dumpmem(((int *)&rp)-1, sbytes, 0);
1357 		} else {
1358 			printf("\n\nUser stack (%s):", hexstr(rp[SP], 8));
1359 			dumpmem((int *)rp[SP], sbytes, 1);
1360 		}
1361 	}
1362 	doingdump = 0;
1363 	splx(s);
1364 }
1365 
1366 extern char kstack[];
1367 #define KSADDR	((int *)&(kstack[(UPAGES-1)*NBPG]))
1368 
1369 dumpmem(ptr, sz, ustack)
1370 	register int *ptr;
1371 	int sz;
1372 {
1373 	register int i, val;
1374 	extern char *hexstr();
1375 
1376 	for (i = 0; i < sz; i++) {
1377 		if ((i & 7) == 0)
1378 			printf("\n%s: ", hexstr((int)ptr, 6));
1379 		else
1380 			printf(" ");
1381 		if (ustack == 1) {
1382 			if ((val = fuword(ptr++)) == -1)
1383 				break;
1384 		} else {
1385 			if (ustack == 0 &&
1386 			    (ptr < KSADDR || ptr > KSADDR+(NBPG/4-1)))
1387 				break;
1388 			val = *ptr++;
1389 		}
1390 		printf("%s", hexstr(val, 8));
1391 	}
1392 	printf("\n");
1393 }
1394 
1395 char *
1396 hexstr(val, len)
1397 	register int val;
1398 {
1399 	static char nbuf[9];
1400 	register int x, i;
1401 
1402 	if (len > 8)
1403 		return("");
1404 	nbuf[len] = '\0';
1405 	for (i = len-1; i >= 0; --i) {
1406 		x = val & 0xF;
1407 		if (x > 9)
1408 			nbuf[i] = x - 10 + 'A';
1409 		else
1410 			nbuf[i] = x + '0';
1411 		val >>= 4;
1412 	}
1413 	return(nbuf);
1414 }
1415