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