1: /* 2: * SCCS id @(#)trap.c 2.1 (Berkeley) 9/4/83 3: */ 4: 5: #include "param.h" 6: #include <sys/systm.h> 7: #include <sys/dir.h> 8: #include <sys/user.h> 9: #include <sys/proc.h> 10: #include <sys/reg.h> 11: #include <sys/seg.h> 12: #ifdef UCB_METER 13: #include <sys/vm.h> 14: #endif 15: #include <sys/trap.h> 16: #include <sys/inline.h> 17: #include <sys/iopage.h> 18: 19: #define SETD 0170011 /* SETD instruction */ 20: #define SYS 0104400 /* sys (trap) instruction */ 21: #define USER 020 /* user-mode flag added to dev */ 22: 23: #ifdef MENLO_KOV 24: extern int _ovno; 25: #endif 26: #ifdef DIAGNOSTIC 27: extern int hasmap; 28: int savhasmap; 29: #endif 30: mapinfo kernelmap; /* saved mapping info on kernel-mode trap */ 31: 32: /* 33: * In order to stop the system from destroying 34: * kernel data space any further, allow only one 35: * fatal trap. After once_thru is set, any 36: * futher traps will be handled by looping in place. 37: */ 38: int once_thru = 0; 39: 40: /* 41: * Offsets of the user's registers relative to 42: * the saved r0. See sys/reg.h. 43: */ 44: char regloc[] = { 45: R0, R1, R2, R3, R4, R5, R6, R7, RPS 46: }; 47: 48: /* 49: * Called from mch.s when a processor trap occurs. 50: * The arguments are the words saved on the system stack 51: * by the hardware and software during the trap processing. 52: * Their order is dictated by the hardware and the details 53: * of C's calling sequence. They are peculiar in that 54: * this call is not 'by value' and changed user registers 55: * get copied back on return. 56: * Dev is the kind of trap that occurred. 57: */ 58: /*ARGSUSED*/ 59: #ifdef MENLO_KOV 60: trap(dev, sp, r1, ov, nps, r0, pc, ps) 61: #else 62: trap(dev, sp, r1, nps, r0, pc, ps) 63: #endif 64: int *pc; 65: dev_t dev; 66: { 67: register i; 68: register int *a; 69: int (*fetch)(), fuword(), fuiword(); 70: time_t syst; 71: 72: if (once_thru) { 73: (void) _spl7(); 74: for(;;); 75: } 76: if (USERMODE(ps)) 77: dev |= USER; 78: else 79: /* guarantee normal kernel mapping */ 80: savemap(kernelmap); 81: syst = u.u_stime; 82: #ifndef NONFP 83: u.u_fpsaved = 0; 84: #endif 85: u.u_ar0 = &r0; 86: #ifdef UCB_METER 87: cnt.v_trap++; 88: #endif 89: switch(minor(dev)) { 90: 91: /* 92: * Trap not expected. 93: * Usually a kernel mode bus error. 94: * The numbers printed are used to 95: * find the hardware PS/PC as follows. 96: * (all numbers in octal 18 bits) 97: * address_of_saved_ps = 98: * (ka6*0100) + aps - 0140000; 99: * address_of_saved_pc = 100: * address_of_saved_ps - 2; 101: */ 102: default: 103: once_thru = 1; 104: #if defined(DIAGNOSTIC) && !defined(NOKA5) 105: /* 106: * Clear hasmap if we attempt to sync the fs. 107: * Else it might fail if we faulted with a mapped 108: * buffer. 109: */ 110: savhasmap = hasmap; 111: hasmap = 0; 112: #endif 113: printf("ka6 = %o\n", *ka6); 114: printf("aps = %o\n", &ps); 115: printf("pc = %o ps = %o\n", pc, ps); 116: #ifdef MENLO_KOV 117: printf("__ovno = %d\n", ov); 118: #endif 119: #if PDP11 == 44 || PDP11 == 70 || PDP11 == GENERIC 120: if((cputype == 70) || (cputype == 44)) 121: printf("cpuerr = %o\n", *CPUERR); 122: #endif 123: printf("trap type %o\n", dev); 124: panic("trap"); 125: 126: case BUSFLT + USER: 127: i = SIGBUS; 128: break; 129: 130: /* 131: * If illegal instructions are not 132: * being caught and the offending instruction 133: * is a SETD, the trap is ignored. 134: * This is because C produces a SETD at 135: * the beginning of every program which 136: * will trap on CPUs without an FP-11. 137: */ 138: case INSTRAP + USER: 139: if(fuiword((caddr_t)(pc-1)) == SETD && u.u_signal[SIGILL] == 0) 140: goto out; 141: i = SIGILL; 142: break; 143: 144: case BPTTRAP + USER: 145: i = SIGTRAP; 146: ps &= ~PS_T; 147: break; 148: 149: case IOTTRAP + USER: 150: i = SIGIOT; 151: break; 152: 153: case EMTTRAP + USER: 154: i = SIGEMT; 155: break; 156: 157: #ifndef NONFP 158: /* 159: * Since the floating exception is an 160: * imprecise trap, a user generated 161: * trap may actually come from kernel 162: * mode. In this case, a signal is sent 163: * to the current process to be picked 164: * up later. 165: */ 166: case ARITHTRAP: 167: stst(&u.u_fperr); /* save error code and address */ 168: psignal(u.u_procp, SIGFPE); 169: runrun++; 170: goto kernelout; 171: 172: case ARITHTRAP + USER: 173: i = SIGFPE; 174: stst(&u.u_fperr); 175: break; 176: #endif 177: 178: /* 179: * If the user SP is below the stack segment, 180: * grow the stack automatically. 181: * This relies on the ability of the hardware 182: * to restart a half executed instruction. 183: * On the 11/40 this is not the case and 184: * the routine backup/mch.s may fail. 185: * The classic example is on the instruction 186: * cmp -(sp),-(sp) 187: */ 188: case SEGFLT + USER: 189: { 190: int osp; 191: 192: osp = sp; 193: if(backup(u.u_ar0) == 0) 194: if(grow((unsigned)osp)) 195: goto out; 196: i = SIGSEGV; 197: break; 198: } 199: 200: #if PDP11 == 44 || PDP11 == 70 || PDP11 == GENERIC 201: /* 202: * The code here is a half-hearted 203: * attempt to do something with all 204: * of the PDP11 parity registers. 205: * In fact, there is little that 206: * can be done. 207: */ 208: case PARITYFLT: 209: case PARITYFLT + USER: 210: printf("parity\n"); 211: if((cputype == 70) || (cputype == 44)) { 212: for(i = 0; i < 4; i++) 213: printf("%o ", MEMERRLO[i]); 214: printf("\n"); 215: MEMERRLO[2] = -1; 216: if(dev & USER) { 217: i = SIGBUS; 218: break; 219: } 220: } 221: panic("parity"); 222: #endif 223: 224: /* 225: * Allow process switch 226: */ 227: case SWITCHTRAP + USER: 228: goto out; 229: 230: /* 231: * Whenever possible, locations 0-2 232: * specify this style trap, since 233: * DEC hardware often generates spurious 234: * traps through location 0. This is a 235: * symptom of hardware problems and may 236: * represent a real interrupt that got 237: * sent to the wrong place. Watch out 238: * for hangs on disk completion if this message appears. 239: * Uninitialized interrupt vectors may be set to trap here also. 240: */ 241: case ZEROTRAP: 242: case ZEROTRAP + USER: 243: printf("Trap to 0: "); 244: /*FALL THROUGH*/ 245: case RANDOMTRAP: 246: case RANDOMTRAP + USER: 247: printf("Random interrupt ignored\n"); 248: if ((dev & USER) != 0) 249: return; 250: 251: #if !defined(NONFP) || !defined(NONSEPARATE) 252: kernelout: 253: restormap(kernelmap); 254: return; 255: #endif 256: } 257: 258: /* 259: * If there is a trap from user mode and it is caught, 260: * send the signal now. This prevents user-mode exceptions 261: * from being delayed by other signals, and in addition is 262: * more efficient in the case of SIGILL and floating-point 263: * simulation. 264: */ 265: #ifndef MENLO_JCL 266: if (((int)u.u_signal[i] &~ (int)SIG_IGN) && !(u.u_procp->p_flag & STRC)) 267: sendsig(u.u_signal[i]); 268: else 269: psignal(u.u_procp, i); 270: #else MENLO_JCL 271: { 272: long sigmask = 1L << (i - 1); 273: if (!(u.u_procp->p_ignsig & sigmask) && (u.u_signal[i] != SIG_DFL) 274: && !(u.u_procp->p_flag & STRC)) 275: sendsig(u.u_signal[i]); 276: else 277: psignal(u.u_procp, i); 278: } 279: #endif MENLO_JCL 280: 281: out: 282: #ifndef MENLO_JCL 283: if(issig()) 284: #else 285: if(u.u_procp->p_cursig || ISSIG(u.u_procp)) 286: #endif 287: psig(); 288: curpri = setpri(u.u_procp); 289: if (runrun) 290: qswtch(); 291: if(u.u_prof.pr_scale) 292: addupc((caddr_t) pc, &u.u_prof, (int) (u.u_stime - syst)); 293: #ifndef NONFP 294: if (u.u_fpsaved) 295: restfp(&u.u_fps); 296: #endif 297: } 298: 299: /* 300: * Called from mch.s when a system call occurs. 301: * Dummy[13] (and dummy2 if MENLO_KOV is defined) are 302: * necessitated by the values of the R[0-7] ... constants 303: * in sys/reg.h (which, in turn, are defined by trap's 304: * stack frame). 305: */ 306: /*ARGSUSED*/ 307: #ifdef MENLO_KOV 308: syscall(dummy1, sp, r1, dummy2, dummy3, r0, pc, ps) 309: #else 310: syscall(dummy1, sp, r1, dummy3, r0, pc, ps) 311: #endif 312: int *pc; 313: { 314: register i; 315: register int *a; 316: register struct sysent *callp; 317: int (*fetch)(), fuword(), fuiword(); 318: time_t syst; 319: #ifdef MENLO_JCL 320: int *opc; /* save original pc in case we must restart syscall */ 321: #endif 322: 323: if (!USERMODE(ps)) 324: panic("syscall"); 325: syst = u.u_stime; 326: #ifndef NONFP 327: u.u_fpsaved = 0; 328: #endif 329: u.u_ar0 = &r0; 330: #ifdef UCB_METER 331: cnt.v_syscall++; 332: #endif 333: u.u_error = 0; 334: #ifdef MENLO_JCL 335: opc = pc - 1; /* opc now points at syscall */ 336: i = fuiword((caddr_t) opc); 337: callp = &sysent[i & 077]; 338: if (i & 0200) { /* are argument(s) on stack ? */ 339: a = sp; 340: fetch = fuword; 341: } else 342: #endif 343: { 344: a = pc; 345: fetch = fuiword; 346: #ifndef MENLO_JCL 347: callp = &sysent[fuiword((caddr_t) (a - 1)) & 077]; 348: #endif 349: pc += callp->sy_narg - callp->sy_nrarg; 350: } 351: if (callp == &sysent[SYSINDIR]) { /* indirect */ 352: a = (int *) (*fetch)((caddr_t) (a)); 353: i = fuword((caddr_t) a); 354: a++; 355: if ((i & ~077) != SYS) 356: i = 077; /* illegal */ 357: callp = &sysent[i & 077]; 358: fetch = fuword; 359: } else 360: if (callp == &sysent[SYSLOCAL]) { /* local */ 361: a = (int *) (*fetch)((caddr_t) (a)); 362: i = fuword((caddr_t) a); 363: a++; 364: if (((i & ~077) != SYS) || ((i &= 077) > nlocalsys)) 365: i = 0; /* illegal */ 366: callp = &syslocal[i]; 367: fetch = fuword; 368: } 369: for (i = 0; i < callp->sy_nrarg; i++) 370: u.u_arg[i] = u.u_ar0[regloc[i]]; 371: for(; i < callp->sy_narg; i++) 372: u.u_arg[i] = (*fetch)((caddr_t)a++); 373: u.u_dirp = (caddr_t) u.u_arg[0]; 374: u.u_r.r_val1 = u.u_ar0[R0]; 375: u.u_r.r_val2 = u.u_ar0[R1]; 376: u.u_ap = u.u_arg; 377: #ifndef MENLO_JCL 378: if (save(u.u_qsav)) { 379: if (u.u_error==0) 380: u.u_error = EINTR; 381: } else { 382: (*callp->sy_call)(); 383: #if defined(DIAGNOSTIC) && !defined(NOKA5) 384: if(hasmap != (struct buf *) NULL) 385: panic("hasmap"); 386: #endif 387: } 388: #else MENLO_JCL 389: if (save(u.u_qsav)) { 390: if (u.u_error == 0 && u.u_eosys == JUSTRETURN) 391: u.u_error = EINTR; 392: } else { 393: u.u_eosys = JUSTRETURN; 394: (*callp->sy_call)(); 395: #if defined(DIAGNOSTIC) && !defined(NOKA5) 396: if(hasmap != (struct buf *) NULL) 397: panic("hasmap"); 398: #endif 399: } 400: if (u.u_eosys == RESTARTSYS) 401: pc = opc; /* back up pc to restart syscall */ 402: else if (u.u_eosys == SIMULATERTI) 403: dorti(fuiword((caddr_t)opc) & 0200 ? 404: callp->sy_narg - callp->sy_nrarg : 0); 405: else 406: #endif MENLO_JCL 407: if (u.u_error) { 408: ps |= PS_C; 409: u.u_ar0[R0] = u.u_error; 410: } else { 411: ps &= ~PS_C; 412: u.u_ar0[R0] = u.u_r.r_val1; 413: u.u_ar0[R1] = u.u_r.r_val2; 414: } 415: #ifndef MENLO_JCL 416: if(issig()) 417: #else 418: if(u.u_procp->p_cursig || ISSIG(u.u_procp)) 419: #endif 420: psig(); 421: curpri = setpri(u.u_procp); 422: if (runrun) 423: qswtch(); 424: if(u.u_prof.pr_scale) 425: addupc((caddr_t)pc, &u.u_prof, (int)(u.u_stime - syst)); 426: #ifndef NONFP 427: if (u.u_fpsaved) 428: restfp(&u.u_fps); 429: #endif 430: } 431: 432: /* 433: * nonexistent system call-- set fatal error code. 434: */ 435: nosys() 436: { 437: u.u_error = EINVAL; 438: }