|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)trap.c 1.1 86/02/03 Copyr 1985 Sun Micro"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1985 by Sun Microsystems, Inc. ! 7: */ ! 8: ! 9: #include "../h/param.h" ! 10: #include "../h/systm.h" ! 11: #include "../h/dir.h" ! 12: #include "../h/user.h" ! 13: #include "../h/lnode.h" ! 14: #include "../h/proc.h" ! 15: #include "../h/seg.h" ! 16: #include "../h/vm.h" ! 17: #include "../h/share.h" ! 18: ! 19: #include "../machine/fault.h" ! 20: #include "../machine/frame.h" ! 21: #include "../machine/buserr.h" ! 22: #include "../machine/memerr.h" ! 23: #include "../machine/mmu.h" ! 24: #include "../machine/cpu.h" ! 25: #include "../machine/psl.h" ! 26: #include "../machine/pte.h" ! 27: #include "../machine/reg.h" ! 28: #include "../machine/trap.h" ! 29: ! 30: ! 31: #define USER 0x400 /* user-mode flag added to type */ ! 32: ! 33: struct sysent sysent[128]; ! 34: int syscnt[128]; ! 35: ! 36: char *trap_type[] = { ! 37: "Vector address 0x0", ! 38: "Vector address 0x4", ! 39: "Bus error", ! 40: "Address error", ! 41: "Illegal instruction", ! 42: "Divide by zero", ! 43: "CHK, CHK2 instruction", ! 44: "TRAPV, cpTRAPcc, cpTRAPcc instruction", ! 45: "Priviledge violation", ! 46: "Trace", ! 47: "1010 emulator trap", ! 48: "1111 emulator trap", ! 49: "Vector address 0x30", ! 50: "Coprocessor protocol error", ! 51: "Stack format error", ! 52: "Unitialized interrupt", ! 53: "Vector address 0x40", ! 54: "Vector address 0x44", ! 55: "Vector address 0x48", ! 56: "Vector address 0x4c", ! 57: "Vector address 0x50", ! 58: "Vector address 0x54", ! 59: "Vector address 0x58", ! 60: "Vector address 0x5c", ! 61: "Spurious interrupt", ! 62: }; ! 63: #define TRAP_TYPES (sizeof trap_type / sizeof trap_type[0]) ! 64: ! 65: #if defined(DEBUG) || defined(lint) ! 66: int tdebug = 0; ! 67: int tudebug = 0; ! 68: int lodebug = 0; ! 69: int bedebug = 0; ! 70: #else ! 71: #define tdebug 0 ! 72: #define tudebug 0 ! 73: #define lodebug 0 ! 74: #define bedebug 0 ! 75: #endif defined(DEBUG) || defined(lint) ! 76: ! 77: u_char getsegmap(); ! 78: long getpgmap(); ! 79: ! 80: /* ! 81: * Called from the trap handler when a processor trap occurs. ! 82: * Returns amount to adjust the stack: > 0 removes bus error ! 83: * info, == 0 does nothing. ! 84: */ ! 85: int ! 86: trap(type, regs, fmt) ! 87: int type; ! 88: struct regs regs; ! 89: struct stkfmt fmt; ! 90: { ! 91: register struct regs *locregs = ®s; ! 92: register int i = 0; ! 93: register struct proc *p = u.u_procp; ! 94: time_t syst; ! 95: int nosig = 0; ! 96: int besize = 0; ! 97: int be = (type == T_BUSERR)? getbuserr() : 0; ! 98: ! 99: cnt.v_trap++; ! 100: syst = u.u_vm.vm_stime; ! 101: if (tdebug) { ! 102: i = type/sizeof (int); ! 103: if ((unsigned)i < TRAP_TYPES) ! 104: printf("trap: %s\n", trap_type[i]); ! 105: showregs("trap", type, locregs, &fmt, be); ! 106: } ! 107: if (USERMODE(locregs->r_sr)) { ! 108: type |= USER; ! 109: u.u_ar0 = &locregs->r_dreg[0]; ! 110: } ! 111: ! 112: switch (type) { ! 113: ! 114: default: ! 115: die: ! 116: (void) spl7(); ! 117: showregs((char *)0, fmt.f_vector, locregs, &fmt, be); ! 118: traceback((long)locregs->r_areg[6], (long)locregs->r_sp); ! 119: i = fmt.f_vector/sizeof (int); ! 120: if (i < TRAP_TYPES) ! 121: panic(trap_type[i]); ! 122: panic("trap"); ! 123: /*NOTREACHED*/ ! 124: ! 125: case T_BUSERR: ! 126: if (be & BE_TIMEOUT) ! 127: DELAY(2000); /* allow for refresh recovery time */ ! 128: ! 129: /* may have been expected by C (e.g., Multibus probe) */ ! 130: if (nofault) { ! 131: label_t *ftmp; ! 132: ! 133: ftmp = nofault; ! 134: nofault = 0; ! 135: longjmp(ftmp); ! 136: } ! 137: /* may be fault caused by transfer to/from user space */ ! 138: if (u.u_lofault == 0) ! 139: goto die; ! 140: ! 141: switch (fmt.f_stkfmt) { ! 142: case SF_MEDIUM: { ! 143: struct bei_medium *beip = ! 144: (struct bei_medium *)&fmt.f_beibase; ! 145: ! 146: besize = sizeof (struct bei_medium); ! 147: if (beip->bei_faultc || beip->bei_faultb) ! 148: break; ! 149: if (beip->bei_dfault && pagefault(beip->bei_fault)) ! 150: return (0); ! 151: break; ! 152: } ! 153: case SF_LONGB: { ! 154: struct bei_longb *beip = ! 155: (struct bei_longb *)&fmt.f_beibase; ! 156: ! 157: besize = sizeof (struct bei_longb); ! 158: if (beip->bei_faultc || beip->bei_faultb) ! 159: break; ! 160: if (beip->bei_dfault && pagefault(beip->bei_fault)) ! 161: return (0); ! 162: break; ! 163: } ! 164: default: ! 165: panic("bad bus error stack format"); ! 166: } ! 167: ! 168: if (lodebug) { ! 169: showregs("lofault", type, locregs, &fmt, be); ! 170: traceback((long)locregs->r_areg[6], ! 171: (long)locregs->r_sp); ! 172: } ! 173: locregs->r_pc = u.u_lofault; ! 174: return (besize); ! 175: ! 176: case T_ADDRERR: /* address error */ ! 177: /* may be fault caused by transfer to/from user space */ ! 178: if (u.u_lofault == 0) ! 179: goto die; ! 180: switch (fmt.f_stkfmt) { ! 181: case SF_MEDIUM: { ! 182: struct bei_medium *beip = ! 183: (struct bei_medium *)&fmt.f_beibase; ! 184: ! 185: if (beip->bei_fcode != FC_UD) ! 186: goto die; ! 187: besize = sizeof (struct bei_medium); ! 188: break; ! 189: } ! 190: case SF_LONGB: { ! 191: struct bei_longb *beip = ! 192: (struct bei_longb *)&fmt.f_beibase; ! 193: ! 194: if (beip->bei_fcode != FC_UD) ! 195: goto die; ! 196: besize = sizeof (struct bei_longb); ! 197: break; ! 198: } ! 199: default: ! 200: panic("bad address error stack format"); ! 201: } ! 202: if (lodebug) { ! 203: showregs("lofault", type, locregs, &fmt, be); ! 204: traceback((long)locregs->r_areg[6], ! 205: (long)locregs->r_sp); ! 206: } ! 207: locregs->r_pc = u.u_lofault; ! 208: return (besize); ! 209: ! 210: case T_ADDRERR + USER: /* user address error */ ! 211: if (tudebug) ! 212: showregs("USER ADDRESS ERROR", type, locregs, &fmt, be); ! 213: i = SIGBUS; ! 214: switch (fmt.f_stkfmt) { ! 215: case SF_MEDIUM: ! 216: besize = sizeof (struct bei_medium); ! 217: break; ! 218: case SF_LONGB: ! 219: besize = sizeof (struct bei_longb); ! 220: break; ! 221: default: ! 222: panic("bad address error stack format"); ! 223: } ! 224: break; ! 225: ! 226: case T_SPURIOUS: ! 227: case T_SPURIOUS + USER: /* spurious interrupt */ ! 228: i = spl7(); ! 229: printf("spurious level %d interrupt\n", (i & SR_INTPRI) >> 8); ! 230: (void) splx(i); ! 231: return (0); ! 232: ! 233: case T_PRIVVIO + USER: /* privileged instruction fault */ ! 234: if (tudebug) ! 235: showregs("USER PRIVILEGED INSTRUCTION", type, locregs, ! 236: &fmt, be); ! 237: u.u_code = fmt.f_vector; ! 238: i = SIGILL; ! 239: break; ! 240: ! 241: case T_COPROCERR + USER: /* coprocessor protocol error */ ! 242: /* ! 243: * Dump out obnoxious info to warn user ! 244: * that something isn't right w/ the 68881 ! 245: */ ! 246: showregs("USER COPROCESSOR PROTOCOL ERROR", type, locregs, ! 247: &fmt, be); ! 248: u.u_code = fmt.f_vector; ! 249: i = SIGILL; ! 250: break; ! 251: ! 252: case T_M_BADTRAP + USER: /* (some) undefined trap */ ! 253: case T_ILLINST + USER: /* illegal instruction fault */ ! 254: if (tudebug) ! 255: showregs("USER ILLEGAL INSTRUCTION", type, locregs, ! 256: &fmt, be); ! 257: u.u_code = fmt.f_vector; ! 258: i = SIGILL; ! 259: break; ! 260: ! 261: case T_M_FLOATERR + USER: /* (some) floating error trap */ ! 262: case T_ZERODIV + USER: /* divide by zero */ ! 263: case T_CHKINST + USER: /* CHK [CHK2] instruction */ ! 264: case T_TRAPV + USER: /* TRAPV [cpTRAPcc TRAPcc] instr */ ! 265: u.u_code = fmt.f_vector; ! 266: i = SIGFPE; ! 267: break; ! 268: ! 269: /* ! 270: * If the user SP is above the stack segment, ! 271: * grow the stack automatically. ! 272: */ ! 273: case T_BUSERR + USER: { ! 274: ! 275: if (be & BE_TIMEOUT) ! 276: DELAY(2000); /* allow for refresh recovery time */ ! 277: ! 278: switch (fmt.f_stkfmt) { ! 279: case SF_MEDIUM: { ! 280: struct bei_medium *beip = ! 281: (struct bei_medium *)&fmt.f_beibase; ! 282: ! 283: besize = sizeof (struct bei_medium); ! 284: /* ! 285: * check for any errors in buserr ! 286: * register besides invalid ! 287: */ ! 288: if (be & ~BE_INVALID) ! 289: goto pferr; ! 290: if ((bedebug && (beip->bei_faultb || beip->bei_faultc)) ! 291: || (bedebug > 1 && beip->bei_fault)) ! 292: printf("medium fault b %d %x, c %d %x, d %d %x\n", ! 293: beip->bei_faultb, locregs->r_pc+4, ! 294: beip->bei_faultc, locregs->r_pc+2, ! 295: beip->bei_dfault, beip->bei_fault); ! 296: ! 297: if (beip->bei_dfault && ((beip->bei_fcode == FC_UD) ! 298: || (beip->bei_fcode == FC_UP))) { ! 299: if (pagefault(beip->bei_fault)) ! 300: return (0); ! 301: if (grow((unsigned)beip->bei_fault)) { ! 302: nosig = 1; ! 303: besize = 0; ! 304: goto out; ! 305: } ! 306: goto pferr; ! 307: } ! 308: if (beip->bei_faultc) { ! 309: if (pagefault(locregs->r_pc+2)) ! 310: return (0); ! 311: goto pferr; ! 312: } ! 313: if (beip->bei_faultb) { ! 314: if (pagefault(locregs->r_pc+4)) ! 315: return (0); ! 316: goto pferr; ! 317: } ! 318: goto pferr; ! 319: } ! 320: case SF_LONGB: { ! 321: struct bei_longb *beip = ! 322: (struct bei_longb *)&fmt.f_beibase; ! 323: ! 324: besize = sizeof (struct bei_longb); ! 325: /* ! 326: * check for any errors in buserr ! 327: * register besides invalid ! 328: */ ! 329: if (be & ~BE_INVALID) ! 330: goto pferr; ! 331: if ((bedebug && (beip->bei_faultb || beip->bei_faultc)) ! 332: || (bedebug > 1 && beip->bei_fault)) ! 333: printf("long fault b %d %x, c %d %x, d %d %x\n", ! 334: beip->bei_faultb, beip->bei_stageb, ! 335: beip->bei_faultc, beip->bei_stageb-2, ! 336: beip->bei_dfault, beip->bei_fault); ! 337: ! 338: if (beip->bei_dfault && ((beip->bei_fcode == FC_UD) ! 339: || (beip->bei_fcode == FC_UP))) { ! 340: if (pagefault(beip->bei_fault)) ! 341: return (0); ! 342: if (grow((unsigned)beip->bei_fault)) { ! 343: nosig = 1; ! 344: besize = 0; ! 345: goto out; ! 346: } ! 347: goto pferr; ! 348: } ! 349: if (beip->bei_faultc) { ! 350: if (pagefault(beip->bei_stageb-2)) ! 351: return (0); ! 352: goto pferr; ! 353: } ! 354: if (beip->bei_faultb) { ! 355: if (pagefault(beip->bei_stageb)) ! 356: return (0); ! 357: goto pferr; ! 358: } ! 359: goto pferr; ! 360: } ! 361: default: ! 362: panic("bad bus error stack format"); ! 363: } ! 364: pferr: ! 365: if (tudebug) ! 366: showregs("USER BUS ERROR", type, locregs, &fmt, be); ! 367: i = SIGSEGV; ! 368: if (besize == 0) ! 369: panic("besize"); ! 370: break; ! 371: } ! 372: ! 373: case T_TRACE: /* caused by tracing trap instr */ ! 374: u.u_pcb.pcb_p0lr |= TRACE_PENDING; ! 375: return (0); ! 376: ! 377: case T_TRACE + USER: /* trace trap */ ! 378: dotrace(locregs); ! 379: goto out; ! 380: ! 381: case T_BRKPT + USER: /* bpt instruction (trap #15) fault */ ! 382: u.u_code = TRAP_BKPT; ! 383: i = SIGTRAP; ! 384: break; ! 385: ! 386: case T_EMU1010 + USER: /* 1010 emulator trap */ ! 387: case T_EMU1111 + USER: /* 1111 emulator trap */ ! 388: u.u_code = fmt.f_vector; ! 389: i = SIGEMT; ! 390: break; ! 391: } ! 392: ! 393: psignal(u.u_procp, i); ! 394: out: ! 395: if (u.u_pcb.pcb_p0lr & TRACE_PENDING) ! 396: dotrace(locregs); ! 397: p = u.u_procp; ! 398: if (p->p_cursig || (p->p_sig && issig(p))) ! 399: psig(); ! 400: p->p_pri = p->p_usrpri; ! 401: if (runrun) { ! 402: /* ! 403: * Since we are u.u_procp, clock will normally just change ! 404: * our priority without moving us from one queue to another ! 405: * (since the running process is not on a queue.) ! 406: * If that happened after we setrq ourselves but before we ! 407: * swtch()'ed, we might not be on the queue indicated by ! 408: * our priority. ! 409: */ ! 410: (void) spl6(); ! 411: setrq(p); ! 412: swtch(); ! 413: (void) spl0(); ! 414: } ! 415: if (u.u_prof.pr_scale && (syst -= u.u_vm.vm_stime)) ! 416: addupc(locregs->r_pc, &u.u_prof, (int)-syst); ! 417: curpri = p->p_pri; ! 418: return (besize); ! 419: } ! 420: ! 421: /* ! 422: * Called from the trap handler when a system call occurs ! 423: */ ! 424: long syscount[0200]; /* temp */ ! 425: syscall(code, regs) ! 426: int code; ! 427: struct regs regs; ! 428: { ! 429: time_t syst; ! 430: caddr_t params; ! 431: int i; ! 432: ! 433: syst = u.u_vm.vm_stime; ! 434: if (!USERMODE(regs.r_sr)) ! 435: panic("syscall"); ! 436: { ! 437: /* ! 438: * At this point we declare a number of register variables. ! 439: * syscall_setjmp (called below) does not preserve the values ! 440: * of register variables, so we limit their scope to this block. ! 441: */ ! 442: register struct regs *locregs; ! 443: register struct sysent *callp; ! 444: register struct proc *p; ! 445: ! 446: p = u.u_procp; ! 447: p->p_lnode->kl_cost += shconsts.sc_syscall; ! 448: shconsts.sc_syscallc++; ! 449: syscount[code&0177]++; ! 450: locregs = ®s; ! 451: u.u_ar0 = &locregs->r_dreg[0]; ! 452: params = (caddr_t)locregs->r_sp + 2 * NBPW; ! 453: u.u_error = 0; ! 454: callp = &sysent[code&0177]; ! 455: if (callp == sysent) { ! 456: i = fuword(params); ! 457: params += NBPW; ! 458: callp = &sysent[i&0177]; ! 459: } ! 460: if (callp->sy_narg) { ! 461: if (fulwds((caddr_t)params, (caddr_t)u.u_arg, ! 462: callp->sy_narg)) { ! 463: u.u_error = EFAULT; ! 464: goto bad; ! 465: } ! 466: } ! 467: u.u_ap = u.u_arg; ! 468: u.u_dirp = (caddr_t)u.u_arg[0]; ! 469: u.u_r.r_val1 = 0; ! 470: u.u_r.r_val2 = regs.r_dreg[1]; ! 471: syscnt[callp - sysent]++; ! 472: /* ! 473: * Syscall_setjmp is a special setjmp that only saves a6 and sp. ! 474: * The result is a significant speedup of this critical path, ! 475: * but meanwhile all the register variables have the wrong ! 476: * values after a longjmp returns here. ! 477: * This is the reason for the limited scope of the register ! 478: * variables in this routine - the values may go away here. ! 479: */ ! 480: if (syscall_setjmp(u.u_qsav)) { ! 481: if (u.u_error == 0 && u.u_eosys == JUSTRETURN) ! 482: u.u_error = EINTR; ! 483: } else { ! 484: u.u_eosys = JUSTRETURN; ! 485: (*(callp->sy_call))(u.u_ap); ! 486: } ! 487: /* end of scope of register variables above */ ! 488: } ! 489: if (u.u_eosys != JUSTRETURN) { ! 490: if (u.u_eosys == RESTARTSYS) ! 491: regs.r_pc -= 2; ! 492: } else { ! 493: regs.r_sp += sizeof (int); /* pop syscall # */ ! 494: if (u.u_error) { ! 495: bad: ! 496: regs.r_dreg[0] = u.u_error; ! 497: regs.r_sr |= SR_CC; /* carry bit */ ! 498: } else { ! 499: regs.r_sr &= ~SR_CC; ! 500: regs.r_dreg[0] = u.u_r.r_val1; ! 501: regs.r_dreg[1] = u.u_r.r_val2; ! 502: } ! 503: } ! 504: if (u.u_pcb.pcb_p0lr & TRACE_PENDING) ! 505: dotrace(®s); ! 506: { ! 507: /* scope for use of register variable p */ ! 508: register struct proc *p; ! 509: ! 510: p = u.u_procp; ! 511: if (p->p_cursig || (p->p_sig && issig(p))) ! 512: psig(); ! 513: p->p_pri = p->p_usrpri; ! 514: if (runrun) { ! 515: /* ! 516: * Since we are u.u_procp, clock will normally just change ! 517: * our priority without moving us from one queue to another ! 518: * (since the running process is not on a queue.) ! 519: * If that happened after we setrq ourselves but before we ! 520: * swtch()'ed, we might not be on the queue indicated by ! 521: * our priority. ! 522: */ ! 523: (void) spl6(); ! 524: setrq(p); ! 525: swtch(); ! 526: (void) spl0(); ! 527: } ! 528: if (u.u_prof.pr_scale && (syst -= u.u_vm.vm_stime)) ! 529: addupc(regs.r_pc, &u.u_prof, (int)-syst); ! 530: curpri = p->p_pri; ! 531: } ! 532: } ! 533: ! 534: /* ! 535: * nonexistent system call-- set fatal error code. ! 536: */ ! 537: nosys() ! 538: { ! 539: ! 540: u.u_error = 100; ! 541: } ! 542: ! 543: /* ! 544: * Ignored system call ! 545: */ ! 546: nullsys() ! 547: { ! 548: ! 549: } ! 550: ! 551: /* ! 552: * Handle trace traps, both real and delayed. ! 553: */ ! 554: dotrace(locregs) ! 555: struct regs *locregs; ! 556: { ! 557: register int r, s; ! 558: struct proc *p = u.u_procp; ! 559: ! 560: s = spl6(); ! 561: r = u.u_pcb.pcb_p0lr&AST_CLR; ! 562: u.u_pcb.pcb_p0lr &= ~AST_CLR; ! 563: u.u_ar0[PS] &= ~PSL_T; ! 564: (void) splx(s); ! 565: if (r & TRACE_AST) { ! 566: if ((p->p_flag&SOWEUPC) && u.u_prof.pr_scale) { ! 567: addupc(locregs->r_pc, &u.u_prof, 1); ! 568: p->p_flag &= ~SOWEUPC; ! 569: } ! 570: if ((r & TRACE_USER) == 0) ! 571: return; ! 572: } ! 573: u.u_code = TRAP_TRACE; ! 574: psignal(p, SIGTRAP); ! 575: } ! 576: ! 577: /* ! 578: * Print out a traceback for kernel traps ! 579: */ ! 580: traceback(afp, sp) ! 581: long afp, sp; ! 582: { ! 583: struct frame *tospage = (struct frame *)btoc(sp); ! 584: struct frame *fp = (struct frame *)afp; ! 585: static int done = 0; ! 586: ! 587: if (panicstr && done++ > 0) ! 588: return; ! 589: ! 590: printf("Begin traceback...fp = %x, sp = %x\n", fp, sp); ! 591: while (btoc(((int)fp)) == (int)tospage) { ! 592: if (fp == fp->fr_savfp) { ! 593: printf("FP loop at %x", fp); ! 594: break; ! 595: } ! 596: printf("Called from %x, fp=%x, args=%x %x %x %x\n", ! 597: fp->fr_savpc, fp->fr_savfp, ! 598: fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], fp->fr_arg[3]); ! 599: fp = fp->fr_savfp; ! 600: } ! 601: printf("End traceback...\n"); ! 602: DELAY(2000000); ! 603: } ! 604: ! 605: showregs(str, type, locregs, fmtp, be) ! 606: char *str; ! 607: int type; ! 608: struct regs *locregs; ! 609: struct stkfmt *fmtp; ! 610: { ! 611: int *r, s; ! 612: int fcode, accaddr; ! 613: char *why; ! 614: ! 615: s = spl7(); ! 616: printf("%s: %s\n", u.u_comm, str ? str : ""); ! 617: printf( ! 618: "trap address 0x%x, pid %d, pc = %x, sr = %x, stkfmt %x, context %x\n", ! 619: fmtp->f_vector, u.u_procp->p_pid, locregs->r_pc, locregs->r_sr, ! 620: fmtp->f_stkfmt, getcontext()); ! 621: type &= ~USER; ! 622: if (type == T_BUSERR) ! 623: printf("Bus Error Reg %b\n", be, BUSERR_BITS); ! 624: if (type == T_BUSERR || type == T_ADDRERR) { ! 625: switch (fmtp->f_stkfmt) { ! 626: case SF_MEDIUM: { ! 627: struct bei_medium *beip = ! 628: (struct bei_medium *)&fmtp->f_beibase; ! 629: ! 630: fcode = beip->bei_fcode; ! 631: if (beip->bei_dfault) { ! 632: why = "data"; ! 633: accaddr = beip->bei_fault; ! 634: } else if (beip->bei_faultc) { ! 635: why = "stage c"; ! 636: accaddr = locregs->r_pc+2; ! 637: } else if (beip->bei_faultb) { ! 638: why = "stage b"; ! 639: accaddr = locregs->r_pc+4; ! 640: } else { ! 641: why = "unknown"; ! 642: accaddr = 0; ! 643: } ! 644: printf("%s fault address %x faultc %d faultb %d ", ! 645: why, accaddr, beip->bei_faultc, beip->bei_faultb); ! 646: printf("dfault %d rw %d size %d fcode %d\n", ! 647: beip->bei_dfault, beip->bei_rw, ! 648: beip->bei_size, fcode); ! 649: break; ! 650: } ! 651: case SF_LONGB: { ! 652: struct bei_longb *beip = ! 653: (struct bei_longb *)&fmtp->f_beibase; ! 654: ! 655: fcode = beip->bei_fcode; ! 656: if (beip->bei_dfault) { ! 657: why = "data"; ! 658: accaddr = beip->bei_fault; ! 659: } else if (beip->bei_faultc) { ! 660: why = "stage c"; ! 661: accaddr = beip->bei_stageb-2; ! 662: } else if (beip->bei_faultb) { ! 663: why = "stage b"; ! 664: accaddr = beip->bei_stageb; ! 665: } else { ! 666: why = "unknown"; ! 667: accaddr = 0; ! 668: } ! 669: printf("%s fault address %x faultc %d faultb %d ", ! 670: why, accaddr, beip->bei_faultc, beip->bei_faultb); ! 671: printf("dfault %d rw %d size %d fcode %d\n", ! 672: beip->bei_dfault, beip->bei_rw, ! 673: beip->bei_size, fcode); ! 674: break; ! 675: } ! 676: default: ! 677: panic("bad bus error stack format"); ! 678: } ! 679: if (fcode == FC_SD || fcode == FC_SP) { ! 680: printf("KERNEL MODE\n"); ! 681: printf("page map %x\n", getpgmap((caddr_t)accaddr)); ! 682: } else { ! 683: int tss, dss, sss, v; ! 684: struct pmeg *pmp; ! 685: struct proc *p = u.u_procp; ! 686: struct pte *pte; ! 687: ! 688: v = btop(accaddr); ! 689: tss = tptov(p, 0); ! 690: dss = dptov(p, 0); ! 691: sss = sptov(p, p->p_ssize - 1); ! 692: if (v >= tss && v < tss + p->p_tsize || ! 693: v >= dss && v < dss + p->p_dsize || ! 694: v >= sss && v < sss + p->p_ssize) { ! 695: pmp = &pmeg[p->p_ctx->ctx_pmeg[v/NPAGSEG]]; ! 696: pte = vtopte(p, (unsigned)v); ! 697: printf("pagefault, pmp %x, pte %x %x\n", ! 698: pmp, pte, *pte); ! 699: printf("pme %x\n", getpgmap((caddr_t)accaddr)); ! 700: } else { ! 701: printf("bad addr, v %d tss %d dss %d sss %d\n", ! 702: v, tss, dss, sss); ! 703: } ! 704: } ! 705: } ! 706: r = &locregs->r_dreg[0]; ! 707: printf("D0-D7 %x %x %x %x %x %x %x %x\n", ! 708: r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]); ! 709: r = &locregs->r_areg[0]; ! 710: printf("A0-A7 %x %x %x %x %x %x %x %x\n", ! 711: r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]); ! 712: DELAY(2000000); ! 713: (void) splx(s); ! 714: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.