From c0648e43a5fc3f7fdfa4a4c69acccf6a17aecbe6 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Fri, 8 Jun 1979 15:44:40 -0500 Subject: [PATCH] Research V7 development Work on file usr/sys/sys/trap.c Synthesized-from: v7 --- usr/sys/sys/trap.c | 251 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 usr/sys/sys/trap.c diff --git a/usr/sys/sys/trap.c b/usr/sys/sys/trap.c new file mode 100644 index 0000000000..b29229d5d7 --- /dev/null +++ b/usr/sys/sys/trap.c @@ -0,0 +1,251 @@ +#include "../h/param.h" +#include "../h/systm.h" +#include "../h/dir.h" +#include "../h/user.h" +#include "../h/proc.h" +#include "../h/reg.h" +#include "../h/seg.h" + +#define EBIT 1 /* user error bit in PS: C-bit */ +#define SETD 0170011 /* SETD instruction */ +#define SYS 0104400 /* sys (trap) instruction */ +#define USER 020 /* user-mode flag added to dev */ +#define MEMORY ((physadr)0177740) /* 11/70 "memory" subsystem */ + +/* + * Offsets of the user's registers relative to + * the saved r0. See reg.h + */ +char regloc[9] = +{ + R0, R1, R2, R3, R4, R5, R6, R7, RPS +}; + +/* + * Called from l40.s or l45.s when a processor trap occurs. + * The arguments are the words saved on the system stack + * by the hardware and software during the trap processing. + * Their order is dictated by the hardware and the details + * of C's calling sequence. They are peculiar in that + * this call is not 'by value' and changed user registers + * get copied back on return. + * dev is the kind of trap that occurred. + */ +trap(dev, sp, r1, nps, r0, pc, ps) +int *pc; +dev_t dev; +{ + register i; + register *a; + register struct sysent *callp; + int (*fetch)(); + time_t syst; + + syst = u.u_stime; + u.u_fpsaved = 0; + if ((ps&UMODE) == UMODE) + dev |= USER; + u.u_ar0 = &r0; + switch(minor(dev)) { + + /* + * Trap not expected. + * Usually a kernel mode bus error. + * The numbers printed are used to + * find the hardware PS/PC as follows. + * (all numbers in octal 18 bits) + * address_of_saved_ps = + * (ka6*0100) + aps - 0140000; + * address_of_saved_pc = + * address_of_saved_ps - 2; + */ + default: + printf("ka6 = %o\n", ka6->r[0]); + printf("aps = %o\n", &ps); + printf("pc = %o ps = %o\n", pc, ps); + printf("trap type %o\n", dev); + panic("trap"); + + case 0+USER: /* bus error */ + i = SIGBUS; + break; + + /* + * If illegal instructions are not + * being caught and the offending instruction + * is a SETD, the trap is ignored. + * This is because C produces a SETD at + * the beginning of every program which + * will trap on CPUs without 11/45 FPU. + */ + case 1+USER: /* illegal instruction */ + if(fuiword((caddr_t)(pc-1)) == SETD && u.u_signal[SIGINS] == 0) + goto out; + i = SIGINS; + break; + + case 2+USER: /* bpt or trace */ + i = SIGTRC; + ps &= ~TBIT; + break; + + case 3+USER: /* iot */ + i = SIGIOT; + break; + + case 5+USER: /* emt */ + i = SIGEMT; + break; + + case 6+USER: /* sys call */ + u.u_error = 0; + ps &= ~EBIT; + a = pc; + callp = &sysent[fuiword((caddr_t)(a-1))&077]; + if (callp == sysent) { /* indirect */ + a = (int *)fuiword((caddr_t)(a)); + pc++; + i = fuword((caddr_t)a); + a++; + if ((i & ~077) != SYS) + i = 077; /* illegal */ + callp = &sysent[i&077]; + fetch = fuword; + } else { + pc += callp->sy_narg - callp->sy_nrarg; + fetch = fuiword; + } + for (i=0; isy_nrarg; i++) + u.u_arg[i] = u.u_ar0[regloc[i]]; + for(; isy_narg; i++) + u.u_arg[i] = (*fetch)((caddr_t)a++); + u.u_dirp = (caddr_t)u.u_arg[0]; + u.u_r.r_val1 = u.u_ar0[R0]; + u.u_r.r_val2 = u.u_ar0[R1]; + u.u_ap = u.u_arg; + if (save(u.u_qsav)) { + if (u.u_error==0) + u.u_error = EINTR; + } else { + (*callp->sy_call)(); + } + if(u.u_error) { + ps |= EBIT; + u.u_ar0[R0] = u.u_error; + } else { + u.u_ar0[R0] = u.u_r.r_val1; + u.u_ar0[R1] = u.u_r.r_val2; + } + goto out; + + /* + * Since the floating exception is an + * imprecise trap, a user generated + * trap may actually come from kernel + * mode. In this case, a signal is sent + * to the current process to be picked + * up later. + */ + case 8: /* floating exception */ + stst(&u.u_fper); /* save error code */ + psignal(u.u_procp, SIGFPT); + return; + + case 8+USER: + i = SIGFPT; + stst(&u.u_fper); + break; + + /* + * If the user SP is below the stack segment, + * grow the stack automatically. + * This relies on the ability of the hardware + * to restart a half executed instruction. + * On the 11/40 this is not the case and + * the routine backup/l40.s may fail. + * The classic example is on the instruction + * cmp -(sp),-(sp) + */ + case 9+USER: /* segmentation exception */ + { + int osp; + + osp = sp; + if(backup(u.u_ar0) == 0) + if(grow((unsigned)osp)) + goto out; + i = SIGSEG; + break; + } + + /* + * The code here is a half-hearted + * attempt to do something with all + * of the 11/70 parity registers. + * In fact, there is little that + * can be done. + */ + case 10: + case 10+USER: + printf("parity\n"); + if(cputype == 70) { + for(i=0; i<4; i++) + printf("%o ", MEMORY->r[i]); + printf("\n"); + MEMORY->r[2] = -1; + if(dev & USER) { + i = SIGBUS; + break; + } + } + panic("parity"); + + /* + * Allow process switch + */ + case USER+12: + goto out; + + /* + * Locations 0-2 specify this style trap, since + * DEC hardware often generates spurious + * traps through location 0. This is a + * symptom of hardware problems and may + * represent a real interrupt that got + * sent to the wrong place. Watch out + * for hangs on disk completion if this message appears. + */ + case 15: + case 15+USER: + printf("Random interrupt ignored\n"); + return; + } + psignal(u.u_procp, i); + +out: + if(issig()) { + psig(); + } + curpri = setpri(u.u_procp); + if (runrun) + qswtch(); + if(u.u_prof.pr_scale) + addupc((caddr_t)pc, &u.u_prof, (int)(u.u_stime-syst)); + if (u.u_fpsaved) + restfp(&u.u_fps); +} + +/* + * nonexistent system call-- set fatal error code. + */ +nosys() +{ + u.u_error = EINVAL; +} + +/* + * Ignored system call + */ +nullsys() +{ +} -- 2.20.1