Commit | Line | Data |
---|---|---|
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 |
20 | struct sysent sysent[]; |
21 | int nsysent; | |
ee1451be | 22 | |
683ddffc RE |
23 | char *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*/ | |
47 | trap(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); | |
129 | out: | |
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*/ | |
155 | syscall(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 */ | |
185 | asm("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 | 209 | bad: |
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 | */ |
243 | nosys() | |
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 | } |