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