|
|
1.1 ! root 1: /* trap.c 4.10 84/02/09 */ ! 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 "../h/proc.h" ! 12: #include "../h/seg.h" ! 13: #include "../machine/trap.h" ! 14: #include "../h/acct.h" ! 15: #include "../h/kernel.h" ! 16: #include "../machine/mtpr.h" ! 17: #ifdef SYSCALLTRACE ! 18: #include "../sys/syscalls.c" ! 19: #endif ! 20: #include "../machine/fp_in_krnl.h" ! 21: ! 22: #define USER 040 /* user-mode flag added to type */ ! 23: ! 24: struct sysent sysent[]; ! 25: int nsysent; ! 26: ! 27: /* ! 28: * Called from the trap handler when a processor trap occurs. ! 29: */ ! 30: trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl) ! 31: unsigned code; ! 32: { ! 33: /* Next 2 dummy variables MUST BE the first local */ ! 34: /* variables; leaving place for registers 0 and 1 */ ! 35: /* which are not preserved by the 'cct' */ ! 36: ! 37: int dumm1; /* register 1 */ ! 38: int dumm0; /* register 0 */ ! 39: register dumm3; /* register 12 is the 1'st register variable */ ! 40: /* in TAHOE (register 11 in VAX) */ ! 41: ! 42: register int *locr0 = ((int *)&psl)-PS; ! 43: register int i; ! 44: register struct proc *p; ! 45: struct timeval syst; ! 46: char *typename; ! 47: ! 48: syst = u.u_ru.ru_stime; ! 49: if (USERMODE(locr0[PS])) { ! 50: type |= USER; ! 51: u.u_ar0 = locr0; ! 52: } ! 53: switch (type) { ! 54: ! 55: default: switch (type) { ! 56: case T_RESADFLT: ! 57: typename = "reserved addressing mode";break; ! 58: case T_PRIVINFLT: ! 59: typename = "illegal opcode";break; ! 60: case T_RESOPFLT: ! 61: typename = "reserved operand";break; ! 62: case T_BPTFLT: ! 63: typename = "breakpoint";break; ! 64: case T_SYSCALL: ! 65: typename = "kernel call";break; ! 66: case T_ARITHTRAP: ! 67: typename = "arithmetic exception";break; ! 68: case T_ASTFLT: ! 69: typename = "system forced exception";break; ! 70: case T_SEGFLT: ! 71: typename = "limit fault";break; ! 72: case T_PROTFLT: ! 73: typename = "illegal access type";break; ! 74: case T_TRCTRAP: ! 75: typename = "trace trap";break; ! 76: case T_PAGEFLT: ! 77: typename = "page fault";break; ! 78: case T_TABLEFLT: ! 79: typename = "page table fault";break; ! 80: case T_ALIGNFLT: ! 81: typename = "alignment fault";break; ! 82: case T_KSPNOTVAL: ! 83: typename = "kernel stack not valid";break; ! 84: } ! 85: printf("System trap (%s), code = %x, pc = %x\n", ! 86: typename, code, pc); ! 87: panic("trap"); ! 88: ! 89: case T_PROTFLT + USER: /* protection fault */ ! 90: i = SIGBUS; ! 91: break; ! 92: ! 93: case T_PRIVINFLT + USER: /* privileged instruction fault */ ! 94: case T_RESADFLT + USER: /* reserved addressing fault */ ! 95: case T_RESOPFLT + USER: /* resereved operand fault */ ! 96: case T_ALIGNFLT + USER: /* unaligned data fault */ ! 97: u.u_code = type &~ USER; ! 98: i = SIGILL; ! 99: break; ! 100: ! 101: case T_ASTFLT + USER: /* Allow process switch */ ! 102: case T_ASTFLT: ! 103: astoff(); ! 104: if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) { ! 105: addupc(pc, &u.u_prof, 1); ! 106: u.u_procp->p_flag &= ~SOWEUPC; ! 107: } ! 108: goto out; ! 109: ! 110: case T_ARITHTRAP + USER: ! 111: u.u_code = code; ! 112: i = SIGFPE; ! 113: break; ! 114: ! 115: /* ! 116: * If the user SP is above the stack segment, ! 117: * grow the stack automatically. ! 118: */ ! 119: case T_SEGFLT + USER: ! 120: if (grow((unsigned)locr0[SP]) || grow(code)) ! 121: goto out; ! 122: i = SIGSEGV; ! 123: break; ! 124: ! 125: case T_TABLEFLT: /* allow page table faults in kernel mode */ ! 126: case T_TABLEFLT + USER: /* page table fault */ ! 127: panic("ptable fault"); ! 128: ! 129: case T_PAGEFLT: /* allow page faults in kernel mode */ ! 130: case T_PAGEFLT + USER: /* page fault */ ! 131: i = u.u_error; ! 132: pagein(code, 0); ! 133: u.u_error = i; ! 134: if (type == T_PAGEFLT) ! 135: return; ! 136: goto out; ! 137: ! 138: case T_BPTFLT + USER: /* bpt instruction fault */ ! 139: case T_TRCTRAP + USER: /* trace trap */ ! 140: locr0[PS] &= ~PSL_T; ! 141: i = SIGTRAP; ! 142: break; ! 143: case T_KSPNOTVAL: ! 144: case T_KSPNOTVAL + USER: ! 145: i = SIGKILL; /* There is nothing to do but to kill the ! 146: * process.. */ ! 147: printf("KSP NOT VALID.\n"); ! 148: break; ! 149: ! 150: } ! 151: psignal(u.u_procp, i); ! 152: out: ! 153: p = u.u_procp; ! 154: if (p->p_cursig || ISSIG(p)) ! 155: psig(); ! 156: p->p_pri = p->p_usrpri; ! 157: if (runrun) { ! 158: /* ! 159: * Since we are u.u_procp, clock will normally just change ! 160: * our priority without moving us from one queue to another ! 161: * (since the running process is not on a queue.) ! 162: * If that happened after we setrq ourselves but before we ! 163: * swtch()'ed, we might not be on the queue indicated by ! 164: * our priority. ! 165: */ ! 166: (void) spl8(); ! 167: setrq(p); ! 168: u.u_ru.ru_nivcsw++; ! 169: swtch(); ! 170: } ! 171: if (u.u_prof.pr_scale) { ! 172: int ticks; ! 173: struct timeval *tv = &u.u_ru.ru_stime; ! 174: ! 175: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 176: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 177: if (ticks) ! 178: addupc(locr0[PC], &u.u_prof, ticks); ! 179: } ! 180: curpri = p->p_pri; ! 181: } ! 182: ! 183: #ifdef SYSCALLTRACE ! 184: int syscalltrace = 0; ! 185: #endif ! 186: ! 187: /* ! 188: * Called from the trap handler when a system call occurs ! 189: */ ! 190: syscall(sp, type, hfs, accmst, acclst, dbl, code, pc, psl) ! 191: unsigned code; ! 192: { ! 193: /* Next 2 dummy variables MUST BE the first local */ ! 194: /* variables; leaving place for registers 0 and 1 */ ! 195: /* which are not preserved by the 'cct' */ ! 196: ! 197: int dumm1; /* register 1 */ ! 198: int dumm0; /* register 0 */ ! 199: register dumm3; /* register 12 is the 1'st register variable */ ! 200: /* in TAHOE (register 11 in VAX) */ ! 201: ! 202: register int *locr0 = ((int *)&psl)-PS; ! 203: register caddr_t params; /* known to be r10 below */ ! 204: register int i; /* known to be r9 below */ ! 205: register struct sysent *callp; ! 206: register struct proc *p; ! 207: struct timeval syst; ! 208: int opc; ! 209: ! 210: syst = u.u_ru.ru_stime; ! 211: if (!USERMODE(locr0[PS])) ! 212: panic("syscall"); ! 213: u.u_ar0 = locr0; ! 214: if (code == 139) { /* XXX */ ! 215: sigcleanup(); /* XXX */ ! 216: goto done; /* XXX */ ! 217: } ! 218: params = (caddr_t)locr0[FP] + NBPW; ! 219: u.u_error = 0; ! 220: /*------ DIRTY CODE !!!!!!!!!---------*/ ! 221: /* try to reconstruct pc, assuming code is an immediate constant */ ! 222: opc = pc - 2; /* short literal */ ! 223: if (code > 0x3f) { ! 224: opc--; /* byte immediate */ ! 225: if (code > 0x7f) { ! 226: opc--; /* word immediate */ ! 227: if (code > 0x7fff) ! 228: opc -= 2; /* long immediate */ ! 229: } ! 230: } ! 231: /*------------------------------------*/ ! 232: callp = (code >= nsysent) ? &sysent[63] : &sysent[code]; ! 233: if (callp == sysent) { ! 234: i = fuword(params); ! 235: params += NBPW; ! 236: callp = (code >= nsysent) ? &sysent[63] : &sysent[code]; ! 237: } ! 238: if (i = callp->sy_narg * sizeof (int)) { ! 239: asm("prober $1,(r10),r9"); /* GROT */ ! 240: asm("bnequ ok"); /* GROT */ ! 241: u.u_error = EFAULT; /* GROT */ ! 242: goto bad; /* GROT */ ! 243: asm("ok:"); /* GROT */ ! 244: bcopy(params,u.u_arg,i); ! 245: } ! 246: u.u_ap = u.u_arg; ! 247: u.u_dirp = (caddr_t)u.u_arg[0]; ! 248: u.u_r.r_val1 = 0; ! 249: u.u_r.r_val2 = locr0[R1]; /*------------ CHECK again */ ! 250: if (setjmp(&u.u_qsave)) { ! 251: if (u.u_error == 0 && u.u_eosys == JUSTRETURN) ! 252: u.u_error = EINTR; ! 253: } else { ! 254: u.u_eosys = JUSTRETURN; ! 255: #ifdef SYSCALLTRACE ! 256: if (syscalltrace) { ! 257: register int i; ! 258: char *cp; ! 259: ! 260: if (code >= nsysent) ! 261: printf("0x%x", code); ! 262: else ! 263: printf("%s", syscallnames[code]); ! 264: cp = "("; ! 265: for (i= 0; i < callp->sy_narg; i++) { ! 266: printf("%s%x", cp, u.u_arg[i]); ! 267: cp = ", "; ! 268: } ! 269: if (i) ! 270: putchar(')', 0); ! 271: putchar('\n', 0); ! 272: } ! 273: #endif ! 274: ! 275: (*(callp->sy_call))(); ! 276: } ! 277: if (u.u_eosys == RESTARTSYS) ! 278: pc = opc; ! 279: else if (u.u_error) { ! 280: bad: ! 281: locr0[R0] = u.u_error; ! 282: locr0[PS] |= PSL_C; /* carry bit */ ! 283: } else { ! 284: locr0[PS] &= ~PSL_C; /* clear carry bit */ ! 285: locr0[R0] = u.u_r.r_val1; ! 286: locr0[R1] = u.u_r.r_val2; ! 287: } ! 288: done: ! 289: p = u.u_procp; ! 290: if (p->p_cursig || ISSIG(p)) ! 291: psig(); ! 292: p->p_pri = p->p_usrpri; ! 293: if (runrun) { ! 294: /* ! 295: * Since we are u.u_procp, clock will normally just change ! 296: * our priority without moving us from one queue to another ! 297: * (since the running process is not on a queue.) ! 298: * If that happened after we setrq ourselves but before we ! 299: * swtch()'ed, we might not be on the queue indicated by ! 300: * our priority. ! 301: */ ! 302: (void) spl8(); ! 303: setrq(p); ! 304: u.u_ru.ru_nivcsw++; ! 305: swtch(); ! 306: } ! 307: if (u.u_prof.pr_scale) { ! 308: int ticks; ! 309: struct timeval *tv = &u.u_ru.ru_stime; ! 310: ! 311: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 312: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 313: if (ticks) ! 314: addupc(locr0[PC], &u.u_prof, ticks); ! 315: } ! 316: curpri = p->p_pri; ! 317: } ! 318: ! 319: /* ! 320: * nonexistent system call-- signal process (may want to handle it) ! 321: * flag error if process won't see signal immediately ! 322: * Q: should we do that all the time ?? ! 323: */ ! 324: nosys() ! 325: { ! 326: if (u.u_signal[SIGSYS] == SIG_IGN || u.u_signal[SIGSYS] == SIG_HOLD) ! 327: u.u_error = EINVAL; ! 328: psignal(u.u_procp, SIGSYS); ! 329: } ! 330: ! 331: /* ! 332: * Ignored system call ! 333: */ ! 334: nullsys() ! 335: { ! 336: ! 337: } ! 338: ! 339: fpemulate(hfsreg,acc_most,acc_least,dbl,op_most,op_least,opcode,pc,psl) ! 340: { ! 341: /* ! 342: * Emulate the F.P. 'opcode'. Update psl flags as necessary. ! 343: * If all OK, set 'opcode' to 0, else to the F.P. exception #. ! 344: * Not all parameter longwords are relevant - depends on opcode. ! 345: * ! 346: * The entry mask is set so ALL registers are saved - courtesy of ! 347: * locore.s. This enables F.P. opcodes to change 'user' registers ! 348: * before return. ! 349: */ ! 350: ! 351: /* WARNING!!!! THIS CODE MUST NOT PRODUCE ANY FLOATING POINT EXCEPTIONS. */ ! 352: ! 353: /* Next 2 dummy variables MUST BE the first local */ ! 354: /* variables; leaving place for registers 0 and 1 */ ! 355: /* which are not preserved by the 'cct' */ ! 356: ! 357: int dumm1; /* register 1 */ ! 358: int dumm0; /* register 0 */ ! 359: register dumm3; /* register 12 is the 1'st register variable */ ! 360: /* in TAHOE (register 11 in VAX) */ ! 361: ! 362: register int *locr0 = ((int *)&psl)-PS; /* R11 */ ! 363: int hfs = 0; /* returned data about exceptions */ ! 364: float (*f_proc)(); /* fp procedure to be called. */ ! 365: double (*d_proc)(); /* fp procedure to be called. */ ! 366: int dest_type; /* float or double. */ ! 367: union{ ! 368: float ff; /* float result. */ ! 369: int fi; ! 370: }f_res; ! 371: union{ ! 372: double dd; /* double result. */ ! 373: int di[2] ; ! 374: }d_res; ! 375: extern float Kcvtlf(), Kaddf(), Ksubf(), Kmulf(), Kdivf(); ! 376: extern double Kcvtld(), Kaddd(), Ksubd(), Kmuld(), Kdivd(); ! 377: extern float Ksinf(), Kcosf(), Katanf(), Klogf(), Ksqrtf(), Kexpf(); ! 378: ! 379: ! 380: ! 381: switch(opcode & 0x0FF){ ! 382: ! 383: case CVLF: f_proc = Kcvtlf; dest_type = FLOAT; ! 384: locr0[PS] &= ~PSL_DBL; ! 385: dbl &= ~1;break; /* clear double bit */ ! 386: case CVLD: d_proc = Kcvtld; dest_type = DOUBLE; ! 387: locr0[PS] |= PSL_DBL; ! 388: dbl |= 1; break; /* turn on double bit */ ! 389: case ADDF: f_proc = Kaddf; dest_type = FLOAT; ! 390: break; ! 391: case ADDD: d_proc = Kaddd; dest_type = DOUBLE; ! 392: break; ! 393: case SUBF: f_proc = Ksubf; dest_type = FLOAT; ! 394: break; ! 395: case SUBD: d_proc = Ksubd; dest_type = DOUBLE; ! 396: break; ! 397: case MULF: f_proc = Kmulf; dest_type = FLOAT; ! 398: break; ! 399: case MULD: d_proc = Kmuld; dest_type = DOUBLE; ! 400: break; ! 401: case DIVF: f_proc = Kdivf; dest_type = FLOAT; ! 402: break; ! 403: case DIVD: d_proc = Kdivd; dest_type = DOUBLE; ! 404: break; ! 405: case SINF: f_proc = Ksinf; dest_type = FLOAT; ! 406: break; ! 407: case COSF: f_proc = Kcosf; dest_type = FLOAT; ! 408: break; ! 409: case ATANF: f_proc = Katanf; dest_type = FLOAT; ! 410: break; ! 411: case LOGF: f_proc = Klogf; dest_type = FLOAT; ! 412: break; ! 413: case SQRTF: f_proc = Ksqrtf; dest_type = FLOAT; ! 414: break; ! 415: case EXPF: f_proc = Kexpf; dest_type = FLOAT; ! 416: break; ! 417: } ! 418: ! 419: switch(dest_type){ ! 420: ! 421: case FLOAT: ! 422: f_res.ff = (*f_proc)(acc_most,acc_least,op_most,op_least,&hfs); ! 423: ! 424: if (f_res.fi == 0 ) locr0[PS] |= PSL_Z; ! 425: if (f_res.fi < 0 ) locr0[PS] |= PSL_N; ! 426: break; ! 427: case DOUBLE: ! 428: d_res.dd = (*d_proc)(acc_most,acc_least,op_most,op_least,&hfs); ! 429: if ((d_res.di[0] == 0) && (d_res.di[1] == 0)) ! 430: locr0[PS] |= PSL_Z; ! 431: if (d_res.di[0] < 0 ) locr0[PS] |= PSL_N; ! 432: break; ! 433: } ! 434: ! 435: if (hfs & HFS_OVF){ ! 436: locr0[PS] |= PSL_V; /* turn on overflow bit */ ! 437: /* if (locr0[PS] & PSL_IV) { /* overflow elabled? */ ! 438: opcode = OVF_EXC; ! 439: u.u_error = (hfs & HFS_DOM) ? EDOM : ERANGE; ! 440: return; ! 441: /*}*/ ! 442: } ! 443: else if (hfs & HFS_UNDF){ ! 444: if (locr0[PS] & PSL_FU){ /* underflow elabled? */ ! 445: opcode = UNDF_EXC; ! 446: u.u_error = (hfs & HFS_DOM) ? EDOM : ERANGE; ! 447: return; ! 448: } ! 449: } ! 450: else if (hfs & HFS_DIVZ){ ! 451: opcode = DIV0_EXC; ! 452: return; ! 453: } ! 454: else if (hfs & HFS_DOM) ! 455: u.u_error = EDOM; ! 456: else if (hfs & HFS_RANGE) ! 457: u.u_error = ERANGE; ! 458: ! 459: switch(dest_type){ ! 460: case FLOAT: ! 461: if ((hfs & HFS_OVF) || (hfs & HFS_UNDF)) { ! 462: f_res.ff = 0.0; ! 463: locr0[PS] |= PSL_Z; ! 464: } ! 465: mvtofacc(f_res.ff, &acc_most); ! 466: break; ! 467: case DOUBLE: ! 468: if ((hfs & HFS_OVF) || (hfs & HFS_UNDF)) { ! 469: d_res.dd = 0.0; ! 470: locr0[PS] |= PSL_Z; ! 471: } ! 472: mvtodacc(d_res.di[0], d_res.di[1], &acc_most); ! 473: break; ! 474: } ! 475: opcode=0; ! 476: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.