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