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