|
|
1.1 ! root 1: /* trap.c 6.1 83/08/18 */ ! 2: ! 3: #include "../machine/psl.h" ! 4: #include "../machine/reg.h" ! 5: #include "../machine/pte.h" ! 6: ! 7: #include "../h/param.h" ! 8: #include "../h/systm.h" ! 9: #include "../h/dir.h" ! 10: #include "../h/user.h" ! 11: #include "assym.s" ! 12: #include "../h/proc.h" ! 13: #include "../h/seg.h" ! 14: #include "../vax/trap.h" ! 15: #include "../h/acct.h" ! 16: #include "../h/kernel.h" ! 17: #ifdef SYSCALLTRACE ! 18: #include "../sys/syscalls.c" ! 19: #endif ! 20: ! 21: #include "../vax/mtpr.h" ! 22: ! 23: #define USER 040 /* user-mode flag added to type */ ! 24: ! 25: struct sysent sysent[]; ! 26: int nsysent; ! 27: ! 28: char *trap_type[] = { ! 29: "Reserved addressing mode", ! 30: "Privileged instruction", ! 31: "Reserved operand", ! 32: "Breakpoint", ! 33: "Xfc trap", ! 34: "Syscall trap", ! 35: "Arithmetic fault", ! 36: "Ast trap", ! 37: "Segmentation fault", ! 38: "Protection fault", ! 39: "Trace trap", ! 40: "Compatibility mode trap", ! 41: #ifdef notdef ! 42: "Page fault", ! 43: "Page table fault", ! 44: #endif ! 45: }; ! 46: #define TRAP_TYPES (sizeof trap_type / sizeof trap_type[0]) ! 47: ! 48: /* ! 49: * Called from the trap handler when a processor trap occurs. ! 50: */ ! 51: /*ARGSUSED*/ ! 52: trap(sp, type, code, pc, psl) ! 53: int sp, type; ! 54: unsigned code; ! 55: int pc, psl; ! 56: { ! 57: register int *locr0 = ((int *)&psl)-PS; ! 58: register int i; ! 59: register struct proc *p; ! 60: struct timeval syst; ! 61: ! 62: syst = u.u_ru.ru_stime; ! 63: if (USERMODE(locr0[PS])) { ! 64: type |= USER; ! 65: u.u_ar0 = locr0; ! 66: } ! 67: switch (type) { ! 68: ! 69: default: ! 70: printf("trap type %d, code = %x, pc = %x\n", type, code, pc); ! 71: type &= ~USER; ! 72: if ((unsigned)type < TRAP_TYPES) ! 73: panic(trap_type[type]); ! 74: panic("trap"); ! 75: ! 76: case T_PROTFLT+USER: /* protection fault */ ! 77: i = SIGBUS; ! 78: break; ! 79: ! 80: case T_PRIVINFLT+USER: /* privileged instruction fault */ ! 81: case T_RESADFLT+USER: /* reserved addressing fault */ ! 82: case T_RESOPFLT+USER: /* resereved operand fault */ ! 83: u.u_code = type &~ USER; ! 84: i = SIGILL; ! 85: break; ! 86: ! 87: case T_ASTFLT+USER: ! 88: astoff(); ! 89: if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) { ! 90: addupc(pc, &u.u_prof, 1); ! 91: u.u_procp->p_flag &= ~SOWEUPC; ! 92: } ! 93: goto out; ! 94: ! 95: case T_ARITHTRAP+USER: ! 96: u.u_code = code; ! 97: i = SIGFPE; ! 98: break; ! 99: ! 100: /* ! 101: * If the user SP is above the stack segment, ! 102: * grow the stack automatically. ! 103: */ ! 104: case T_SEGFLT+USER: ! 105: if (grow((unsigned)locr0[SP]) || grow(code)) ! 106: goto out; ! 107: i = SIGSEGV; ! 108: break; ! 109: ! 110: case T_TABLEFLT: /* allow page table faults in kernel mode */ ! 111: case T_TABLEFLT+USER: /* page table fault */ ! 112: panic("ptable fault"); ! 113: ! 114: case T_PAGEFLT: /* allow page faults in kernel mode */ ! 115: case T_PAGEFLT+USER: /* page fault */ ! 116: i = u.u_error; ! 117: pagein(code, 0); ! 118: u.u_error = i; ! 119: if (type == T_PAGEFLT) ! 120: return; ! 121: goto out; ! 122: ! 123: case T_BPTFLT+USER: /* bpt instruction fault */ ! 124: case T_TRCTRAP+USER: /* trace trap */ ! 125: locr0[PS] &= ~PSL_T; ! 126: i = SIGTRAP; ! 127: break; ! 128: ! 129: case T_XFCFLT+USER: /* xfc instruction fault */ ! 130: i = SIGEMT; ! 131: break; ! 132: ! 133: case T_COMPATFLT+USER: /* compatibility mode fault */ ! 134: u.u_acflag |= ACOMPAT; ! 135: u.u_code = code; ! 136: i = SIGILL; ! 137: break; ! 138: } ! 139: psignal(u.u_procp, i); ! 140: out: ! 141: p = u.u_procp; ! 142: if (p->p_cursig || ISSIG(p)) ! 143: psig(); ! 144: p->p_pri = p->p_usrpri; ! 145: if (runrun) { ! 146: /* ! 147: * Since we are u.u_procp, clock will normally just change ! 148: * our priority without moving us from one queue to another ! 149: * (since the running process is not on a queue.) ! 150: * If that happened after we setrq ourselves but before we ! 151: * swtch()'ed, we might not be on the queue indicated by ! 152: * our priority. ! 153: */ ! 154: (void) spl6(); ! 155: setrq(p); ! 156: u.u_ru.ru_nivcsw++; ! 157: swtch(); ! 158: } ! 159: if (u.u_prof.pr_scale) { ! 160: int ticks; ! 161: struct timeval *tv = &u.u_ru.ru_stime; ! 162: ! 163: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 164: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 165: if (ticks) ! 166: addupc(locr0[PC], &u.u_prof, ticks); ! 167: } ! 168: curpri = p->p_pri; ! 169: } ! 170: ! 171: #ifdef SYSCALLTRACE ! 172: int syscalltrace = 0; ! 173: #endif ! 174: /* ! 175: * Called from the trap handler when a system call occurs ! 176: */ ! 177: /*ARGSUSED*/ ! 178: syscall(sp, type, code, pc, psl) ! 179: unsigned code; ! 180: { ! 181: register int *locr0 = ((int *)&psl)-PS; ! 182: register caddr_t params; /* known to be r10 below */ ! 183: register int i; /* known to be r9 below */ ! 184: register struct sysent *callp; ! 185: register struct proc *p; ! 186: int opc; ! 187: struct timeval syst; ! 188: ! 189: syst = u.u_ru.ru_stime; ! 190: if (!USERMODE(locr0[PS])) ! 191: panic("syscall"); ! 192: u.u_ar0 = locr0; ! 193: if (code == 139) { /* XXX */ ! 194: sigcleanup(); /* XXX */ ! 195: goto done; /* XXX */ ! 196: } ! 197: params = (caddr_t)locr0[AP] + NBPW; ! 198: u.u_error = 0; ! 199: opc = pc - 2; ! 200: if (code > 63) ! 201: opc -= 2; ! 202: callp = (code >= nsysent) ? &sysent[63] : &sysent[code]; ! 203: if (callp == sysent) { ! 204: i = fuword(params); ! 205: params += NBPW; ! 206: callp = ((unsigned)i >= nsysent) ? &sysent[63] : &sysent[i]; ! 207: } ! 208: if (i = callp->sy_narg * sizeof (int)) { ! 209: #ifndef lint ! 210: asm("prober $3,r9,(r10)"); /* GROT */ ! 211: asm("bnequ ok"); /* GROT */ ! 212: u.u_error = EFAULT; /* GROT */ ! 213: goto bad; /* GROT */ ! 214: asm("ok:"); /* GROT */ ! 215: asm("movc3 r9,(r10),_u+U_ARG"); /* GROT */ ! 216: #else ! 217: bcopy(params, (caddr_t)u.u_arg, (u_int)i); ! 218: #endif ! 219: } ! 220: u.u_ap = u.u_arg; ! 221: u.u_dirp = (caddr_t)u.u_arg[0]; ! 222: u.u_r.r_val1 = 0; ! 223: u.u_r.r_val2 = locr0[R1]; ! 224: if (setjmp(&u.u_qsave)) { ! 225: if (u.u_error == 0 && u.u_eosys == JUSTRETURN) ! 226: u.u_error = EINTR; ! 227: } else { ! 228: u.u_eosys = JUSTRETURN; ! 229: #ifdef SYSCALLTRACE ! 230: if (syscalltrace) { ! 231: register int i; ! 232: char *cp; ! 233: ! 234: if (code >= nsysent) ! 235: printf("0x%x", code); ! 236: else ! 237: printf("%s", syscallnames[code]); ! 238: cp = "("; ! 239: for (i= 0; i < callp->sy_narg; i++) { ! 240: printf("%s%x", cp, u.u_arg[i]); ! 241: cp = ", "; ! 242: } ! 243: if (i) ! 244: putchar(')', 0); ! 245: putchar('\n', 0); ! 246: } ! 247: #endif ! 248: (*(callp->sy_call))(); ! 249: } ! 250: locr0[PS] &= ~PSL_C; ! 251: if (u.u_eosys == RESTARTSYS) ! 252: pc = opc; ! 253: #ifdef notdef ! 254: else if (u.u_eosys == SIMULATERTI) ! 255: dorti(); ! 256: #endif ! 257: else if (u.u_error) { ! 258: #ifndef lint ! 259: bad: ! 260: #endif ! 261: locr0[R0] = u.u_error; ! 262: locr0[PS] |= PSL_C; /* carry bit */ ! 263: } else { ! 264: locr0[R0] = u.u_r.r_val1; ! 265: locr0[R1] = u.u_r.r_val2; ! 266: } ! 267: done: ! 268: p = u.u_procp; ! 269: if (p->p_cursig || ISSIG(p)) ! 270: psig(); ! 271: p->p_pri = p->p_usrpri; ! 272: if (runrun) { ! 273: /* ! 274: * Since we are u.u_procp, clock will normally just change ! 275: * our priority without moving us from one queue to another ! 276: * (since the running process is not on a queue.) ! 277: * If that happened after we setrq ourselves but before we ! 278: * swtch()'ed, we might not be on the queue indicated by ! 279: * our priority. ! 280: */ ! 281: (void) spl6(); ! 282: setrq(p); ! 283: u.u_ru.ru_nivcsw++; ! 284: swtch(); ! 285: } ! 286: if (u.u_prof.pr_scale) { ! 287: int ticks; ! 288: struct timeval *tv = &u.u_ru.ru_stime; ! 289: ! 290: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 291: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 292: if (ticks) ! 293: addupc(locr0[PC], &u.u_prof, ticks); ! 294: } ! 295: curpri = p->p_pri; ! 296: } ! 297: ! 298: /* ! 299: * nonexistent system call-- signal process (may want to handle it) ! 300: * flag error if process won't see signal immediately ! 301: * Q: should we do that all the time ?? ! 302: */ ! 303: nosys() ! 304: { ! 305: if (u.u_signal[SIGSYS] == SIG_IGN || u.u_signal[SIGSYS] == SIG_HOLD) ! 306: u.u_error = EINVAL; ! 307: psignal(u.u_procp, SIGSYS); ! 308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.