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