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