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