|
|
1.1 root 1: /* trap.c 4.10 84/02/09 */
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 "../h/proc.h"
12: #include "../h/seg.h"
13: #include "../machine/trap.h"
14: #include "../h/acct.h"
15: #include "../h/kernel.h"
16: #include "../machine/mtpr.h"
17: #ifdef SYSCALLTRACE
18: #include "../sys/syscalls.c"
19: #endif
20: #include "../machine/fp_in_krnl.h"
21:
22: #define USER 040 /* user-mode flag added to type */
23:
24: struct sysent sysent[];
25: int nsysent;
26:
27: /*
28: * Called from the trap handler when a processor trap occurs.
29: */
30: trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
31: unsigned code;
32: {
33: /* Next 2 dummy variables MUST BE the first local */
34: /* variables; leaving place for registers 0 and 1 */
35: /* which are not preserved by the 'cct' */
36:
37: int dumm1; /* register 1 */
38: int dumm0; /* register 0 */
39: register dumm3; /* register 12 is the 1'st register variable */
40: /* in TAHOE (register 11 in VAX) */
41:
42: register int *locr0 = ((int *)&psl)-PS;
43: register int i;
44: register struct proc *p;
45: struct timeval syst;
46: char *typename;
47:
48: syst = u.u_ru.ru_stime;
49: if (USERMODE(locr0[PS])) {
50: type |= USER;
51: u.u_ar0 = locr0;
52: }
53: switch (type) {
54:
55: default: switch (type) {
56: case T_RESADFLT:
57: typename = "reserved addressing mode";break;
58: case T_PRIVINFLT:
59: typename = "illegal opcode";break;
60: case T_RESOPFLT:
61: typename = "reserved operand";break;
62: case T_BPTFLT:
63: typename = "breakpoint";break;
64: case T_SYSCALL:
65: typename = "kernel call";break;
66: case T_ARITHTRAP:
67: typename = "arithmetic exception";break;
68: case T_ASTFLT:
69: typename = "system forced exception";break;
70: case T_SEGFLT:
71: typename = "limit fault";break;
72: case T_PROTFLT:
73: typename = "illegal access type";break;
74: case T_TRCTRAP:
75: typename = "trace trap";break;
76: case T_PAGEFLT:
77: typename = "page fault";break;
78: case T_TABLEFLT:
79: typename = "page table fault";break;
80: case T_ALIGNFLT:
81: typename = "alignment fault";break;
82: case T_KSPNOTVAL:
83: typename = "kernel stack not valid";break;
84: }
85: printf("System trap (%s), code = %x, pc = %x\n",
86: typename, code, pc);
87: panic("trap");
88:
89: case T_PROTFLT + USER: /* protection fault */
90: i = SIGBUS;
91: break;
92:
93: case T_PRIVINFLT + USER: /* privileged instruction fault */
94: case T_RESADFLT + USER: /* reserved addressing fault */
95: case T_RESOPFLT + USER: /* resereved operand fault */
96: case T_ALIGNFLT + USER: /* unaligned data fault */
97: u.u_code = type &~ USER;
98: i = SIGILL;
99: break;
100:
101: case T_ASTFLT + USER: /* Allow process switch */
102: case T_ASTFLT:
103: astoff();
104: if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) {
105: addupc(pc, &u.u_prof, 1);
106: u.u_procp->p_flag &= ~SOWEUPC;
107: }
108: goto out;
109:
110: case T_ARITHTRAP + USER:
111: u.u_code = code;
112: i = SIGFPE;
113: break;
114:
115: /*
116: * If the user SP is above the stack segment,
117: * grow the stack automatically.
118: */
119: case T_SEGFLT + USER:
120: if (grow((unsigned)locr0[SP]) || grow(code))
121: goto out;
122: i = SIGSEGV;
123: break;
124:
125: case T_TABLEFLT: /* allow page table faults in kernel mode */
126: case T_TABLEFLT + USER: /* page table fault */
127: panic("ptable fault");
128:
129: case T_PAGEFLT: /* allow page faults in kernel mode */
130: case T_PAGEFLT + USER: /* page fault */
131: i = u.u_error;
132: pagein(code, 0);
133: u.u_error = i;
134: if (type == T_PAGEFLT)
135: return;
136: goto out;
137:
138: case T_BPTFLT + USER: /* bpt instruction fault */
139: case T_TRCTRAP + USER: /* trace trap */
140: locr0[PS] &= ~PSL_T;
141: i = SIGTRAP;
142: break;
143: case T_KSPNOTVAL:
144: case T_KSPNOTVAL + USER:
145: i = SIGKILL; /* There is nothing to do but to kill the
146: * process.. */
147: printf("KSP NOT VALID.\n");
148: break;
149:
150: }
151: psignal(u.u_procp, i);
152: out:
153: p = u.u_procp;
154: if (p->p_cursig || ISSIG(p))
155: psig();
156: p->p_pri = p->p_usrpri;
157: if (runrun) {
158: /*
159: * Since we are u.u_procp, clock will normally just change
160: * our priority without moving us from one queue to another
161: * (since the running process is not on a queue.)
162: * If that happened after we setrq ourselves but before we
163: * swtch()'ed, we might not be on the queue indicated by
164: * our priority.
165: */
166: (void) spl8();
167: setrq(p);
168: u.u_ru.ru_nivcsw++;
169: swtch();
170: }
171: if (u.u_prof.pr_scale) {
172: int ticks;
173: struct timeval *tv = &u.u_ru.ru_stime;
174:
175: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
176: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
177: if (ticks)
178: addupc(locr0[PC], &u.u_prof, ticks);
179: }
180: curpri = p->p_pri;
181: }
182:
183: #ifdef SYSCALLTRACE
184: int syscalltrace = 0;
185: #endif
186:
187: /*
188: * Called from the trap handler when a system call occurs
189: */
190: syscall(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
191: unsigned code;
192: {
193: /* Next 2 dummy variables MUST BE the first local */
194: /* variables; leaving place for registers 0 and 1 */
195: /* which are not preserved by the 'cct' */
196:
197: int dumm1; /* register 1 */
198: int dumm0; /* register 0 */
199: register dumm3; /* register 12 is the 1'st register variable */
200: /* in TAHOE (register 11 in VAX) */
201:
202: register int *locr0 = ((int *)&psl)-PS;
203: register caddr_t params; /* known to be r10 below */
204: register int i; /* known to be r9 below */
205: register struct sysent *callp;
206: register struct proc *p;
207: struct timeval syst;
208: int opc;
209:
210: syst = u.u_ru.ru_stime;
211: if (!USERMODE(locr0[PS]))
212: panic("syscall");
213: u.u_ar0 = locr0;
214: if (code == 139) { /* XXX */
215: sigcleanup(); /* XXX */
216: goto done; /* XXX */
217: }
218: params = (caddr_t)locr0[FP] + NBPW;
219: u.u_error = 0;
220: /*------ DIRTY CODE !!!!!!!!!---------*/
221: /* try to reconstruct pc, assuming code is an immediate constant */
222: opc = pc - 2; /* short literal */
223: if (code > 0x3f) {
224: opc--; /* byte immediate */
225: if (code > 0x7f) {
226: opc--; /* word immediate */
227: if (code > 0x7fff)
228: opc -= 2; /* long immediate */
229: }
230: }
231: /*------------------------------------*/
232: callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
233: if (callp == sysent) {
234: i = fuword(params);
235: params += NBPW;
236: callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
237: }
238: if (i = callp->sy_narg * sizeof (int)) {
239: asm("prober $1,(r10),r9"); /* GROT */
240: asm("bnequ ok"); /* GROT */
241: u.u_error = EFAULT; /* GROT */
242: goto bad; /* GROT */
243: asm("ok:"); /* GROT */
244: bcopy(params,u.u_arg,i);
245: }
246: u.u_ap = u.u_arg;
247: u.u_dirp = (caddr_t)u.u_arg[0];
248: u.u_r.r_val1 = 0;
249: u.u_r.r_val2 = locr0[R1]; /*------------ CHECK again */
250: if (setjmp(&u.u_qsave)) {
251: if (u.u_error == 0 && u.u_eosys == JUSTRETURN)
252: u.u_error = EINTR;
253: } else {
254: u.u_eosys = JUSTRETURN;
255: #ifdef SYSCALLTRACE
256: if (syscalltrace) {
257: register int i;
258: char *cp;
259:
260: if (code >= nsysent)
261: printf("0x%x", code);
262: else
263: printf("%s", syscallnames[code]);
264: cp = "(";
265: for (i= 0; i < callp->sy_narg; i++) {
266: printf("%s%x", cp, u.u_arg[i]);
267: cp = ", ";
268: }
269: if (i)
270: putchar(')', 0);
271: putchar('\n', 0);
272: }
273: #endif
274:
275: (*(callp->sy_call))();
276: }
277: if (u.u_eosys == RESTARTSYS)
278: pc = opc;
279: else if (u.u_error) {
280: bad:
281: locr0[R0] = u.u_error;
282: locr0[PS] |= PSL_C; /* carry bit */
283: } else {
284: locr0[PS] &= ~PSL_C; /* clear carry bit */
285: locr0[R0] = u.u_r.r_val1;
286: locr0[R1] = u.u_r.r_val2;
287: }
288: done:
289: p = u.u_procp;
290: if (p->p_cursig || ISSIG(p))
291: psig();
292: p->p_pri = p->p_usrpri;
293: if (runrun) {
294: /*
295: * Since we are u.u_procp, clock will normally just change
296: * our priority without moving us from one queue to another
297: * (since the running process is not on a queue.)
298: * If that happened after we setrq ourselves but before we
299: * swtch()'ed, we might not be on the queue indicated by
300: * our priority.
301: */
302: (void) spl8();
303: setrq(p);
304: u.u_ru.ru_nivcsw++;
305: swtch();
306: }
307: if (u.u_prof.pr_scale) {
308: int ticks;
309: struct timeval *tv = &u.u_ru.ru_stime;
310:
311: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
312: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
313: if (ticks)
314: addupc(locr0[PC], &u.u_prof, ticks);
315: }
316: curpri = p->p_pri;
317: }
318:
319: /*
320: * nonexistent system call-- signal process (may want to handle it)
321: * flag error if process won't see signal immediately
322: * Q: should we do that all the time ??
323: */
324: nosys()
325: {
326: if (u.u_signal[SIGSYS] == SIG_IGN || u.u_signal[SIGSYS] == SIG_HOLD)
327: u.u_error = EINVAL;
328: psignal(u.u_procp, SIGSYS);
329: }
330:
331: /*
332: * Ignored system call
333: */
334: nullsys()
335: {
336:
337: }
338:
339: fpemulate(hfsreg,acc_most,acc_least,dbl,op_most,op_least,opcode,pc,psl)
340: {
341: /*
342: * Emulate the F.P. 'opcode'. Update psl flags as necessary.
343: * If all OK, set 'opcode' to 0, else to the F.P. exception #.
344: * Not all parameter longwords are relevant - depends on opcode.
345: *
346: * The entry mask is set so ALL registers are saved - courtesy of
347: * locore.s. This enables F.P. opcodes to change 'user' registers
348: * before return.
349: */
350:
351: /* WARNING!!!! THIS CODE MUST NOT PRODUCE ANY FLOATING POINT EXCEPTIONS. */
352:
353: /* Next 2 dummy variables MUST BE the first local */
354: /* variables; leaving place for registers 0 and 1 */
355: /* which are not preserved by the 'cct' */
356:
357: int dumm1; /* register 1 */
358: int dumm0; /* register 0 */
359: register dumm3; /* register 12 is the 1'st register variable */
360: /* in TAHOE (register 11 in VAX) */
361:
362: register int *locr0 = ((int *)&psl)-PS; /* R11 */
363: int hfs = 0; /* returned data about exceptions */
364: float (*f_proc)(); /* fp procedure to be called. */
365: double (*d_proc)(); /* fp procedure to be called. */
366: int dest_type; /* float or double. */
367: union{
368: float ff; /* float result. */
369: int fi;
370: }f_res;
371: union{
372: double dd; /* double result. */
373: int di[2] ;
374: }d_res;
375: extern float Kcvtlf(), Kaddf(), Ksubf(), Kmulf(), Kdivf();
376: extern double Kcvtld(), Kaddd(), Ksubd(), Kmuld(), Kdivd();
377: extern float Ksinf(), Kcosf(), Katanf(), Klogf(), Ksqrtf(), Kexpf();
378:
379:
380:
381: switch(opcode & 0x0FF){
382:
383: case CVLF: f_proc = Kcvtlf; dest_type = FLOAT;
384: locr0[PS] &= ~PSL_DBL;
385: dbl &= ~1;break; /* clear double bit */
386: case CVLD: d_proc = Kcvtld; dest_type = DOUBLE;
387: locr0[PS] |= PSL_DBL;
388: dbl |= 1; break; /* turn on double bit */
389: case ADDF: f_proc = Kaddf; dest_type = FLOAT;
390: break;
391: case ADDD: d_proc = Kaddd; dest_type = DOUBLE;
392: break;
393: case SUBF: f_proc = Ksubf; dest_type = FLOAT;
394: break;
395: case SUBD: d_proc = Ksubd; dest_type = DOUBLE;
396: break;
397: case MULF: f_proc = Kmulf; dest_type = FLOAT;
398: break;
399: case MULD: d_proc = Kmuld; dest_type = DOUBLE;
400: break;
401: case DIVF: f_proc = Kdivf; dest_type = FLOAT;
402: break;
403: case DIVD: d_proc = Kdivd; dest_type = DOUBLE;
404: break;
405: case SINF: f_proc = Ksinf; dest_type = FLOAT;
406: break;
407: case COSF: f_proc = Kcosf; dest_type = FLOAT;
408: break;
409: case ATANF: f_proc = Katanf; dest_type = FLOAT;
410: break;
411: case LOGF: f_proc = Klogf; dest_type = FLOAT;
412: break;
413: case SQRTF: f_proc = Ksqrtf; dest_type = FLOAT;
414: break;
415: case EXPF: f_proc = Kexpf; dest_type = FLOAT;
416: break;
417: }
418:
419: switch(dest_type){
420:
421: case FLOAT:
422: f_res.ff = (*f_proc)(acc_most,acc_least,op_most,op_least,&hfs);
423:
424: if (f_res.fi == 0 ) locr0[PS] |= PSL_Z;
425: if (f_res.fi < 0 ) locr0[PS] |= PSL_N;
426: break;
427: case DOUBLE:
428: d_res.dd = (*d_proc)(acc_most,acc_least,op_most,op_least,&hfs);
429: if ((d_res.di[0] == 0) && (d_res.di[1] == 0))
430: locr0[PS] |= PSL_Z;
431: if (d_res.di[0] < 0 ) locr0[PS] |= PSL_N;
432: break;
433: }
434:
435: if (hfs & HFS_OVF){
436: locr0[PS] |= PSL_V; /* turn on overflow bit */
437: /* if (locr0[PS] & PSL_IV) { /* overflow elabled? */
438: opcode = OVF_EXC;
439: u.u_error = (hfs & HFS_DOM) ? EDOM : ERANGE;
440: return;
441: /*}*/
442: }
443: else if (hfs & HFS_UNDF){
444: if (locr0[PS] & PSL_FU){ /* underflow elabled? */
445: opcode = UNDF_EXC;
446: u.u_error = (hfs & HFS_DOM) ? EDOM : ERANGE;
447: return;
448: }
449: }
450: else if (hfs & HFS_DIVZ){
451: opcode = DIV0_EXC;
452: return;
453: }
454: else if (hfs & HFS_DOM)
455: u.u_error = EDOM;
456: else if (hfs & HFS_RANGE)
457: u.u_error = ERANGE;
458:
459: switch(dest_type){
460: case FLOAT:
461: if ((hfs & HFS_OVF) || (hfs & HFS_UNDF)) {
462: f_res.ff = 0.0;
463: locr0[PS] |= PSL_Z;
464: }
465: mvtofacc(f_res.ff, &acc_most);
466: break;
467: case DOUBLE:
468: if ((hfs & HFS_OVF) || (hfs & HFS_UNDF)) {
469: d_res.dd = 0.0;
470: locr0[PS] |= PSL_Z;
471: }
472: mvtodacc(d_res.di[0], d_res.di[1], &acc_most);
473: break;
474: }
475: opcode=0;
476: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.