xref: /original-bsd/sys/hp300/hp300/machdep.c (revision dd262573)
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.10 (Berkeley) 12/16/90
15  */
16 
17 #include "sys/param.h"
18 #include "sys/systm.h"
19 #include "sys/user.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 #ifdef SYSVSHM
33 #include "sys/shm.h"
34 #endif
35 #ifdef HPUXCOMPAT
36 #include "../hpux/hpux.h"
37 #endif
38 
39 #include "../include/cpu.h"
40 #include "../include/reg.h"
41 #include "../include/psl.h"
42 #include "isr.h"
43 #include "net/netisr.h"
44 
45 #define	MAXMEM	64*1024*CLSIZE	/* XXX - from cmap.h */
46 #include "vm/vm_param.h"
47 #include "vm/pmap.h"
48 #include "vm/vm_map.h"
49 #include "vm/vm_object.h"
50 #include "vm/vm_kern.h"
51 #include "vm/vm_page.h"
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	physmem = MAXMEM;	/* max supported memory, changes to actual */
71 /*
72  * safepri is a safe priority for sleep to set for a spin-wait
73  * during autoconfiguration or after a panic.
74  */
75 int   safepri = PSL_LOWIPL;
76 
77 extern	u_int lowram;
78 
79 /*
80  * Machine-dependent startup code
81  */
82 startup(firstaddr)
83 	int firstaddr;
84 {
85 	register unsigned i;
86 	register caddr_t v;
87 	int base, residual;
88 	extern long Usrptsize;
89 	extern struct map *useriomap;
90 #ifdef DEBUG
91 	extern int pmapdebug;
92 	int opmapdebug = pmapdebug;
93 #endif
94 	vm_offset_t minaddr, maxaddr;
95 	vm_size_t size;
96 
97 	/*
98 	 * Set cpuspeed immediately since cninit() called routines
99 	 * might use delay.
100 	 */
101 	switch (machineid) {
102 	case HP_320:
103 	case HP_330:
104 	case HP_340:
105 		cpuspeed = MHZ_16;
106 		break;
107 	case HP_350:
108 	case HP_360:
109 		cpuspeed = MHZ_25;
110 		break;
111 	case HP_370:
112 		cpuspeed = MHZ_33;
113 		break;
114 	case HP_375:
115 		cpuspeed = MHZ_50;
116 		break;
117 	}
118 #ifndef DEBUG
119 	/*
120          * Find what hardware is attached to this machine.
121          */
122 	find_devs();
123 	/*
124 	 * Initialize the console before we print anything out.
125 	 */
126 	cninit();
127 #endif
128 	/*
129 	 * Initialize error message buffer (at end of core).
130 	 */
131 #ifdef DEBUG
132 	pmapdebug = 0;
133 #endif
134 	/* avail_end was pre-decremented in pmap_bootstrap to compensate */
135 	for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
136 		pmap_enter(pmap_kernel(), msgbufp, avail_end + i * NBPG,
137 			   VM_PROT_ALL, TRUE);
138 	msgbufmapped = 1;
139 
140 	/*
141 	 * Good {morning,afternoon,evening,night}.
142 	 */
143 	printf(version);
144 	identifycpu();
145 	printf("real mem = %d\n", ctob(physmem));
146 
147 	/*
148 	 * Allocate space for system data structures.
149 	 * The first available real memory address is in "firstaddr".
150 	 * The first available kernel virtual address is in "v".
151 	 * As pages of kernel virtual memory are allocated, "v" is incremented.
152 	 * As pages of memory are allocated and cleared,
153 	 * "firstaddr" is incremented.
154 	 * An index into the kernel page table corresponding to the
155 	 * virtual memory address maintained in "v" is kept in "mapaddr".
156 	 */
157 	/*
158 	 * Make two passes.  The first pass calculates how much memory is
159 	 * needed and allocates it.  The second pass assigns virtual
160 	 * addresses to the various data structures.
161 	 */
162 	firstaddr = 0;
163 again:
164 	v = (caddr_t)firstaddr;
165 
166 #define	valloc(name, type, num) \
167 	    (name) = (type *)v; v = (caddr_t)((name)+(num))
168 #define	valloclim(name, type, num, lim) \
169 	    (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
170 	valloclim(file, struct file, nfile, fileNFILE);
171 	valloclim(proc, struct proc, nproc, procNPROC);
172 	valloc(cfree, struct cblock, nclist);
173 	valloc(callout, struct callout, ncallout);
174 	valloc(swapmap, struct map, nswapmap = nproc * 2);
175 #ifdef SYSVSHM
176 	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
177 #endif
178 
179 	/*
180 	 * Determine how many buffers to allocate.
181 	 * Since HPs tend to be long on memory and short on disk speed,
182 	 * we allocate more buffer space than the BSD standard of
183 	 * use 10% of memory for the first 2 Meg, 5% of remaining.
184 	 * We just allocate a flat 10%.  Insure a minimum of 16 buffers.
185 	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
186 	 */
187 	if (bufpages == 0)
188 		bufpages = physmem / 10 / CLSIZE;
189 	if (nbuf == 0) {
190 		nbuf = bufpages;
191 		if (nbuf < 16)
192 			nbuf = 16;
193 	}
194 	if (nswbuf == 0) {
195 		nswbuf = (nbuf / 2) &~ 1;	/* force even */
196 		if (nswbuf > 256)
197 			nswbuf = 256;		/* sanity */
198 	}
199 	valloc(swbuf, struct buf, nswbuf);
200 	valloc(buf, struct buf, nbuf);
201 	/*
202 	 * End of first pass, size has been calculated so allocate memory
203 	 */
204 	if (firstaddr == 0) {
205 		size = (vm_size_t)(v - firstaddr);
206 		firstaddr = (int)kmem_alloc(kernel_map, round_page(size));
207 		if (firstaddr == 0)
208 			panic("startup: no room for tables");
209 		goto again;
210 	}
211 	/*
212 	 * End of second pass, addresses have been assigned
213 	 */
214 	if ((vm_size_t)(v - firstaddr) != size)
215 		panic("startup: table size inconsistency");
216 	/*
217 	 * Now allocate buffers proper.  They are different than the above
218 	 * in that they usually occupy more virtual memory than physical.
219 	 */
220 	size = MAXBSIZE * nbuf;
221 	buffer_map = kmem_suballoc(kernel_map, (vm_offset_t)&buffers,
222 				   &maxaddr, size, FALSE);
223 	minaddr = (vm_offset_t)buffers;
224 	if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
225 			&minaddr, size, FALSE) != KERN_SUCCESS)
226 		panic("startup: cannot allocate buffers");
227 	base = bufpages / nbuf;
228 	residual = bufpages % nbuf;
229 	for (i = 0; i < nbuf; i++) {
230 		vm_size_t curbufsize;
231 		vm_offset_t curbuf;
232 
233 		/*
234 		 * First <residual> buffers get (base+1) physical pages
235 		 * allocated for them.  The rest get (base) physical pages.
236 		 *
237 		 * The rest of each buffer occupies virtual space,
238 		 * but has no physical memory allocated for it.
239 		 */
240 		curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
241 		curbufsize = CLBYTES * (i < residual ? base+1 : base);
242 		vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
243 		vm_map_simplify(buffer_map, curbuf);
244 	}
245 	/*
246 	 * Allocate a submap for exec arguments.  This map effectively
247 	 * limits the number of processes exec'ing at any time.
248 	 */
249 	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
250 				 16*NCARGS, TRUE);
251 	/*
252 	 * Allocate a submap for physio
253 	 */
254 	phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
255 				 VM_PHYS_SIZE, TRUE);
256 
257 	/*
258 	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
259 	 * we use the more space efficient malloc in place of kmem_alloc.
260 	 */
261 	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
262 				   M_MBUF, M_NOWAIT);
263 	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
264 	mb_map = kmem_suballoc(kernel_map, (vm_offset_t)&mbutl, &maxaddr,
265 			       VM_MBUF_SIZE, FALSE);
266 	/*
267 	 * Initialize callouts
268 	 */
269 	callfree = callout;
270 	for (i = 1; i < ncallout; i++)
271 		callout[i-1].c_next = &callout[i];
272 
273 #ifdef DEBUG
274 	pmapdebug = opmapdebug;
275 #endif
276 	printf("avail mem = %d\n", ptoa(vm_page_free_count));
277 	printf("using %d buffers containing %d bytes of memory\n",
278 		nbuf, bufpages * CLBYTES);
279 	/*
280 	 * Set up CPU-specific registers, cache, etc.
281 	 */
282 	initcpu();
283 
284 	/*
285 	 * Set up buffers, so they can be used to read disk labels.
286 	 */
287 	bhinit();
288 	binit();
289 
290 	/*
291 	 * Configure the system.
292 	 */
293 	configure();
294 }
295 
296 #ifdef PGINPROF
297 /*
298  * Return the difference (in microseconds)
299  * between the  current time and a previous
300  * time as represented by the arguments.
301  */
302 /*ARGSUSED*/
303 vmtime(otime, olbolt, oicr)
304 	register int otime, olbolt, oicr;
305 {
306 
307 	return (((time.tv_sec-otime)*100 + lbolt-olbolt)*10000);
308 }
309 #endif
310 
311 /*
312  * Clear registers on exec
313  */
314 setregs(entry, retval)
315 	u_long entry;
316 	int retval[2];
317 {
318 	u.u_ar0[PC] = entry & ~1;
319 #ifdef FPCOPROC
320 	/* restore a null state frame */
321 	u.u_pcb.pcb_fpregs.fpf_null = 0;
322 	m68881_restore(&u.u_pcb.pcb_fpregs);
323 #endif
324 #ifdef HPUXCOMPAT
325 	if (u.u_procp->p_flag & SHPUX) {
326 
327 		u.u_ar0[A0] = 0;	/* not 68010 (bit 31), no FPA (30) */
328 		retval[0] = 0;		/* no float card */
329 #ifdef FPCOPROC
330 		retval[1] = 1;		/* yes 68881 */
331 #else
332 		retval[1] = 0;		/* no 68881 */
333 #endif
334 	}
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 	 * XXX This doesn't have much to do with setting registers but
342 	 * I didn't want to muck up kern_exec.c with this code, so I
343 	 * stuck it here.
344 	 */
345 	if ((u.u_procp->p_pptr->p_flag & SHPUX) &&
346 	    (u.u_procp->p_flag & STRC)) {
347 		tweaksigcode(1);
348 		u.u_pcb.pcb_flags |= PCB_HPUXTRACE;
349 	} else if (u.u_pcb.pcb_flags & PCB_HPUXTRACE) {
350 		tweaksigcode(0);
351 		u.u_pcb.pcb_flags &= ~PCB_HPUXTRACE;
352 	}
353 #endif
354 }
355 
356 identifycpu()
357 {
358 	printf("HP9000/");
359 	switch (machineid) {
360 	case HP_320:
361 		printf("320 (16.67Mhz");
362 		break;
363 	case HP_330:
364 		printf("318/319/330 (16.67Mhz");
365 		break;
366 	case HP_340:
367 		printf("340 (16.67Mhz");
368 		break;
369 	case HP_350:
370 		printf("350 (25Mhz");
371 		break;
372 	case HP_360:
373 		printf("360 (25Mhz");
374 		break;
375 	case HP_370:
376 		printf("370 (33.33Mhz");
377 		break;
378 	case HP_375:
379 		printf("345/375 (50Mhz");
380 		break;
381 	default:
382 		printf("\nunknown machine type %d\n", machineid);
383 		panic("startup");
384 	}
385 	printf(" MC680%s CPU", mmutype == MMU_68030 ? "30" : "20");
386 	switch (mmutype) {
387 	case MMU_68030:
388 		printf("+MMU");
389 		break;
390 	case MMU_68851:
391 		printf(", MC68851 MMU");
392 		break;
393 	case MMU_HP:
394 		printf(", HP MMU");
395 		break;
396 	default:
397 		printf("\nunknown MMU type %d\n", mmutype);
398 		panic("startup");
399 	}
400 	if (mmutype == MMU_68030)
401 		printf(", %sMhz MC68882 FPU",
402 		       machineid == HP_340 ? "16.67" :
403 		       (machineid == HP_360 ? "25" :
404 			(machineid == HP_370 ? "33.33" : "50")));
405 	else
406 		printf(", %sMhz MC68881 FPU",
407 		       machineid == HP_350 ? "20" : "16.67");
408 	switch (ectype) {
409 	case EC_VIRT:
410 		printf(", %dK virtual-address cache",
411 		       machineid == HP_320 ? 16 : 32);
412 		break;
413 	case EC_PHYS:
414 		printf(", %dK physical-address cache",
415 		       machineid == HP_370 ? 64 : 32);
416 		break;
417 	}
418 	printf(")\n");
419 	/*
420 	 * Now that we have told the user what they have,
421 	 * let them know if that machine type isn't configured.
422 	 */
423 	switch (machineid) {
424 	case -1:		/* keep compilers happy */
425 #if !defined(HP320) && !defined(HP350)
426 	case HP_320:
427 	case HP_350:
428 #endif
429 #ifndef HP330
430 	case HP_330:
431 #endif
432 #if !defined(HP360) && !defined(HP370)
433 	case HP_340:
434 	case HP_360:
435 	case HP_370:
436 #endif
437 		panic("CPU type not configured");
438 	default:
439 		break;
440 	}
441 }
442 
443 #ifdef HPUXCOMPAT
444 tweaksigcode(ishpux)
445 {
446 	static short *sigtrap = NULL;
447 
448 	/* locate trap instruction in pcb_sigc */
449 	if (sigtrap == NULL) {
450 		register struct pcb *pcp = &u.u_pcb;
451 
452 		sigtrap = &pcp->pcb_sigc[sizeof(pcp->pcb_sigc)/sizeof(short)];
453 		while (--sigtrap >= pcp->pcb_sigc)
454 			if ((*sigtrap & 0xFFF0) == 0x4E40)
455 				break;
456 		if (sigtrap < pcp->pcb_sigc)
457 			panic("bogus sigcode\n");
458 	}
459 	*sigtrap = ishpux ? 0x4E42 : 0x4E41;
460 }
461 #endif
462 
463 #define SS_RTEFRAME	1
464 #define SS_FPSTATE	2
465 #define SS_USERREGS	4
466 
467 struct sigstate {
468 	int	ss_flags;		/* which of the following are valid */
469 	struct	frame ss_frame;		/* original exception frame */
470 	struct	fpframe ss_fpstate;	/* 68881/68882 state info */
471 };
472 
473 /*
474  * WARNING: code in locore.s assumes the layout shown for sf_signum
475  * thru sf_handler so... don't screw with them!
476  */
477 struct sigframe {
478 	int	sf_signum;		/* signo for handler */
479 	int	sf_code;		/* additional info for handler */
480 	struct	sigcontext *sf_scp;	/* context ptr for handler */
481 	sig_t	sf_handler;		/* handler addr for u_sigc */
482 	struct	sigstate sf_state;	/* state of the hardware */
483 	struct	sigcontext sf_sc;	/* actual context */
484 };
485 
486 #ifdef HPUXCOMPAT
487 struct	hpuxsigcontext {
488 	int	hsc_syscall;
489 	char	hsc_action;
490 	char	hsc_pad1;
491 	char	hsc_pad2;
492 	char	hsc_onstack;
493 	int	hsc_mask;
494 	int	hsc_sp;
495 	short	hsc_ps;
496 	int	hsc_pc;
497 /* the rest aren't part of the context but are included for our convenience */
498 	short	hsc_pad;
499 	u_int	hsc_magic;		/* XXX sigreturn: cookie */
500 	struct	sigcontext *hsc_realsc;	/* XXX sigreturn: ptr to BSD context */
501 };
502 
503 /*
504  * For an HP-UX process, a partial hpuxsigframe follows the normal sigframe.
505  * Tremendous waste of space, but some HP-UX applications (e.g. LCL) need it.
506  */
507 struct hpuxsigframe {
508 	int	hsf_signum;
509 	int	hsf_code;
510 	struct	sigcontext *hsf_scp;
511 	struct	hpuxsigcontext hsf_sc;
512 	int	hsf_regs[15];
513 };
514 #endif
515 
516 #ifdef DEBUG
517 int sigdebug = 0;
518 int sigpid = 0;
519 #define SDB_FOLLOW	0x01
520 #define SDB_KSTACK	0x02
521 #define SDB_FPSTATE	0x04
522 #endif
523 
524 /*
525  * Send an interrupt to process.
526  */
527 sendsig(catcher, sig, mask, code)
528 	sig_t catcher;
529 	int sig, mask;
530 	unsigned code;
531 {
532 	register struct proc *p = u.u_procp;
533 	register struct sigframe *fp, *kfp;
534 	register struct frame *frame;
535 	register short ft;
536 	int oonstack, fsize;
537 
538 	frame = (struct frame *)u.u_ar0;
539 	ft = frame->f_format;
540 	oonstack = u.u_onstack;
541 	/*
542 	 * Allocate and validate space for the signal handler
543 	 * context. Note that if the stack is in P0 space, the
544 	 * call to grow() is a nop, and the useracc() check
545 	 * will fail if the process has not already allocated
546 	 * the space with a `brk'.
547 	 */
548 #ifdef HPUXCOMPAT
549 	if (p->p_flag & SHPUX)
550 		fsize = sizeof(struct sigframe) + sizeof(struct hpuxsigframe);
551 	else
552 #endif
553 	fsize = sizeof(struct sigframe);
554 	if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) {
555 		fp = (struct sigframe *)(u.u_sigsp - fsize);
556 		u.u_onstack = 1;
557 	} else
558 		fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
559 	if ((unsigned)fp <= USRSTACK - ctob(u.u_ssize))
560 		(void)grow((unsigned)fp);
561 #ifdef DEBUG
562 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
563 		printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n",
564 		       p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
565 #endif
566 	if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) {
567 #ifdef DEBUG
568 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
569 			printf("sendsig(%d): useracc failed on sig %d\n",
570 			       p->p_pid, sig);
571 #endif
572 		/*
573 		 * Process has trashed its stack; give it an illegal
574 		 * instruction to halt it in its tracks.
575 		 */
576 		SIGACTION(p, SIGILL) = SIG_DFL;
577 		sig = sigmask(SIGILL);
578 		p->p_sigignore &= ~sig;
579 		p->p_sigcatch &= ~sig;
580 		p->p_sigmask &= ~sig;
581 		psignal(p, SIGILL);
582 		return;
583 	}
584 	kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
585 	/*
586 	 * Build the argument list for the signal handler.
587 	 */
588 	kfp->sf_signum = sig;
589 	kfp->sf_code = code;
590 	kfp->sf_scp = &fp->sf_sc;
591 	kfp->sf_handler = catcher;
592 	/*
593 	 * Save necessary hardware state.  Currently this includes:
594 	 *	- general registers
595 	 *	- original exception frame (if not a "normal" frame)
596 	 *	- FP coprocessor state
597 	 */
598 	kfp->sf_state.ss_flags = SS_USERREGS;
599 	bcopy((caddr_t)frame->f_regs,
600 	      (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
601 	if (ft >= FMT9) {
602 #ifdef DEBUG
603 		if (ft != FMT9 && ft != FMTA && ft != FMTB)
604 			panic("sendsig: bogus frame type");
605 #endif
606 		kfp->sf_state.ss_flags |= SS_RTEFRAME;
607 		kfp->sf_state.ss_frame.f_format = frame->f_format;
608 		kfp->sf_state.ss_frame.f_vector = frame->f_vector;
609 		bcopy((caddr_t)&frame->F_u,
610 		      (caddr_t)&kfp->sf_state.ss_frame.F_u,
611 		      (ft == FMT9) ? FMT9SIZE :
612 		      (ft == FMTA) ? FMTASIZE : FMTBSIZE);
613 		/*
614 		 * Gag!  Leave an indicator that we need to clean up the
615 		 * kernel stack.  We do this by setting the "pad word"
616 		 * above the hardware stack frame.  "bexit" in locore
617 		 * will then know that it must compress the kernel stack
618 		 * and create a normal four word stack frame.
619 		 */
620 		frame->f_stackadj = -1;
621 #ifdef DEBUG
622 		if (sigdebug & SDB_FOLLOW)
623 			printf("sendsig(%d): copy out %d of frame %d\n",
624 			       p->p_pid,
625 			       (ft == FMT9) ? FMT9SIZE :
626 			       (ft == FMTA) ? FMTASIZE : FMTBSIZE, ft);
627 #endif
628 	}
629 #ifdef FPCOPROC
630 	kfp->sf_state.ss_flags |= SS_FPSTATE;
631 	m68881_save(&kfp->sf_state.ss_fpstate);
632 #ifdef DEBUG
633 	if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
634 		printf("sendsig(%d): copy out FP state (%x) to %x\n",
635 		       p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
636 		       &kfp->sf_state.ss_fpstate);
637 #endif
638 #endif
639 	/*
640 	 * Build the signal context to be used by sigreturn.
641 	 */
642 	kfp->sf_sc.sc_onstack = oonstack;
643 	kfp->sf_sc.sc_mask = mask;
644 	kfp->sf_sc.sc_sp = frame->f_regs[SP];
645 	kfp->sf_sc.sc_fp = frame->f_regs[A6];
646 	kfp->sf_sc.sc_ap = (int)&fp->sf_state;
647 	kfp->sf_sc.sc_pc = frame->f_pc;
648 	kfp->sf_sc.sc_ps = frame->f_sr;
649 #ifdef HPUXCOMPAT
650 	/*
651 	 * Create an HP-UX style sigcontext structure and associated goo
652 	 */
653 	if (p->p_flag & SHPUX) {
654 		register struct hpuxsigframe *hkfp;
655 
656 		hkfp = (struct hpuxsigframe *)&kfp[1];
657 		hkfp->hsf_signum = bsdtohpuxsig(kfp->sf_signum);
658 		hkfp->hsf_code = kfp->sf_code;
659 		hkfp->hsf_scp = (struct sigcontext *)
660 			&((struct hpuxsigframe *)(&fp[1]))->hsf_sc;
661 		hkfp->hsf_sc.hsc_syscall = 0;		/* XXX */
662 		hkfp->hsf_sc.hsc_action = 0;		/* XXX */
663 		hkfp->hsf_sc.hsc_pad1 = hkfp->hsf_sc.hsc_pad2 = 0;
664 		hkfp->hsf_sc.hsc_onstack = kfp->sf_sc.sc_onstack;
665 		hkfp->hsf_sc.hsc_mask = kfp->sf_sc.sc_mask;
666 		hkfp->hsf_sc.hsc_sp = kfp->sf_sc.sc_sp;
667 		hkfp->hsf_sc.hsc_ps = kfp->sf_sc.sc_ps;
668 		hkfp->hsf_sc.hsc_pc = kfp->sf_sc.sc_pc;
669 		hkfp->hsf_sc.hsc_pad = 0;
670 		hkfp->hsf_sc.hsc_magic = 0xdeadbeef;
671 		hkfp->hsf_sc.hsc_realsc = kfp->sf_scp;
672 		bcopy((caddr_t)frame->f_regs, (caddr_t)hkfp->hsf_regs,
673 		      sizeof (hkfp->hsf_regs));
674 
675 		kfp->sf_signum = hkfp->hsf_signum;
676 		kfp->sf_scp = hkfp->hsf_scp;
677 	}
678 #endif
679 	(void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
680 	frame->f_regs[SP] = (int)fp;
681 #ifdef DEBUG
682 	if (sigdebug & SDB_FOLLOW)
683 		printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n",
684 		       p->p_pid, sig, kfp->sf_scp, fp,
685 		       kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
686 #endif
687 	/*
688 	 * Signal trampoline code is at base of user stack.
689 	 */
690 	frame->f_pc = USRSTACK - sizeof(u.u_pcb.pcb_sigc);
691 #ifdef DEBUG
692 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
693 		printf("sendsig(%d): sig %d returns\n",
694 		       p->p_pid, sig);
695 #endif
696 	free((caddr_t)kfp, M_TEMP);
697 }
698 
699 /*
700  * System call to cleanup state after a signal
701  * has been taken.  Reset signal mask and
702  * stack state from context left by sendsig (above).
703  * Return to previous pc and psl as specified by
704  * context left by sendsig. Check carefully to
705  * make sure that the user has not modified the
706  * psl to gain improper priviledges or to cause
707  * a machine fault.
708  */
709 /* ARGSUSED */
710 sigreturn(p, uap, retval)
711 	struct proc *p;
712 	struct args {
713 		struct sigcontext *sigcntxp;
714 	} *uap;
715 	int *retval;
716 {
717 	register struct sigcontext *scp;
718 	register struct frame *frame;
719 	register int rf;
720 	struct sigcontext tsigc;
721 	struct sigstate tstate;
722 	int flags;
723 
724 	scp = uap->sigcntxp;
725 #ifdef DEBUG
726 	if (sigdebug & SDB_FOLLOW)
727 		printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
728 #endif
729 	if ((int)scp & 1)
730 		return (EINVAL);
731 #ifdef HPUXCOMPAT
732 	/*
733 	 * Grab context as an HP-UX style context and determine if it
734 	 * was one that we contructed in sendsig.
735 	 */
736 	if (p->p_flag & SHPUX) {
737 		struct hpuxsigcontext *hscp = (struct hpuxsigcontext *)scp;
738 		struct hpuxsigcontext htsigc;
739 
740 		if (useracc((caddr_t)hscp, sizeof (*hscp), B_WRITE) == 0 ||
741 		    copyin((caddr_t)hscp, (caddr_t)&htsigc, sizeof htsigc))
742 			return (EINVAL);
743 		/*
744 		 * If not generated by sendsig or we cannot restore the
745 		 * BSD-style sigcontext, just restore what we can -- state
746 		 * will be lost, but them's the breaks.
747 		 */
748 		hscp = &htsigc;
749 		if (hscp->hsc_magic != 0xdeadbeef ||
750 		    (scp = hscp->hsc_realsc) == 0 ||
751 		    useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
752 		    copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) {
753 			u.u_onstack = hscp->hsc_onstack & 01;
754 			p->p_sigmask = hscp->hsc_mask &~ sigcantmask;
755 			frame = (struct frame *) u.u_ar0;
756 			frame->f_regs[SP] = hscp->hsc_sp;
757 			frame->f_pc = hscp->hsc_pc;
758 			frame->f_sr = hscp->hsc_ps &~ PSL_USERCLR;
759 			return (EJUSTRETURN);
760 		}
761 		/*
762 		 * Otherwise, overlay BSD context with possibly modified
763 		 * HP-UX values.
764 		 */
765 		tsigc.sc_onstack = hscp->hsc_onstack;
766 		tsigc.sc_mask = hscp->hsc_mask;
767 		tsigc.sc_sp = hscp->hsc_sp;
768 		tsigc.sc_ps = hscp->hsc_ps;
769 		tsigc.sc_pc = hscp->hsc_pc;
770 	} else
771 #endif
772 	/*
773 	 * Test and fetch the context structure.
774 	 * We grab it all at once for speed.
775 	 */
776 	if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
777 	    copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
778 		return (EINVAL);
779 	scp = &tsigc;
780 	if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
781 		return (EINVAL);
782 	/*
783 	 * Restore the user supplied information
784 	 */
785 	u.u_onstack = scp->sc_onstack & 01;
786 	p->p_sigmask = scp->sc_mask &~ sigcantmask;
787 	frame = (struct frame *) u.u_ar0;
788 	frame->f_regs[SP] = scp->sc_sp;
789 	frame->f_regs[A6] = scp->sc_fp;
790 	frame->f_pc = scp->sc_pc;
791 	frame->f_sr = scp->sc_ps;
792 	/*
793 	 * Grab pointer to hardware state information.
794 	 * If zero, the user is probably doing a longjmp.
795 	 */
796 	if ((rf = scp->sc_ap) == 0)
797 		return (EJUSTRETURN);
798 	/*
799 	 * See if there is anything to do before we go to the
800 	 * expense of copying in close to 1/2K of data
801 	 */
802 	flags = fuword((caddr_t)rf);
803 #ifdef DEBUG
804 	if (sigdebug & SDB_FOLLOW)
805 		printf("sigreturn(%d): sc_ap %x flags %x\n",
806 		       p->p_pid, rf, flags);
807 #endif
808 	if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
809 		return (EJUSTRETURN);
810 #ifdef DEBUG
811 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
812 		printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
813 		       p->p_pid, &flags, scp->sc_sp, uap->sigcntxp,
814 		       (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
815 #endif
816 	/*
817 	 * Restore most of the users registers except for A6 and SP
818 	 * which were handled above.
819 	 */
820 	if (flags & SS_USERREGS)
821 		bcopy((caddr_t)tstate.ss_frame.f_regs,
822 		      (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
823 	/*
824 	 * Restore long stack frames.  Note that we do not copy
825 	 * back the saved SR or PC, they were picked up above from
826 	 * the sigcontext structure.
827 	 */
828 	if (flags & SS_RTEFRAME) {
829 		register int sz;
830 
831 		/* grab frame type and validate */
832 		sz = tstate.ss_frame.f_format;
833 		if (sz == FMT9)
834 			sz = FMT9SIZE;
835 		else if (sz == FMTA)
836 			sz = FMTASIZE;
837 		else if (sz == FMTB) {
838 			sz = FMTBSIZE;
839 			/* no k-stack adjustment necessary */
840 			frame->f_stackadj = 0;
841 		} else
842 			return (EINVAL);
843 		frame->f_format = tstate.ss_frame.f_format;
844 		frame->f_vector = tstate.ss_frame.f_vector;
845 		bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
846 #ifdef DEBUG
847 		if (sigdebug & SDB_FOLLOW)
848 			printf("sigreturn(%d): copy in %d of frame type %d\n",
849 			       p->p_pid, sz, tstate.ss_frame.f_format);
850 #endif
851 	}
852 #ifdef FPCOPROC
853 	/*
854 	 * Finally we restore the original FP context
855 	 */
856 	if (flags & SS_FPSTATE)
857 		m68881_restore(&tstate.ss_fpstate);
858 #ifdef DEBUG
859 	if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
860 		printf("sigreturn(%d): copied in FP state (%x) at %x\n",
861 		       p->p_pid, *(u_int *)&tstate.ss_fpstate,
862 		       &tstate.ss_fpstate);
863 #endif
864 #endif
865 #ifdef DEBUG
866 	if ((sigdebug & SDB_FOLLOW) ||
867 	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
868 		printf("sigreturn(%d): returns\n", p->p_pid);
869 #endif
870 	return (EJUSTRETURN);
871 }
872 
873 int	waittime = -1;
874 
875 boot(howto)
876 	register int howto;
877 {
878 	/* take a snap shot before clobbering any registers */
879 	if (u.u_procp)
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 			vnode_pager_umount(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 	for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) {
1296 		pmap_enter(pmap_kernel(), vmmap, ctob(pg), VM_PROT_READ, TRUE);
1297 		for (o = 0; o < NBPG; o += sizeof(int))
1298 			i = *(int *)(&vmmap[o]);
1299 	}
1300 	/*
1301 	 * Getting here implies no fault was found.  Should never happen.
1302 	 */
1303 	printf("Couldn't locate parity error\n");
1304 	found = 0;
1305 done:
1306 	looking = 0;
1307 	pmap_remove(pmap_kernel(), vmmap, &vmmap[NBPG]);
1308 	ecacheon();
1309 	splx(s);
1310 	return(found);
1311 }
1312 
1313 regdump(rp, sbytes)
1314   int *rp; /* must not be register */
1315   int sbytes;
1316 {
1317 	static int doingdump = 0;
1318 	register int i;
1319 	int s;
1320 	extern char *hexstr();
1321 
1322 	if (doingdump)
1323 		return;
1324 	s = splhigh();
1325 	doingdump = 1;
1326 	printf("pid = %d, pc = %s, ", u.u_procp->p_pid, hexstr(rp[PC], 8));
1327 	printf("ps = %s, ", hexstr(rp[PS], 4));
1328 	printf("sfc = %s, ", hexstr(getsfc(), 4));
1329 	printf("dfc = %s\n", hexstr(getdfc(), 4));
1330 	printf("Registers:\n     ");
1331 	for (i = 0; i < 8; i++)
1332 		printf("        %d", i);
1333 	printf("\ndreg:");
1334 	for (i = 0; i < 8; i++)
1335 		printf(" %s", hexstr(rp[i], 8));
1336 	printf("\nareg:");
1337 	for (i = 0; i < 8; i++)
1338 		printf(" %s", hexstr(rp[i+8], 8));
1339 	if (sbytes > 0) {
1340 		if (rp[PS] & PSL_S) {
1341 			printf("\n\nKernel stack (%s):",
1342 			       hexstr((int)(((int *)&rp)-1), 8));
1343 			dumpmem(((int *)&rp)-1, sbytes, 0);
1344 		} else {
1345 			printf("\n\nUser stack (%s):", hexstr(rp[SP], 8));
1346 			dumpmem((int *)rp[SP], sbytes, 1);
1347 		}
1348 	}
1349 	doingdump = 0;
1350 	splx(s);
1351 }
1352 
1353 #define KSADDR	((int *)&(((char *)&u)[(UPAGES-1)*NBPG]))
1354 
1355 dumpmem(ptr, sz, ustack)
1356  register int *ptr;
1357  int sz;
1358 {
1359 	register int i, val;
1360 	extern char *hexstr();
1361 
1362 	for (i = 0; i < sz; i++) {
1363 		if ((i & 7) == 0)
1364 			printf("\n%s: ", hexstr((int)ptr, 6));
1365 		else
1366 			printf(" ");
1367 		if (ustack == 1) {
1368 			if ((val = fuword(ptr++)) == -1)
1369 				break;
1370 		} else {
1371 			if (ustack == 0 && (ptr < KSADDR || ptr > KSADDR+(NBPG/4-1)))
1372 				break;
1373 			val = *ptr++;
1374 		}
1375 		printf("%s", hexstr(val, 8));
1376 	}
1377 	printf("\n");
1378 }
1379 
1380 char *
1381 hexstr(val, len)
1382 	register int val;
1383 {
1384 	static char nbuf[9];
1385 	register int x, i;
1386 
1387 	if (len > 8)
1388 		return("");
1389 	nbuf[len] = '\0';
1390 	for (i = len-1; i >= 0; --i) {
1391 		x = val & 0xF;
1392 		if (x > 9)
1393 			nbuf[i] = x - 10 + 'A';
1394 		else
1395 			nbuf[i] = x + '0';
1396 		val >>= 4;
1397 	}
1398 	return(nbuf);
1399 }
1400