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