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