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

Defined functions

nosys defined in line 435; used 42 times
syscall defined in line 308; used 2 times
trap defined in line 60; never used

Defined variables

kernelmap defined in line 30; used 2 times
once_thru defined in line 38; used 2 times
regloc defined in line 44; used 7 times
savhasmap defined in line 28; used 1 times

Defined macros

SETD defined in line 19; used 1 times
SYS defined in line 20; used 2 times
USER defined in line 21; used 3 times
Last modified: 1983-09-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 49
Valid CSS Valid XHTML 1.0 Strict