xref: /original-bsd/sys/luna68k/luna68k/machdep.c (revision 2bdcd748)
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.10 (Berkeley) 05/12/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 #ifdef LUNA2
318 	if (machineid == LUNA_II) {
319 		sprintf(cpu_model, "LUNA-II (25MHz MC68040 CPU+MMU+FPU)");
320 		printf("%s\n", cpu_model);
321 		return;
322 	}
323 #endif
324 	if ( fpptype == -1 ) {
325 		printf("unknow FPU type \n");
326 		panic("startup");
327 	}
328 	sprintf(cpu_model, "LUNA-I (20MHz MC68030 CPU+MMU, 20MHz MC6888%d FPU)", fpptype);
329 	printf("%s\n", cpu_model);
330 
331 /*
332 	printf("LUNA(20Mhz MC68030 CPU, 20Mhz MC6888%d FPU)\n",fpptype);
333  */
334 }
335 
336 #define SS_RTEFRAME	1
337 #define SS_FPSTATE	2
338 #define SS_USERREGS	4
339 
340 struct sigstate {
341 	int	ss_flags;		/* which of the following are valid */
342 	struct	frame ss_frame;		/* original exception frame */
343 	struct	fpframe ss_fpstate;	/* 68881/68882 state info */
344 };
345 
346 /*
347  * WARNING: code in locore.s assumes the layout shown for sf_signum
348  * thru sf_handler so... don't screw with them!
349  */
350 struct sigframe {
351 	int	sf_signum;		/* signo for handler */
352 	int	sf_code;		/* additional info for handler */
353 	struct	sigcontext *sf_scp;	/* context ptr for handler */
354 	sig_t	sf_handler;		/* handler addr for u_sigc */
355 	struct	sigstate sf_state;	/* state of the hardware */
356 	struct	sigcontext sf_sc;	/* actual context */
357 };
358 
359 #ifdef DEBUG
360 int sigdebug = 0;
361 int sigpid = 0;
362 #define SDB_FOLLOW	0x01
363 #define SDB_KSTACK	0x02
364 #define SDB_FPSTATE	0x04
365 #endif
366 
367 /*
368  * Send an interrupt to process.
369  */
370 void
371 sendsig(catcher, sig, mask, code)
372 	sig_t catcher;
373 	int sig, mask;
374 	unsigned code;
375 {
376 	register struct proc *p = curproc;
377 	register struct sigframe *fp, *kfp;
378 	register struct frame *frame;
379 	register struct sigacts *psp = p->p_sigacts;
380 	register short ft;
381 	int oonstack, fsize;
382 	extern char sigcode[], esigcode[];
383 
384 	frame = (struct frame *)p->p_md.md_regs;
385 	ft = frame->f_format;
386 	oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
387 	/*
388 	 * Allocate and validate space for the signal handler
389 	 * context. Note that if the stack is in P0 space, the
390 	 * call to grow() is a nop, and the useracc() check
391 	 * will fail if the process has not already allocated
392 	 * the space with a `brk'.
393 	 */
394 	fsize = sizeof(struct sigframe);
395 	if ((psp->ps_flags & SAS_ALTSTACK) &&
396 	    (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
397 	    (psp->ps_sigonstack & sigmask(sig))) {
398 		fp = (struct sigframe *)(psp->ps_sigstk.ss_base +
399 					 psp->ps_sigstk.ss_size - fsize);
400 		psp->ps_sigstk.ss_flags |= SA_ONSTACK;
401 	} else
402 		fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
403 	if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
404 		(void)grow(p, (unsigned)fp);
405 #ifdef DEBUG
406 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
407 		printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n",
408 		       p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
409 #endif
410 	if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) {
411 #ifdef DEBUG
412 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
413 			printf("sendsig(%d): useracc failed on sig %d\n",
414 			       p->p_pid, sig);
415 #endif
416 		/*
417 		 * Process has trashed its stack; give it an illegal
418 		 * instruction to halt it in its tracks.
419 		 */
420 		SIGACTION(p, SIGILL) = SIG_DFL;
421 		sig = sigmask(SIGILL);
422 		p->p_sigignore &= ~sig;
423 		p->p_sigcatch &= ~sig;
424 		p->p_sigmask &= ~sig;
425 		psignal(p, SIGILL);
426 		return;
427 	}
428 	kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
429 	/*
430 	 * Build the argument list for the signal handler.
431 	 */
432 	kfp->sf_signum = sig;
433 	kfp->sf_code = code;
434 	kfp->sf_scp = &fp->sf_sc;
435 	kfp->sf_handler = catcher;
436 	/*
437 	 * Save necessary hardware state.  Currently this includes:
438 	 *	- general registers
439 	 *	- original exception frame (if not a "normal" frame)
440 	 *	- FP coprocessor state
441 	 */
442 	kfp->sf_state.ss_flags = SS_USERREGS;
443 	bcopy((caddr_t)frame->f_regs,
444 	      (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
445 	if (ft >= FMT7) {
446 #ifdef DEBUG
447 		if (ft != FMT9 && ft != FMTA && ft != FMTB)
448 			panic("sendsig: bogus frame type");
449 #endif
450 		kfp->sf_state.ss_flags |= SS_RTEFRAME;
451 		kfp->sf_state.ss_frame.f_format = frame->f_format;
452 		kfp->sf_state.ss_frame.f_vector = frame->f_vector;
453 		bcopy((caddr_t)&frame->F_u,
454 		      (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]);
455 		/*
456 		 * Leave an indicator that we need to clean up the kernel
457 		 * stack.  We do this by setting the "pad word" above the
458 		 * hardware stack frame to the amount the stack must be
459 		 * adjusted by.
460 		 *
461 		 * N.B. we increment rather than just set f_stackadj in
462 		 * case we are called from syscall when processing a
463 		 * sigreturn.  In that case, f_stackadj may be non-zero.
464 		 */
465 		frame->f_stackadj += exframesize[ft];
466 		frame->f_format = frame->f_vector = 0;
467 #ifdef DEBUG
468 		if (sigdebug & SDB_FOLLOW)
469 			printf("sendsig(%d): copy out %d of frame %d\n",
470 			       p->p_pid, exframesize[ft], ft);
471 #endif
472 	}
473 #ifdef FPCOPROC
474 	kfp->sf_state.ss_flags |= SS_FPSTATE;
475 	m68881_save(&kfp->sf_state.ss_fpstate);
476 #ifdef DEBUG
477 	if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
478 		printf("sendsig(%d): copy out FP state (%x) to %x\n",
479 		       p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
480 		       &kfp->sf_state.ss_fpstate);
481 #endif
482 #endif
483 	/*
484 	 * Build the signal context to be used by sigreturn.
485 	 */
486 	kfp->sf_sc.sc_onstack = oonstack;
487 	kfp->sf_sc.sc_mask = mask;
488 	kfp->sf_sc.sc_sp = frame->f_regs[SP];
489 	kfp->sf_sc.sc_fp = frame->f_regs[A6];
490 	kfp->sf_sc.sc_ap = (int)&fp->sf_state;
491 	kfp->sf_sc.sc_pc = frame->f_pc;
492 	kfp->sf_sc.sc_ps = frame->f_sr;
493 	(void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
494 	frame->f_regs[SP] = (int)fp;
495 #ifdef DEBUG
496 	if (sigdebug & SDB_FOLLOW)
497 		printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n",
498 		       p->p_pid, sig, kfp->sf_scp, fp,
499 		       kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
500 #endif
501 	/*
502 	 * Signal trampoline code is at base of user stack.
503 	 */
504 	frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode);
505 #ifdef DEBUG
506 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
507 		printf("sendsig(%d): sig %d returns\n",
508 		       p->p_pid, sig);
509 #endif
510 	free((caddr_t)kfp, M_TEMP);
511 }
512 
513 /*
514  * System call to cleanup state after a signal
515  * has been taken.  Reset signal mask and
516  * stack state from context left by sendsig (above).
517  * Return to previous pc and psl as specified by
518  * context left by sendsig. Check carefully to
519  * make sure that the user has not modified the
520  * psl to gain improper priviledges or to cause
521  * a machine fault.
522  */
523 struct sigreturn_args {
524 	struct sigcontext *sigcntxp;
525 };
526 /* ARGSUSED */
527 sigreturn(p, uap, retval)
528 	struct proc *p;
529 	struct sigreturn_args *uap;
530 	int *retval;
531 {
532 	register struct sigcontext *scp;
533 	register struct frame *frame;
534 	register int rf;
535 	struct sigcontext tsigc;
536 	struct sigstate tstate;
537 	int flags;
538 
539 	scp = uap->sigcntxp;
540 #ifdef DEBUG
541 	if (sigdebug & SDB_FOLLOW)
542 		printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
543 #endif
544 	if ((int)scp & 1)
545 		return (EINVAL);
546 	/*
547 	 * Test and fetch the context structure.
548 	 * We grab it all at once for speed.
549 	 */
550 	if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
551 	    copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
552 		return (EINVAL);
553 	scp = &tsigc;
554 	if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
555 		return (EINVAL);
556 	/*
557 	 * Restore the user supplied information
558 	 */
559 	if (scp->sc_onstack & 01)
560 		p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
561 	else
562 		p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
563 	p->p_sigmask = scp->sc_mask &~ sigcantmask;
564 	frame = (struct frame *) p->p_md.md_regs;
565 	frame->f_regs[SP] = scp->sc_sp;
566 	frame->f_regs[A6] = scp->sc_fp;
567 	frame->f_pc = scp->sc_pc;
568 	frame->f_sr = scp->sc_ps;
569 	/*
570 	 * Grab pointer to hardware state information.
571 	 * If zero, the user is probably doing a longjmp.
572 	 */
573 	if ((rf = scp->sc_ap) == 0)
574 		return (EJUSTRETURN);
575 	/*
576 	 * See if there is anything to do before we go to the
577 	 * expense of copying in close to 1/2K of data
578 	 */
579 	flags = fuword((caddr_t)rf);
580 #ifdef DEBUG
581 	if (sigdebug & SDB_FOLLOW)
582 		printf("sigreturn(%d): sc_ap %x flags %x\n",
583 		       p->p_pid, rf, flags);
584 #endif
585 	/*
586 	 * fuword failed (bogus sc_ap value).
587 	 */
588 	if (flags == -1)
589 		return (EINVAL);
590 	if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
591 		return (EJUSTRETURN);
592 #ifdef DEBUG
593 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
594 		printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
595 		       p->p_pid, &flags, scp->sc_sp, uap->sigcntxp,
596 		       (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
597 #endif
598 	/*
599 	 * Restore most of the users registers except for A6 and SP
600 	 * which were handled above.
601 	 */
602 	if (flags & SS_USERREGS)
603 		bcopy((caddr_t)tstate.ss_frame.f_regs,
604 		      (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
605 	/*
606 	 * Restore long stack frames.  Note that we do not copy
607 	 * back the saved SR or PC, they were picked up above from
608 	 * the sigcontext structure.
609 	 */
610 	if (flags & SS_RTEFRAME) {
611 		register int sz;
612 
613 		/* grab frame type and validate */
614 		sz = tstate.ss_frame.f_format;
615 		if (sz > 15 || (sz = exframesize[sz]) < 0)
616 			return (EINVAL);
617 		frame->f_stackadj -= sz;
618 		frame->f_format = tstate.ss_frame.f_format;
619 		frame->f_vector = tstate.ss_frame.f_vector;
620 		bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
621 #ifdef DEBUG
622 		if (sigdebug & SDB_FOLLOW)
623 			printf("sigreturn(%d): copy in %d of frame type %d\n",
624 			       p->p_pid, sz, tstate.ss_frame.f_format);
625 #endif
626 	}
627 #ifdef FPCOPROC
628 	/*
629 	 * Finally we restore the original FP context
630 	 */
631 	if (flags & SS_FPSTATE)
632 		m68881_restore(&tstate.ss_fpstate);
633 #ifdef DEBUG
634 	if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
635 		printf("sigreturn(%d): copied in FP state (%x) at %x\n",
636 		       p->p_pid, *(u_int *)&tstate.ss_fpstate,
637 		       &tstate.ss_fpstate);
638 #endif
639 #endif
640 #ifdef DEBUG
641 	if ((sigdebug & SDB_FOLLOW) ||
642 	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
643 		printf("sigreturn(%d): returns\n", p->p_pid);
644 #endif
645 	return (EJUSTRETURN);
646 }
647 
648 int	waittime = -1;
649 
650 boot(howto)
651 	register int howto;
652 {
653 	/* take a snap shot before clobbering any registers */
654 	if (curproc)
655 		savectx(curproc->p_addr, 0);
656 
657 	boothowto = howto;
658 	if ((howto&RB_NOSYNC) == 0 && waittime < 0) {
659 		register struct buf *bp;
660 		int iter, nbusy;
661 
662 		waittime = 0;
663 		(void) spl0();
664 		printf("syncing disks... ");
665 		/*
666 		 * Release vnodes held by texts before sync.
667 		 */
668 		if (panicstr == 0)
669 			vnode_pager_umount(NULL);
670 #ifdef notdef
671 #include "fd.h"
672 #if NFD > 0
673 		fdshutdown();
674 #endif
675 #endif
676 		sync(&proc0, (void *)NULL, (int *)NULL);
677 
678 		for (iter = 0; iter < 20; iter++) {
679 			nbusy = 0;
680 			for (bp = &buf[nbuf]; --bp >= buf; )
681 				if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
682 					nbusy++;
683 			if (nbusy == 0)
684 				break;
685 			printf("%d ", nbusy);
686 			DELAY(40000 * iter);
687 		}
688 		if (nbusy)
689 			printf("giving up\n");
690 		else
691 			printf("done\n");
692 
693 		/*
694 		 * If we've been adjusting the clock, the todr
695 		 * will be out of synch; adjust it now.
696 		 */
697 		resettodr();
698 	}
699 	splhigh();			/* extreme priority */
700 	if (howto&RB_HALT) {
701 		printf("halted\n\n");
702 		asm("	stop	#0x2700");
703 	} else {
704 		printf("\r\n\n");
705 		if (howto & RB_DUMP)
706 			dumpsys();
707 		doboot();
708 		/*NOTREACHED*/
709 	}
710 	/*NOTREACHED*/
711 }
712 
713 int	dumpmag = 0x8fca0101;	/* magic number for savecore */
714 int	dumpsize = 0;		/* also for savecore */
715 long	dumplo = 0;
716 
717 dumpconf()
718 {
719 	int nblks;
720 
721 	dumpsize = physmem;
722 	if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
723 		nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
724 		if (dumpsize > btoc(dbtob(nblks - dumplo)))
725 			dumpsize = btoc(dbtob(nblks - dumplo));
726 		else if (dumplo == 0)
727 			dumplo = nblks - btodb(ctob(physmem));
728 	}
729 	/*
730 	 * Don't dump on the first CLBYTES (why CLBYTES?)
731 	 * in case the dump device includes a disk label.
732 	 */
733 	if (dumplo < btodb(CLBYTES))
734 		dumplo = btodb(CLBYTES);
735 }
736 
737 /*
738  * Doadump comes here after turning off memory management and
739  * getting on the dump stack, either when called above, or by
740  * the auto-restart code.
741  */
742 dumpsys()
743 {
744 
745 	msgbufmapped = 0;
746 	if (dumpdev == NODEV)
747 		return;
748 	/*
749 	 * For dumps during autoconfiguration,
750 	 * if dump device has already configured...
751 	 */
752 	if (dumpsize == 0)
753 		dumpconf();
754 	if (dumplo < 0)
755 		return;
756 	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
757 	printf("dump ");
758 	switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
759 
760 	case ENXIO:
761 		printf("device bad\n");
762 		break;
763 
764 	case EFAULT:
765 		printf("device not ready\n");
766 		break;
767 
768 	case EINVAL:
769 		printf("area improper\n");
770 		break;
771 
772 	case EIO:
773 		printf("i/o error\n");
774 		break;
775 
776 	default:
777 		printf("succeeded\n");
778 		break;
779 	}
780 }
781 
782 initcpu()
783 {
784 	parityenable();
785 }
786 
787 straytrap(pc, evec)
788 	int pc;
789 	u_short evec;
790 {
791 	printf("unexpected trap (vector offset %x) from %x\n",
792 	       evec & 0xFFF, pc);
793 }
794 
795 int	*nofault;
796 
797 badaddr(addr)
798 	register caddr_t addr;
799 {
800 	register int i;
801 	label_t	faultbuf;
802 
803 #ifdef lint
804 	i = *addr; if (i) return(0);
805 #endif
806 	nofault = (int *) &faultbuf;
807 	if (setjmp((label_t *)nofault)) {
808 		nofault = (int *) 0;
809 		return(1);
810 	}
811 	i = *(volatile short *)addr;
812 	nofault = (int *) 0;
813 	return(0);
814 }
815 
816 badbaddr(addr)
817 	register caddr_t addr;
818 {
819 	register int i;
820 	label_t	faultbuf;
821 
822 #ifdef lint
823 	i = *addr; if (i) return(0);
824 #endif
825 	nofault = (int *) &faultbuf;
826 	if (setjmp((label_t *)nofault)) {
827 		nofault = (int *) 0;
828 		return(1);
829 	}
830 	i = *(volatile char *)addr;
831 	nofault = (int *) 0;
832 	return(0);
833 }
834 
835 netintr()
836 {
837 #ifdef INET
838 	if (netisr & (1 << NETISR_ARP)) {
839 		netisr &= ~(1 << NETISR_ARP);
840 		arpintr();
841 	}
842 	if (netisr & (1 << NETISR_IP)) {
843 		netisr &= ~(1 << NETISR_IP);
844 		ipintr();
845 	}
846 #endif
847 #ifdef NS
848 	if (netisr & (1 << NETISR_NS)) {
849 		netisr &= ~(1 << NETISR_NS);
850 		nsintr();
851 	}
852 #endif
853 #ifdef ISO
854 	if (netisr & (1 << NETISR_ISO)) {
855 		netisr &= ~(1 << NETISR_ISO);
856 		clnlintr();
857 	}
858 #endif
859 #ifdef CCITT
860 	if (netisr & (1 << NETISR_CCITT)) {
861 		netisr &= ~(1 << NETISR_CCITT);
862 		ccittintr();
863 	}
864 #endif
865 }
866 
867 #ifdef	notfdef
868 intrhand(sr)
869 	int sr;
870 {
871 	register struct isr *isr;
872 	register int found = 0;
873 	register int ipl;
874 	extern struct isr isrqueue[];
875 
876 	ipl = (sr >> 8) & 7;
877 	switch (ipl) {
878 
879 	case 3:
880 	case 4:
881 	case 5:
882 		ipl = ISRIPL(ipl);
883 		isr = isrqueue[ipl].isr_forw;
884 		for (; isr != &isrqueue[ipl]; isr = isr->isr_forw) {
885 			if ((isr->isr_intr)(isr->isr_arg)) {
886 				found++;
887 				break;
888 			}
889 		}
890 		if (found == 0)
891 			printf("stray interrupt, sr 0x%x\n", sr);
892 		break;
893 
894 	case 0:
895 	case 1:
896 	case 2:
897 	case 6:
898 	case 7:
899 		printf("intrhand: unexpected sr 0x%x\n", sr);
900 		break;
901 	}
902 }
903 #endif
904 
905 #if defined(DEBUG) && !defined(PANICBUTTON)
906 #define PANICBUTTON
907 #endif
908 
909 #ifdef PANICBUTTON
910 int panicbutton = 1;	/* non-zero if panic buttons are enabled */
911 int crashandburn = 0;
912 int candbdelay = 50;	/* give em half a second */
913 
914 void
915 candbtimer(arg)
916 	void *arg;
917 {
918 
919 	crashandburn = 0;
920 }
921 #endif
922 
923 /*
924  * Level 7 interrupts can be caused by the keyboard or parity errors.
925  */
926 nmihand(frame)
927 	struct frame frame;
928 {
929 #ifdef PANICBUTTON
930        	static int innmihand = 0;
931 
932        	/*
933        	 * Attempt to reduce the window of vulnerability for recursive
934        	 * NMIs (e.g. someone holding down the keyboard reset button).
935        	 */
936        	if (innmihand == 0) {
937        		innmihand = 1;
938        		printf("Got a keyboard NMI\n");
939        		innmihand = 0;
940        	}
941        	if (panicbutton) {
942        		if (crashandburn) {
943        			crashandburn = 0;
944        			panic(panicstr ?
945        			      "forced crash, nosync" : "forced crash");
946        		}
947        		crashandburn++;
948        		timeout(candbtimer, (void *)0, candbdelay);
949        	}
950 #endif
951        	return;
952 }
953 
954 regdump(fp, sbytes)
955 	struct frame *fp; /* must not be register */
956 	int sbytes;
957 {
958 	static int doingdump = 0;
959 	register int i;
960 	int s;
961 	extern char *hexstr();
962 
963 	if (doingdump)
964 		return;
965 	s = splhigh();
966 	doingdump = 1;
967 	printf("pid = %d, pc = %s, ",
968 	       curproc ? curproc->p_pid : -1, hexstr(fp->f_pc, 8));
969 	printf("ps = %s, ", hexstr(fp->f_sr, 4));
970 	printf("sfc = %s, ", hexstr(getsfc(), 4));
971 	printf("dfc = %s\n", hexstr(getdfc(), 4));
972 	printf("Registers:\n     ");
973 	for (i = 0; i < 8; i++)
974 		printf("        %d", i);
975 	printf("\ndreg:");
976 	for (i = 0; i < 8; i++)
977 		printf(" %s", hexstr(fp->f_regs[i], 8));
978 	printf("\nareg:");
979 	for (i = 0; i < 8; i++)
980 		printf(" %s", hexstr(fp->f_regs[i+8], 8));
981 	if (sbytes > 0) {
982 		if (fp->f_sr & PSL_S) {
983 			printf("\n\nKernel stack (%s):",
984 			       hexstr((int)(((int *)&fp)-1), 8));
985 			dumpmem(((int *)&fp)-1, sbytes, 0);
986 		} else {
987 			printf("\n\nUser stack (%s):", hexstr(fp->f_regs[SP], 8));
988 			dumpmem((int *)fp->f_regs[SP], sbytes, 1);
989 		}
990 	}
991 	doingdump = 0;
992 	splx(s);
993 }
994 
995 extern char kstack[];
996 #define KSADDR	((int *)&(kstack[(UPAGES-1)*NBPG]))
997 
998 dumpmem(ptr, sz, ustack)
999 	register int *ptr;
1000 	int sz;
1001 {
1002 	register int i, val;
1003 	extern char *hexstr();
1004 
1005 	for (i = 0; i < sz; i++) {
1006 		if ((i & 7) == 0)
1007 			printf("\n%s: ", hexstr((int)ptr, 6));
1008 		else
1009 			printf(" ");
1010 		if (ustack == 1) {
1011 			if ((val = fuword(ptr++)) == -1)
1012 				break;
1013 		} else {
1014 			if (ustack == 0 &&
1015 			    (ptr < KSADDR || ptr > KSADDR+(NBPG/4-1)))
1016 				break;
1017 			val = *ptr++;
1018 		}
1019 		printf("%s", hexstr(val, 8));
1020 	}
1021 	printf("\n");
1022 }
1023 
1024 char *
1025 hexstr(val, len)
1026 	register int val;
1027 {
1028 	static char nbuf[9];
1029 	register int x, i;
1030 
1031 	if (len > 8)
1032 		return("");
1033 	nbuf[len] = '\0';
1034 	for (i = len-1; i >= 0; --i) {
1035 		x = val & 0xF;
1036 		if (x > 9)
1037 			nbuf[i] = x - 10 + 'A';
1038 		else
1039 			nbuf[i] = x + '0';
1040 		val >>= 4;
1041 	}
1042 	return(nbuf);
1043 }
1044 
1045 #ifdef DEBUG
1046 char oflowmsg[] = "k-stack overflow";
1047 char uflowmsg[] = "k-stack underflow";
1048 
1049 badkstack(oflow, fr)
1050 	int oflow;
1051 	struct frame fr;
1052 {
1053 #ifdef	notdef
1054 	extern char kstackatbase[];
1055 
1056 	printf("%s: sp should be %x\n",
1057 	       oflow ? oflowmsg : uflowmsg,
1058 	       kstackatbase - (exframesize[fr.f_format] + 8));
1059 #endif
1060 	printf("%s: sp should be ????????\n", oflow ? oflowmsg : uflowmsg);
1061 	regdump(&fr, 0);
1062 	panic(oflow ? oflowmsg : uflowmsg);
1063 }
1064 #endif
1065 
1066 /* for LUNA */
1067 
1068 /*
1069  * Enable parity detection
1070  */
1071 #define PARREG		((volatile short *)0x49000003)
1072 #define	PARITY_ENABLE	0xC
1073 parityenable()
1074 {
1075 	*PARREG = PARITY_ENABLE;
1076 }
1077 
1078 #ifdef FPCOPROC
1079 #define EXT_FPP_ADDR		0x6F000000	/* External 68882 board  */
1080 #define INT_FPP_ADDR		0x6B000000	/* Internal 68881 chip   */
1081 
1082 #define FPP_ON			0x80		/* selected fpp on	 */
1083 #define FPP_OFF			0x00		/* selected fpp off    	 */
1084 
1085 #define	SET_INT_FPP	(*(char *)INT_FPP_ADDR = FPP_ON);(*(char *)EXT_FPP_ADDR = FPP_OFF)
1086 #define	SET_EXT_FPP	(*(char *)INT_FPP_ADDR = FPP_OFF);(*(char *)EXT_FPP_ADDR = FPP_ON)
1087 
1088 #define	FPP68881	1
1089 #define	FPP68882	2
1090 
1091 unsigned char fpp_svarea[212];
1092 
1093 #ifndef	OLD_LUNA
1094 /*
1095  * Check FPP type 68881/68882.
1096  */
1097 
1098 void checkfpp()
1099 {
1100 #ifdef LUNA2
1101 	if (machineid == LUNA_II) {
1102 		return;
1103 	}
1104 #endif
1105     SET_INT_FPP;	/* internal = on, external = off */
1106     if( is_68882() )
1107       fpptype = FPP68882;
1108     else
1109       fpptype = FPP68881;
1110     return;
1111 }
1112 #else
1113 
1114 /*
1115  * Check in/ex-ternal fpp, and determine which we use.
1116  * Also set fpp type(MC68881/68882).
1117  */
1118 
1119 void checkfpp()
1120 {
1121 int	internal_exist,external_exist;
1122 int	external_68882;
1123 #ifdef LUNA2
1124 	if (machineid == LUNA_II) {
1125 		return;
1126 	}
1127 #endif
1128 
1129     SET_INT_FPP;	/* internal = on, external = off */
1130     if ( internal_exist = havefpp() && is_68882() ) {	/* internal = 68882 */
1131 	fpptype = FPP68882;
1132 	return;
1133     } else {		/* internal don't exist  or it is not 68882 */
1134         SET_EXT_FPP;	/* internal = off, external = on */
1135 	if ( internal_exist && 	/* internal = 68882, external <> 68882 */
1136 	     (!(external_exist = havefpp()) || !(external_68882 = is_68882())) ) {
1137 	   SET_INT_FPP;	/* internal = on, external = off */
1138 	   fpptype = FPP68881;
1139 	   return;
1140         }
1141 	if ( internal_exist ) { /* internal = 68881, external = 68882 */
1142 	   fpptype = FPP68882;
1143 	   return;
1144         }
1145 	if ( external_exist )  /* internal not exist, external exist */
1146 	    if ( external_68882 ) { 	/* external = 68882 */
1147 		fpptype = FPP68882;
1148 		return;
1149 	    } else { 			/* external = 68881 */
1150 		fpptype = FPP68881;
1151 		return;
1152 	    }
1153 	else		/* in/ex-ternal non exist */
1154 	    panic("fpp non-existence");
1155     }
1156 }
1157 #endif
1158 #endif
1159