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: }

Defined functions

nosys defined in line 304; used 17 times
syscall defined in line 184; used 3 times
trap defined in line 58; used 3 times

Defined variables

nsysent defined in line 32; used 3 times
syscalltrace defined in line 178; used 1 times
sysent defined in line 31; used 5 times
trap_type defined in line 34; used 3 times

Defined macros

TRAP_TYPES defined in line 52; used 1 times
  • in line 78
USER defined in line 29; used 3 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1361
Valid CSS Valid XHTML 1.0 Strict