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