return errors from ioctl routines and internal ldisc routines
[unix-history] / usr / src / sys / vax / vax / trap.c
CommitLineData
45c48dda 1/* trap.c 4.17 82/09/12 */
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"
11#include "../h/trap.h"
12#include "../h/psl.h"
13#include "../h/pte.h"
73cde86e 14#include "../h/inline.h"
cb5eab56 15#include "../h/mtpr.h"
683ddffc 16#include "../h/acct.h"
ee1451be
BJ
17
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",
36/** these never get to "default" case
37 "Page fault",
38 "Page table fault",
39**/
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)
48unsigned code;
49{
50 register int *locr0 = ((int *)&psl)-PS;
51 register int i;
52 register struct proc *p;
ee1451be 53
ee1451be
BJ
54 if (USERMODE(locr0[PS])) {
55 type |= USER;
56 u.u_ar0 = locr0;
57 }
58 switch (type) {
59
60 default:
48575cec 61 printf("trap type %d, code = %x, pc = %x\n", type, code, pc);
683ddffc
RE
62 type &= ~USER;
63 if ((unsigned)type < TRAP_TYPES)
64 panic(trap_type[type]);
ee1451be
BJ
65 panic("trap");
66
67 case PROTFLT + USER: /* protection fault */
68 i = SIGBUS;
69 break;
70
71 case PRIVINFLT + USER: /* privileged instruction fault */
72 case RESADFLT + USER: /* reserved addressing fault */
73 case RESOPFLT + USER: /* resereved operand fault */
0d83d9c2 74 u.u_code = type &~ USER;
73cde86e 75 i = SIGILL;
ee1451be
BJ
76 break;
77
4602969d 78 case ASTFLT + USER:
cb5eab56 79 astoff();
ee1451be
BJ
80 goto out;
81
ee1451be 82 case ARITHTRAP + USER:
afb8c59e 83 u.u_code = code;
73cde86e 84 i = SIGFPE;
ee1451be
BJ
85 break;
86
87 /*
88 * If the user SP is above the stack segment,
89 * grow the stack automatically.
90 */
afb8c59e
BJ
91 case SEGFLT + USER:
92 if (grow((unsigned)locr0[SP]) || grow(code))
ee1451be 93 goto out;
73cde86e 94 i = SIGSEGV;
ee1451be
BJ
95 break;
96
97 case TABLEFLT: /* allow page table faults in kernel mode */
98 case TABLEFLT + USER: /* page table fault */
afb8c59e 99 panic("ptable fault");
ee1451be
BJ
100
101 case PAGEFLT: /* allow page faults in kernel mode */
102 case PAGEFLT + USER: /* page fault */
103 i = u.u_error;
afb8c59e 104 pagein(code);
ee1451be 105 u.u_error = i;
ee1451be 106 if (type == PAGEFLT)
ee1451be 107 return;
ee1451be 108 goto out;
ee1451be
BJ
109
110 case BPTFLT + USER: /* bpt instruction fault */
111 case TRCTRAP + USER: /* trace trap */
afb8c59e 112 locr0[PS] &= ~PSL_T;
73cde86e 113 i = SIGTRAP;
ee1451be
BJ
114 break;
115
116 case XFCFLT + USER: /* xfc instruction fault */
117 i = SIGEMT;
118 break;
119
120 case COMPATFLT + USER: /* compatibility mode fault */
683ddffc 121 u.u_acflag |= ACOMPAT;
afb8c59e 122 u.u_code = code;
73cde86e 123 i = SIGILL;
ee1451be
BJ
124 break;
125 }
126 psignal(u.u_procp, i);
127out:
128 p = u.u_procp;
73cde86e 129 if (p->p_cursig || ISSIG(p))
ee1451be
BJ
130 psig();
131 p->p_pri = p->p_usrpri;
132 if (runrun) {
133 /*
134 * Since we are u.u_procp, clock will normally just change
135 * our priority without moving us from one queue to another
136 * (since the running process is not on a queue.)
137 * If that happened after we setrq ourselves but before we
138 * swtch()'ed, we might not be on the queue indicated by
139 * our priority.
140 */
934e4ecf 141 (void) spl6();
ee1451be 142 setrq(p);
4602969d 143 u.u_ru.ru_nivcsw++;
ee1451be
BJ
144 swtch();
145 }
ee1451be
BJ
146 curpri = p->p_pri;
147}
148
ee1451be
BJ
149/*
150 * Called from the trap handler when a system call occurs
151 */
152/*ARGSUSED*/
153syscall(sp, type, code, pc, psl)
49ed6685 154 unsigned code;
ee1451be
BJ
155{
156 register int *locr0 = ((int *)&psl)-PS;
157 register caddr_t params; /* known to be r10 below */
158 register int i; /* known to be r9 below */
159 register struct sysent *callp;
160 register struct proc *p;
73cde86e 161 int opc;
ee1451be 162
ee1451be
BJ
163 if (!USERMODE(locr0[PS]))
164 panic("syscall");
165 u.u_ar0 = locr0;
166 params = (caddr_t)locr0[AP] + NBPW;
167 u.u_error = 0;
6fdc0335 168 opc = pc - 2;
73cde86e
BJ
169 if (code > 63)
170 opc -= 2;
49ed6685 171 callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
ee1451be
BJ
172 if (callp == sysent) {
173 i = fuword(params);
174 params += NBPW;
49ed6685 175 callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
ee1451be
BJ
176 }
177 if (i = callp->sy_narg * sizeof (int)) {
73cde86e
BJ
178 asm("prober $3,r9,(r10)"); /* GROT */
179 asm("bnequ ok"); /* GROT */
180 u.u_error = EFAULT; /* GROT */
181 goto bad; /* GROT */
182asm("ok:"); /* GROT */
183 asm("movc3 r9,(r10),_u+U_ARG"); /* GROT */
ee1451be
BJ
184 }
185 u.u_ap = u.u_arg;
ee1451be
BJ
186 u.u_dirp = (caddr_t)u.u_arg[0];
187 u.u_r.r_val1 = 0;
188 u.u_r.r_val2 = locr0[R1];
45c48dda 189 if (setjmp(&u.u_qsave)) {
73cde86e
BJ
190 if (u.u_error == 0 && u.u_eosys == JUSTRETURN)
191 u.u_error = EINTR;
192 } else {
193 u.u_eosys = JUSTRETURN;
194 (*(callp->sy_call))();
195 }
196 locr0[PS] &= ~PSL_C;
197 if (u.u_eosys == RESTARTSYS)
198 pc = opc;
199 else if (u.u_eosys == SIMULATERTI)
200 dorti();
201 else if (u.u_error) {
ee1451be
BJ
202bad:
203 locr0[R0] = u.u_error;
204 locr0[PS] |= PSL_C; /* carry bit */
205 } else {
206 locr0[R0] = u.u_r.r_val1;
207 locr0[R1] = u.u_r.r_val2;
208 }
209 p = u.u_procp;
73cde86e 210 if (p->p_cursig || ISSIG(p))
ee1451be
BJ
211 psig();
212 p->p_pri = p->p_usrpri;
213 if (runrun) {
214 /*
215 * Since we are u.u_procp, clock will normally just change
216 * our priority without moving us from one queue to another
217 * (since the running process is not on a queue.)
218 * If that happened after we setrq ourselves but before we
219 * swtch()'ed, we might not be on the queue indicated by
220 * our priority.
221 */
934e4ecf 222 (void) spl6();
ee1451be 223 setrq(p);
4602969d 224 u.u_ru.ru_nivcsw++;
ee1451be
BJ
225 swtch();
226 }
ee1451be
BJ
227 curpri = p->p_pri;
228}
229
230/*
683ddffc
RE
231 * nonexistent system call-- signal process (may want to handle it)
232 * flag error if process won't see signal immediately
233 * Q: should we do that all the time ??
ee1451be
BJ
234 */
235nosys()
236{
683ddffc
RE
237 if (u.u_signal[SIGSYS] == SIG_IGN || u.u_signal[SIGSYS] == SIG_HOLD)
238 u.u_error = EINVAL;
239 psignal(u.u_procp, SIGSYS);
ee1451be 240}