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 */
consinit()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 */
cpu_startup()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 */
setregs(p,entry,retval)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
identifyfpu()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
sendsig(catcher,sig,mask,code)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
boot(howto)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
dumpconf()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 */
dumpsys()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 */
cpu_sysctl(name,namelen,oldp,oldlenp,newp,newlen,p)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
initcpu()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
straytrap(pc,evec)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
badaddr(addr)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
badbaddr(addr)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
netintr()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
intrhand(sr)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
candbtimer(arg)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
dumpmem(ptr,sz,ustack)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 *
hexstr(val,len)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
badkstack(oflow,fr)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
parityenable()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
checkfpp()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
checkfpp()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