xref: /original-bsd/sys/luna68k/luna68k/machdep.c (revision 49a3a6ff)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1992 OMRON Corporation.
4  * Copyright (c) 1982, 1986, 1990, 1992 The Regents of the University of California.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * the Systems Programming Group of the University of Utah Computer
9  * Science Department.
10  *
11  * %sccs.include.redist.c%
12  *
13  * from: Utah $Hdr: machdep.c 1.63 91/04/24$
14  * from: hp300/hp300/machdep.c   7.36 (Berkeley) 2/10/93
15  *
16  *	@(#)machdep.c	7.8 (Berkeley) 03/10/93
17  */
18 
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/signalvar.h>
22 #include <sys/kernel.h>
23 #include <sys/map.h>
24 #include <sys/proc.h>
25 #include <sys/buf.h>
26 #include <sys/reboot.h>
27 #include <sys/conf.h>
28 #include <sys/file.h>
29 #include <sys/clist.h>
30 #include <sys/callout.h>
31 #include <sys/malloc.h>
32 #include <sys/mbuf.h>
33 #include <sys/msgbuf.h>
34 #include <sys/mount.h>
35 #include <sys/user.h>
36 #include <sys/exec.h>
37 #ifdef SYSVSHM
38 #include <sys/shm.h>
39 #endif
40 
41 #include <machine/cpu.h>
42 #include <machine/reg.h>
43 #include <machine/psl.h>
44 #include <luna68k/luna68k/pte.h>
45 #include <net/netisr.h>
46 
47 #define	MAXMEM	64*1024*CLSIZE	/* XXX - from cmap.h */
48 #include <vm/vm_kern.h>
49 
50 /* the following is used externally (sysctl_hw) */
51 char machine[] = "luna68k";		/* cpu "architecture" */
52 
53 vm_map_t buffer_map;
54 extern vm_offset_t avail_end;
55 
56 /*
57  * Declare these as initialized data so we can patch them.
58  */
59 int	nswbuf = 0;
60 #ifdef	NBUF
61 int	nbuf = NBUF;
62 #else
63 int	nbuf = 0;
64 #endif
65 #ifdef	BUFPAGES
66 int	bufpages = BUFPAGES;
67 #else
68 int	bufpages = 0;
69 #endif
70 int	msgbufmapped;		/* set when safe to use msgbuf */
71 int	maxmem;			/* max memory per process */
72 int	physmem = MAXMEM;	/* max supported memory, changes to actual */
73 /*
74  * safepri is a safe priority for sleep to set for a spin-wait
75  * during autoconfiguration or after a panic.
76  */
77 int	safepri = PSL_LOWIPL;
78 
79 extern	u_int lowram;
80 extern	short exframesize[];
81 
82 #ifdef FPCOPROC
83 int	fpptype = -1;
84 #endif
85 
86 /*
87  * Console initialization: called early on from main,
88  * before vm init or startup.  Do enough configuration
89  * to choose and initialize a console.
90  */
91 consinit()
92 {
93 
94 	/*
95 	 * Set cpuspeed immediately since cninit() called routines
96 	 * might use delay.
97 	 */
98 
99 	cpuspeed = MHZ_25;
100 
101 	/*
102          * Find what hardware is attached to this machine.
103          */
104 	find_devs();
105 
106 	/*
107 	 * Initialize the console before we print anything out.
108 	 */
109 	cninit();
110 }
111 
112 /*
113  * cpu_startup: allocate memory for variable-sized tables,
114  * initialize cpu, and do autoconfiguration.
115  */
116 cpu_startup()
117 {
118 	register unsigned i;
119 	register caddr_t v, firstaddr;
120 	int base, residual;
121 	vm_offset_t minaddr, maxaddr;
122 	vm_size_t size;
123 #ifdef DEBUG
124 	extern int pmapdebug;
125 	int opmapdebug = pmapdebug;
126 
127 	pmapdebug = 0;
128 #endif
129 	/*
130 	 * Initialize error message buffer (at end of core).
131 	 */
132 	for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
133 		pmap_enter(kernel_pmap, (vm_offset_t)msgbufp,
134 		    avail_end + i * NBPG, VM_PROT_ALL, TRUE);
135 	msgbufmapped = 1;
136 
137 	/*
138 	 * Good {morning,afternoon,evening,night}.
139 	 */
140 	printf(version);
141 	identifyfpu();
142 	printf("real mem = %d\n", ctob(physmem));
143 
144 	/*
145 	 * Allocate space for system data structures.
146 	 * The first available real memory address is in "firstaddr".
147 	 * The first available kernel virtual address is in "v".
148 	 * As pages of kernel virtual memory are allocated, "v" is incremented.
149 	 * As pages of memory are allocated and cleared,
150 	 * "firstaddr" is incremented.
151 	 * An index into the kernel page table corresponding to the
152 	 * virtual memory address maintained in "v" is kept in "mapaddr".
153 	 */
154 	/*
155 	 * Make two passes.  The first pass calculates how much memory is
156 	 * needed and allocates it.  The second pass assigns virtual
157 	 * addresses to the various data structures.
158 	 */
159 	firstaddr = 0;
160 again:
161 	v = (caddr_t)firstaddr;
162 
163 #define	valloc(name, type, num) \
164 	    (name) = (type *)v; v = (caddr_t)((name)+(num))
165 #define	valloclim(name, type, num, lim) \
166 	    (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
167 	valloc(cfree, struct cblock, nclist);
168 	valloc(callout, struct callout, ncallout);
169 	valloc(swapmap, struct map, nswapmap = maxproc * 2);
170 #ifdef SYSVSHM
171 	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
172 #endif
173 
174 	/*
175 	 * Determine how many buffers to allocate.
176 	 * Since HPs tend to be long on memory and short on disk speed,
177 	 * we allocate more buffer space than the BSD standard of
178 	 * use 10% of memory for the first 2 Meg, 5% of remaining.
179 	 * We just allocate a flat 10%.  Insure a minimum of 16 buffers.
180 	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
181 	 */
182 	if (bufpages == 0)
183 		bufpages = physmem / 10 / CLSIZE;
184 	if (nbuf == 0) {
185 		nbuf = bufpages;
186 		if (nbuf < 16)
187 			nbuf = 16;
188 	}
189 	if (nswbuf == 0) {
190 		nswbuf = (nbuf / 2) &~ 1;	/* force even */
191 		if (nswbuf > 256)
192 			nswbuf = 256;		/* sanity */
193 	}
194 	valloc(swbuf, struct buf, nswbuf);
195 	valloc(buf, struct buf, nbuf);
196 	/*
197 	 * End of first pass, size has been calculated so allocate memory
198 	 */
199 	if (firstaddr == 0) {
200 		size = (vm_size_t)(v - firstaddr);
201 		firstaddr = (caddr_t) kmem_alloc(kernel_map, round_page(size));
202 		if (firstaddr == 0)
203 			panic("startup: no room for tables");
204 		goto again;
205 	}
206 	/*
207 	 * End of second pass, addresses have been assigned
208 	 */
209 	if ((vm_size_t)(v - firstaddr) != size)
210 		panic("startup: table size inconsistency");
211 	/*
212 	 * Now allocate buffers proper.  They are different than the above
213 	 * in that they usually occupy more virtual memory than physical.
214 	 */
215 	size = MAXBSIZE * nbuf;
216 	buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
217 				   &maxaddr, size, FALSE);
218 	minaddr = (vm_offset_t)buffers;
219 	if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
220 			&minaddr, size, FALSE) != KERN_SUCCESS)
221 		panic("startup: cannot allocate buffers");
222 	base = bufpages / nbuf;
223 	residual = bufpages % nbuf;
224 	for (i = 0; i < nbuf; i++) {
225 		vm_size_t curbufsize;
226 		vm_offset_t curbuf;
227 
228 		/*
229 		 * First <residual> buffers get (base+1) physical pages
230 		 * allocated for them.  The rest get (base) physical pages.
231 		 *
232 		 * The rest of each buffer occupies virtual space,
233 		 * but has no physical memory allocated for it.
234 		 */
235 		curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
236 		curbufsize = CLBYTES * (i < residual ? base+1 : base);
237 		vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
238 		vm_map_simplify(buffer_map, curbuf);
239 	}
240 	/*
241 	 * Allocate a submap for exec arguments.  This map effectively
242 	 * limits the number of processes exec'ing at any time.
243 	 */
244 	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
245 				 16*NCARGS, TRUE);
246 	/*
247 	 * Allocate a submap for physio
248 	 */
249 	phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
250 				 VM_PHYS_SIZE, TRUE);
251 
252 	/*
253 	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
254 	 * we use the more space efficient malloc in place of kmem_alloc.
255 	 */
256 	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
257 				   M_MBUF, M_NOWAIT);
258 	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
259 	mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
260 			       VM_MBUF_SIZE, FALSE);
261 	/*
262 	 * Initialize callouts
263 	 */
264 	callfree = callout;
265 	for (i = 1; i < ncallout; i++)
266 		callout[i-1].c_next = &callout[i];
267 	callout[i-1].c_next = NULL;
268 
269 #ifdef DEBUG
270 	pmapdebug = opmapdebug;
271 #endif
272 	printf("avail mem = %d\n", ptoa(cnt.v_free_count));
273 	printf("using %d buffers containing %d bytes of memory\n",
274 		nbuf, bufpages * CLBYTES);
275 	/*
276 	 * Set up CPU-specific registers, cache, etc.
277 	 */
278 	initcpu();
279 
280 	/*
281 	 * Set up buffers, so they can be used to read disk labels.
282 	 */
283 	bufinit();
284 
285 	/*
286 	 * Configure the system.
287 	 */
288 	configure();
289 }
290 
291 /*
292  * Set registers on exec.
293  * XXX Should clear registers except sp, pc,
294  * but would break init; should be fixed soon.
295  */
296 setregs(p, entry, retval)
297 	register struct proc *p;
298 	u_long entry;
299 	int retval[2];
300 {
301 	struct frame *frame = (struct frame *)p->p_md.md_regs;
302 
303 	frame->f_pc = entry & ~1;
304 #ifdef FPCOPROC
305 	/* restore a null state frame */
306 	p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
307 	m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
308 #endif
309 }
310 
311 extern	char machine[];
312 char	cpu_model[120];
313 extern	char ostype[], osrelease[], version[];
314 
315 identifyfpu()
316 {
317 	if ( fpptype == -1 ) {
318 		printf("unknow FPU type \n");
319 		panic("startup");
320 	}
321 
322 	sprintf(cpu_model, "LUNA-I (20MHz MC68030 CPU+MMU, 20MHz MC6888%d FPU)", fpptype);
323 	printf("%s\n", cpu_model);
324 
325 /*
326 	printf("LUNA(20Mhz MC68030 CPU, 20Mhz MC6888%d FPU)\n",fpptype);
327  */
328 }
329 
330 #define SS_RTEFRAME	1
331 #define SS_FPSTATE	2
332 #define SS_USERREGS	4
333 
334 struct sigstate {
335 	int	ss_flags;		/* which of the following are valid */
336 	struct	frame ss_frame;		/* original exception frame */
337 	struct	fpframe ss_fpstate;	/* 68881/68882 state info */
338 };
339 
340 /*
341  * WARNING: code in locore.s assumes the layout shown for sf_signum
342  * thru sf_handler so... don't screw with them!
343  */
344 struct sigframe {
345 	int	sf_signum;		/* signo for handler */
346 	int	sf_code;		/* additional info for handler */
347 	struct	sigcontext *sf_scp;	/* context ptr for handler */
348 	sig_t	sf_handler;		/* handler addr for u_sigc */
349 	struct	sigstate sf_state;	/* state of the hardware */
350 	struct	sigcontext sf_sc;	/* actual context */
351 };
352 
353 #ifdef DEBUG
354 int sigdebug = 0;
355 int sigpid = 0;
356 #define SDB_FOLLOW	0x01
357 #define SDB_KSTACK	0x02
358 #define SDB_FPSTATE	0x04
359 #endif
360 
361 /*
362  * Send an interrupt to process.
363  */
364 void
365 sendsig(catcher, sig, mask, code)
366 	sig_t catcher;
367 	int sig, mask;
368 	unsigned code;
369 {
370 	register struct proc *p = curproc;
371 	register struct sigframe *fp, *kfp;
372 	register struct frame *frame;
373 	register struct sigacts *psp = p->p_sigacts;
374 	register short ft;
375 	int oonstack, fsize;
376 	extern char sigcode[], esigcode[];
377 
378 	frame = (struct frame *)p->p_md.md_regs;
379 	ft = frame->f_format;
380 	oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
381 	/*
382 	 * Allocate and validate space for the signal handler
383 	 * context. Note that if the stack is in P0 space, the
384 	 * call to grow() is a nop, and the useracc() check
385 	 * will fail if the process has not already allocated
386 	 * the space with a `brk'.
387 	 */
388 	fsize = sizeof(struct sigframe);
389 	if ((psp->ps_flags & SAS_ALTSTACK) &&
390 	    (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
391 	    (psp->ps_sigonstack & sigmask(sig))) {
392 		fp = (struct sigframe *)(psp->ps_sigstk.ss_base +
393 					 psp->ps_sigstk.ss_size - fsize);
394 		psp->ps_sigstk.ss_flags |= SA_ONSTACK;
395 	} else
396 		fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
397 	if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
398 		(void)grow(p, (unsigned)fp);
399 #ifdef DEBUG
400 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
401 		printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n",
402 		       p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
403 #endif
404 	if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) {
405 #ifdef DEBUG
406 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
407 			printf("sendsig(%d): useracc failed on sig %d\n",
408 			       p->p_pid, sig);
409 #endif
410 		/*
411 		 * Process has trashed its stack; give it an illegal
412 		 * instruction to halt it in its tracks.
413 		 */
414 		SIGACTION(p, SIGILL) = SIG_DFL;
415 		sig = sigmask(SIGILL);
416 		p->p_sigignore &= ~sig;
417 		p->p_sigcatch &= ~sig;
418 		p->p_sigmask &= ~sig;
419 		psignal(p, SIGILL);
420 		return;
421 	}
422 	kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
423 	/*
424 	 * Build the argument list for the signal handler.
425 	 */
426 	kfp->sf_signum = sig;
427 	kfp->sf_code = code;
428 	kfp->sf_scp = &fp->sf_sc;
429 	kfp->sf_handler = catcher;
430 	/*
431 	 * Save necessary hardware state.  Currently this includes:
432 	 *	- general registers
433 	 *	- original exception frame (if not a "normal" frame)
434 	 *	- FP coprocessor state
435 	 */
436 	kfp->sf_state.ss_flags = SS_USERREGS;
437 	bcopy((caddr_t)frame->f_regs,
438 	      (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
439 	if (ft >= FMT7) {
440 #ifdef DEBUG
441 		if (ft != FMT9 && ft != FMTA && ft != FMTB)
442 			panic("sendsig: bogus frame type");
443 #endif
444 		kfp->sf_state.ss_flags |= SS_RTEFRAME;
445 		kfp->sf_state.ss_frame.f_format = frame->f_format;
446 		kfp->sf_state.ss_frame.f_vector = frame->f_vector;
447 		bcopy((caddr_t)&frame->F_u,
448 		      (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]);
449 		/*
450 		 * Leave an indicator that we need to clean up the kernel
451 		 * stack.  We do this by setting the "pad word" above the
452 		 * hardware stack frame to the amount the stack must be
453 		 * adjusted by.
454 		 *
455 		 * N.B. we increment rather than just set f_stackadj in
456 		 * case we are called from syscall when processing a
457 		 * sigreturn.  In that case, f_stackadj may be non-zero.
458 		 */
459 		frame->f_stackadj += exframesize[ft];
460 		frame->f_format = frame->f_vector = 0;
461 #ifdef DEBUG
462 		if (sigdebug & SDB_FOLLOW)
463 			printf("sendsig(%d): copy out %d of frame %d\n",
464 			       p->p_pid, exframesize[ft], ft);
465 #endif
466 	}
467 #ifdef FPCOPROC
468 	kfp->sf_state.ss_flags |= SS_FPSTATE;
469 	m68881_save(&kfp->sf_state.ss_fpstate);
470 #ifdef DEBUG
471 	if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
472 		printf("sendsig(%d): copy out FP state (%x) to %x\n",
473 		       p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
474 		       &kfp->sf_state.ss_fpstate);
475 #endif
476 #endif
477 	/*
478 	 * Build the signal context to be used by sigreturn.
479 	 */
480 	kfp->sf_sc.sc_onstack = oonstack;
481 	kfp->sf_sc.sc_mask = mask;
482 	kfp->sf_sc.sc_sp = frame->f_regs[SP];
483 	kfp->sf_sc.sc_fp = frame->f_regs[A6];
484 	kfp->sf_sc.sc_ap = (int)&fp->sf_state;
485 	kfp->sf_sc.sc_pc = frame->f_pc;
486 	kfp->sf_sc.sc_ps = frame->f_sr;
487 	(void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
488 	frame->f_regs[SP] = (int)fp;
489 #ifdef DEBUG
490 	if (sigdebug & SDB_FOLLOW)
491 		printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n",
492 		       p->p_pid, sig, kfp->sf_scp, fp,
493 		       kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
494 #endif
495 	/*
496 	 * Signal trampoline code is at base of user stack.
497 	 */
498 	frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode);
499 #ifdef DEBUG
500 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
501 		printf("sendsig(%d): sig %d returns\n",
502 		       p->p_pid, sig);
503 #endif
504 	free((caddr_t)kfp, M_TEMP);
505 }
506 
507 /*
508  * System call to cleanup state after a signal
509  * has been taken.  Reset signal mask and
510  * stack state from context left by sendsig (above).
511  * Return to previous pc and psl as specified by
512  * context left by sendsig. Check carefully to
513  * make sure that the user has not modified the
514  * psl to gain improper priviledges or to cause
515  * a machine fault.
516  */
517 struct sigreturn_args {
518 	struct sigcontext *sigcntxp;
519 };
520 /* ARGSUSED */
521 sigreturn(p, uap, retval)
522 	struct proc *p;
523 	struct sigreturn_args *uap;
524 	int *retval;
525 {
526 	register struct sigcontext *scp;
527 	register struct frame *frame;
528 	register int rf;
529 	struct sigcontext tsigc;
530 	struct sigstate tstate;
531 	int flags;
532 
533 	scp = uap->sigcntxp;
534 #ifdef DEBUG
535 	if (sigdebug & SDB_FOLLOW)
536 		printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
537 #endif
538 	if ((int)scp & 1)
539 		return (EINVAL);
540 	/*
541 	 * Test and fetch the context structure.
542 	 * We grab it all at once for speed.
543 	 */
544 	if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
545 	    copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
546 		return (EINVAL);
547 	scp = &tsigc;
548 	if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
549 		return (EINVAL);
550 	/*
551 	 * Restore the user supplied information
552 	 */
553 	if (scp->sc_onstack & 01)
554 		p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
555 	else
556 		p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
557 	p->p_sigmask = scp->sc_mask &~ sigcantmask;
558 	frame = (struct frame *) p->p_md.md_regs;
559 	frame->f_regs[SP] = scp->sc_sp;
560 	frame->f_regs[A6] = scp->sc_fp;
561 	frame->f_pc = scp->sc_pc;
562 	frame->f_sr = scp->sc_ps;
563 	/*
564 	 * Grab pointer to hardware state information.
565 	 * If zero, the user is probably doing a longjmp.
566 	 */
567 	if ((rf = scp->sc_ap) == 0)
568 		return (EJUSTRETURN);
569 	/*
570 	 * See if there is anything to do before we go to the
571 	 * expense of copying in close to 1/2K of data
572 	 */
573 	flags = fuword((caddr_t)rf);
574 #ifdef DEBUG
575 	if (sigdebug & SDB_FOLLOW)
576 		printf("sigreturn(%d): sc_ap %x flags %x\n",
577 		       p->p_pid, rf, flags);
578 #endif
579 	/*
580 	 * fuword failed (bogus sc_ap value).
581 	 */
582 	if (flags == -1)
583 		return (EINVAL);
584 	if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
585 		return (EJUSTRETURN);
586 #ifdef DEBUG
587 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
588 		printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
589 		       p->p_pid, &flags, scp->sc_sp, uap->sigcntxp,
590 		       (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
591 #endif
592 	/*
593 	 * Restore most of the users registers except for A6 and SP
594 	 * which were handled above.
595 	 */
596 	if (flags & SS_USERREGS)
597 		bcopy((caddr_t)tstate.ss_frame.f_regs,
598 		      (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
599 	/*
600 	 * Restore long stack frames.  Note that we do not copy
601 	 * back the saved SR or PC, they were picked up above from
602 	 * the sigcontext structure.
603 	 */
604 	if (flags & SS_RTEFRAME) {
605 		register int sz;
606 
607 		/* grab frame type and validate */
608 		sz = tstate.ss_frame.f_format;
609 		if (sz > 15 || (sz = exframesize[sz]) < 0)
610 			return (EINVAL);
611 		frame->f_stackadj -= sz;
612 		frame->f_format = tstate.ss_frame.f_format;
613 		frame->f_vector = tstate.ss_frame.f_vector;
614 		bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
615 #ifdef DEBUG
616 		if (sigdebug & SDB_FOLLOW)
617 			printf("sigreturn(%d): copy in %d of frame type %d\n",
618 			       p->p_pid, sz, tstate.ss_frame.f_format);
619 #endif
620 	}
621 #ifdef FPCOPROC
622 	/*
623 	 * Finally we restore the original FP context
624 	 */
625 	if (flags & SS_FPSTATE)
626 		m68881_restore(&tstate.ss_fpstate);
627 #ifdef DEBUG
628 	if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
629 		printf("sigreturn(%d): copied in FP state (%x) at %x\n",
630 		       p->p_pid, *(u_int *)&tstate.ss_fpstate,
631 		       &tstate.ss_fpstate);
632 #endif
633 #endif
634 #ifdef DEBUG
635 	if ((sigdebug & SDB_FOLLOW) ||
636 	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
637 		printf("sigreturn(%d): returns\n", p->p_pid);
638 #endif
639 	return (EJUSTRETURN);
640 }
641 
642 int	waittime = -1;
643 
644 boot(howto)
645 	register int howto;
646 {
647 	/* take a snap shot before clobbering any registers */
648 	if (curproc)
649 		savectx(curproc->p_addr, 0);
650 
651 	boothowto = howto;
652 	if ((howto&RB_NOSYNC) == 0 && waittime < 0) {
653 		register struct buf *bp;
654 		int iter, nbusy;
655 
656 		waittime = 0;
657 		(void) spl0();
658 		printf("syncing disks... ");
659 		/*
660 		 * Release vnodes held by texts before sync.
661 		 */
662 		if (panicstr == 0)
663 			vnode_pager_umount(NULL);
664 #ifdef notdef
665 #include "fd.h"
666 #if NFD > 0
667 		fdshutdown();
668 #endif
669 #endif
670 		sync(&proc0, (void *)NULL, (int *)NULL);
671 
672 		for (iter = 0; iter < 20; iter++) {
673 			nbusy = 0;
674 			for (bp = &buf[nbuf]; --bp >= buf; )
675 				if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
676 					nbusy++;
677 			if (nbusy == 0)
678 				break;
679 			printf("%d ", nbusy);
680 			DELAY(40000 * iter);
681 		}
682 		if (nbusy)
683 			printf("giving up\n");
684 		else
685 			printf("done\n");
686 
687 		/*
688 		 * If we've been adjusting the clock, the todr
689 		 * will be out of synch; adjust it now.
690 		 */
691 		resettodr();
692 	}
693 	splhigh();			/* extreme priority */
694 	if (howto&RB_HALT) {
695 		printf("halted\n\n");
696 		asm("	stop	#0x2700");
697 	} else {
698 		printf("\r\n\n");
699 		if (howto & RB_DUMP)
700 			dumpsys();
701 		doboot();
702 		/*NOTREACHED*/
703 	}
704 	/*NOTREACHED*/
705 }
706 
707 int	dumpmag = 0x8fca0101;	/* magic number for savecore */
708 int	dumpsize = 0;		/* also for savecore */
709 long	dumplo = 0;
710 
711 dumpconf()
712 {
713 	int nblks;
714 
715 	dumpsize = physmem;
716 	if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
717 		nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
718 		if (dumpsize > btoc(dbtob(nblks - dumplo)))
719 			dumpsize = btoc(dbtob(nblks - dumplo));
720 		else if (dumplo == 0)
721 			dumplo = nblks - btodb(ctob(physmem));
722 	}
723 	/*
724 	 * Don't dump on the first CLBYTES (why CLBYTES?)
725 	 * in case the dump device includes a disk label.
726 	 */
727 	if (dumplo < btodb(CLBYTES))
728 		dumplo = btodb(CLBYTES);
729 }
730 
731 /*
732  * Doadump comes here after turning off memory management and
733  * getting on the dump stack, either when called above, or by
734  * the auto-restart code.
735  */
736 dumpsys()
737 {
738 
739 	msgbufmapped = 0;
740 	if (dumpdev == NODEV)
741 		return;
742 	/*
743 	 * For dumps during autoconfiguration,
744 	 * if dump device has already configured...
745 	 */
746 	if (dumpsize == 0)
747 		dumpconf();
748 	if (dumplo < 0)
749 		return;
750 	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
751 	printf("dump ");
752 	switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
753 
754 	case ENXIO:
755 		printf("device bad\n");
756 		break;
757 
758 	case EFAULT:
759 		printf("device not ready\n");
760 		break;
761 
762 	case EINVAL:
763 		printf("area improper\n");
764 		break;
765 
766 	case EIO:
767 		printf("i/o error\n");
768 		break;
769 
770 	default:
771 		printf("succeeded\n");
772 		break;
773 	}
774 }
775 
776 initcpu()
777 {
778 	parityenable();
779 }
780 
781 straytrap(pc, evec)
782 	int pc;
783 	u_short evec;
784 {
785 	printf("unexpected trap (vector offset %x) from %x\n",
786 	       evec & 0xFFF, pc);
787 }
788 
789 int	*nofault;
790 
791 badaddr(addr)
792 	register caddr_t addr;
793 {
794 	register int i;
795 	label_t	faultbuf;
796 
797 #ifdef lint
798 	i = *addr; if (i) return(0);
799 #endif
800 	nofault = (int *) &faultbuf;
801 	if (setjmp((label_t *)nofault)) {
802 		nofault = (int *) 0;
803 		return(1);
804 	}
805 	i = *(volatile short *)addr;
806 	nofault = (int *) 0;
807 	return(0);
808 }
809 
810 badbaddr(addr)
811 	register caddr_t addr;
812 {
813 	register int i;
814 	label_t	faultbuf;
815 
816 #ifdef lint
817 	i = *addr; if (i) return(0);
818 #endif
819 	nofault = (int *) &faultbuf;
820 	if (setjmp((label_t *)nofault)) {
821 		nofault = (int *) 0;
822 		return(1);
823 	}
824 	i = *(volatile char *)addr;
825 	nofault = (int *) 0;
826 	return(0);
827 }
828 
829 netintr()
830 {
831 #ifdef INET
832 	if (netisr & (1 << NETISR_ARP)) {
833 		netisr &= ~(1 << NETISR_ARP);
834 		arpintr();
835 	}
836 	if (netisr & (1 << NETISR_IP)) {
837 		netisr &= ~(1 << NETISR_IP);
838 		ipintr();
839 	}
840 #endif
841 #ifdef NS
842 	if (netisr & (1 << NETISR_NS)) {
843 		netisr &= ~(1 << NETISR_NS);
844 		nsintr();
845 	}
846 #endif
847 #ifdef ISO
848 	if (netisr & (1 << NETISR_ISO)) {
849 		netisr &= ~(1 << NETISR_ISO);
850 		clnlintr();
851 	}
852 #endif
853 #ifdef CCITT
854 	if (netisr & (1 << NETISR_CCITT)) {
855 		netisr &= ~(1 << NETISR_CCITT);
856 		ccittintr();
857 	}
858 #endif
859 }
860 
861 #ifdef	notfdef
862 intrhand(sr)
863 	int sr;
864 {
865 	register struct isr *isr;
866 	register int found = 0;
867 	register int ipl;
868 	extern struct isr isrqueue[];
869 
870 	ipl = (sr >> 8) & 7;
871 	switch (ipl) {
872 
873 	case 3:
874 	case 4:
875 	case 5:
876 		ipl = ISRIPL(ipl);
877 		isr = isrqueue[ipl].isr_forw;
878 		for (; isr != &isrqueue[ipl]; isr = isr->isr_forw) {
879 			if ((isr->isr_intr)(isr->isr_arg)) {
880 				found++;
881 				break;
882 			}
883 		}
884 		if (found == 0)
885 			printf("stray interrupt, sr 0x%x\n", sr);
886 		break;
887 
888 	case 0:
889 	case 1:
890 	case 2:
891 	case 6:
892 	case 7:
893 		printf("intrhand: unexpected sr 0x%x\n", sr);
894 		break;
895 	}
896 }
897 #endif
898 
899 #if defined(DEBUG) && !defined(PANICBUTTON)
900 #define PANICBUTTON
901 #endif
902 
903 #ifdef PANICBUTTON
904 int panicbutton = 1;	/* non-zero if panic buttons are enabled */
905 int crashandburn = 0;
906 int candbdelay = 50;	/* give em half a second */
907 
908 void
909 candbtimer(arg)
910 	void *arg;
911 {
912 
913 	crashandburn = 0;
914 }
915 #endif
916 
917 /*
918  * Level 7 interrupts can be caused by the keyboard or parity errors.
919  */
920 nmihand(frame)
921 	struct frame frame;
922 {
923 #ifdef PANICBUTTON
924        	static int innmihand = 0;
925 
926        	/*
927        	 * Attempt to reduce the window of vulnerability for recursive
928        	 * NMIs (e.g. someone holding down the keyboard reset button).
929        	 */
930        	if (innmihand == 0) {
931        		innmihand = 1;
932        		printf("Got a keyboard NMI\n");
933        		innmihand = 0;
934        	}
935        	if (panicbutton) {
936        		if (crashandburn) {
937        			crashandburn = 0;
938        			panic(panicstr ?
939        			      "forced crash, nosync" : "forced crash");
940        		}
941        		crashandburn++;
942        		timeout(candbtimer, (void *)0, candbdelay);
943        	}
944 #endif
945        	return;
946 }
947 
948 regdump(fp, sbytes)
949 	struct frame *fp; /* must not be register */
950 	int sbytes;
951 {
952 	static int doingdump = 0;
953 	register int i;
954 	int s;
955 	extern char *hexstr();
956 
957 	if (doingdump)
958 		return;
959 	s = splhigh();
960 	doingdump = 1;
961 	printf("pid = %d, pc = %s, ",
962 	       curproc ? curproc->p_pid : -1, hexstr(fp->f_pc, 8));
963 	printf("ps = %s, ", hexstr(fp->f_sr, 4));
964 	printf("sfc = %s, ", hexstr(getsfc(), 4));
965 	printf("dfc = %s\n", hexstr(getdfc(), 4));
966 	printf("Registers:\n     ");
967 	for (i = 0; i < 8; i++)
968 		printf("        %d", i);
969 	printf("\ndreg:");
970 	for (i = 0; i < 8; i++)
971 		printf(" %s", hexstr(fp->f_regs[i], 8));
972 	printf("\nareg:");
973 	for (i = 0; i < 8; i++)
974 		printf(" %s", hexstr(fp->f_regs[i+8], 8));
975 	if (sbytes > 0) {
976 		if (fp->f_sr & PSL_S) {
977 			printf("\n\nKernel stack (%s):",
978 			       hexstr((int)(((int *)&fp)-1), 8));
979 			dumpmem(((int *)&fp)-1, sbytes, 0);
980 		} else {
981 			printf("\n\nUser stack (%s):", hexstr(fp->f_regs[SP], 8));
982 			dumpmem((int *)fp->f_regs[SP], sbytes, 1);
983 		}
984 	}
985 	doingdump = 0;
986 	splx(s);
987 }
988 
989 extern char kstack[];
990 #define KSADDR	((int *)&(kstack[(UPAGES-1)*NBPG]))
991 
992 dumpmem(ptr, sz, ustack)
993 	register int *ptr;
994 	int sz;
995 {
996 	register int i, val;
997 	extern char *hexstr();
998 
999 	for (i = 0; i < sz; i++) {
1000 		if ((i & 7) == 0)
1001 			printf("\n%s: ", hexstr((int)ptr, 6));
1002 		else
1003 			printf(" ");
1004 		if (ustack == 1) {
1005 			if ((val = fuword(ptr++)) == -1)
1006 				break;
1007 		} else {
1008 			if (ustack == 0 &&
1009 			    (ptr < KSADDR || ptr > KSADDR+(NBPG/4-1)))
1010 				break;
1011 			val = *ptr++;
1012 		}
1013 		printf("%s", hexstr(val, 8));
1014 	}
1015 	printf("\n");
1016 }
1017 
1018 char *
1019 hexstr(val, len)
1020 	register int val;
1021 {
1022 	static char nbuf[9];
1023 	register int x, i;
1024 
1025 	if (len > 8)
1026 		return("");
1027 	nbuf[len] = '\0';
1028 	for (i = len-1; i >= 0; --i) {
1029 		x = val & 0xF;
1030 		if (x > 9)
1031 			nbuf[i] = x - 10 + 'A';
1032 		else
1033 			nbuf[i] = x + '0';
1034 		val >>= 4;
1035 	}
1036 	return(nbuf);
1037 }
1038 
1039 #ifdef DEBUG
1040 char oflowmsg[] = "k-stack overflow";
1041 char uflowmsg[] = "k-stack underflow";
1042 
1043 badkstack(oflow, fr)
1044 	int oflow;
1045 	struct frame fr;
1046 {
1047 	extern char kstackatbase[];
1048 
1049 	printf("%s: sp should be %x\n",
1050 	       oflow ? oflowmsg : uflowmsg,
1051 	       kstackatbase - (exframesize[fr.f_format] + 8));
1052 	regdump(&fr, 0);
1053 	panic(oflow ? oflowmsg : uflowmsg);
1054 }
1055 #endif
1056 
1057 /* for LUNA */
1058 
1059 /*
1060  * Enable parity detection
1061  */
1062 #define PARREG		((volatile short *)0x49000003)
1063 #define	PARITY_ENABLE	0xC
1064 parityenable()
1065 {
1066 	*PARREG = PARITY_ENABLE;
1067 }
1068 
1069 #ifdef FPCOPROC
1070 #define EXT_FPP_ADDR		0x6F000000	/* External 68882 board  */
1071 #define INT_FPP_ADDR		0x6B000000	/* Internal 68881 chip   */
1072 
1073 #define FPP_ON			0x80		/* selected fpp on	 */
1074 #define FPP_OFF			0x00		/* selected fpp off    	 */
1075 
1076 #define	SET_INT_FPP	(*(char *)INT_FPP_ADDR = FPP_ON);(*(char *)EXT_FPP_ADDR = FPP_OFF)
1077 #define	SET_EXT_FPP	(*(char *)INT_FPP_ADDR = FPP_OFF);(*(char *)EXT_FPP_ADDR = FPP_ON)
1078 
1079 #define	FPP68881	1
1080 #define	FPP68882	2
1081 
1082 unsigned char fpp_svarea[212];
1083 
1084 #ifndef	OLD_LUNA
1085 /*
1086  * Check FPP type 68881/68882.
1087  */
1088 
1089 void checkfpp()
1090 {
1091     SET_INT_FPP;	/* internal = on, external = off */
1092     if( is_68882() )
1093       fpptype = FPP68882;
1094     else
1095       fpptype = FPP68881;
1096     return;
1097 }
1098 #else
1099 
1100 /*
1101  * Check in/ex-ternal fpp, and determine which we use.
1102  * Also set fpp type(MC68881/68882).
1103  */
1104 
1105 void checkfpp()
1106 {
1107 int	internal_exist,external_exist;
1108 int	external_68882;
1109 
1110     SET_INT_FPP;	/* internal = on, external = off */
1111     if ( internal_exist = havefpp() && is_68882() ) {	/* internal = 68882 */
1112 	fpptype = FPP68882;
1113 	return;
1114     } else {		/* internal don't exist  or it is not 68882 */
1115         SET_EXT_FPP;	/* internal = off, external = on */
1116 	if ( internal_exist && 	/* internal = 68882, external <> 68882 */
1117 	     (!(external_exist = havefpp()) || !(external_68882 = is_68882())) ) {
1118 	   SET_INT_FPP;	/* internal = on, external = off */
1119 	   fpptype = FPP68881;
1120 	   return;
1121         }
1122 	if ( internal_exist ) { /* internal = 68881, external = 68882 */
1123 	   fpptype = FPP68882;
1124 	   return;
1125         }
1126 	if ( external_exist )  /* internal not exist, external exist */
1127 	    if ( external_68882 ) { 	/* external = 68882 */
1128 		fpptype = FPP68882;
1129 		return;
1130 	    } else { 			/* external = 68881 */
1131 		fpptype = FPP68881;
1132 		return;
1133 	    }
1134 	else		/* in/ex-ternal non exist */
1135 	    panic("fpp non-existence");
1136     }
1137 }
1138 #endif
1139 #endif
1140