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