|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1990 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)trap.c 7.10 (Berkeley) 6/25/90
7: */
8:
9: #include "psl.h"
10: #include "reg.h"
11: #include "pte.h"
12:
13: #include "param.h"
14: #include "systm.h"
15: #include "user.h"
16: #include "assym.s"
17: #include "proc.h"
18: #include "seg.h"
19: #include "trap.h"
20: #include "acct.h"
21: #include "kernel.h"
22: #ifdef KTRACE
23: #include "ktrace.h"
24: #endif
25:
26: #include "mtpr.h"
27:
28: #define USER 040 /* user-mode flag added to type */
29:
30: struct sysent sysent[];
31: int nsysent;
32:
33: char *trap_type[] = {
34: "Reserved addressing mode",
35: "Privileged instruction",
36: "Reserved operand",
37: "Breakpoint",
38: "Xfc trap",
39: "Syscall trap",
40: "Arithmetic fault",
41: "Ast trap",
42: "Segmentation fault",
43: "Protection fault",
44: "Trace trap",
45: "Compatibility mode trap",
46: "Page fault",
47: "Page table fault",
48: "Kernel debugger trap",
49: };
50: int TRAP_TYPES = (sizeof trap_type / sizeof trap_type[0]);
51:
52: /*
53: * Called from the trap handler when a processor trap occurs.
54: */
55: /*ARGSUSED*/
56: trap(sp, type, code, pc, psl)
57: int sp, type;
58: unsigned code;
59: int pc, psl;
60: {
61: register int *locr0 = ((int *)&psl)-PS;
62: register int i;
63: unsigned ucode = code;
64: register struct proc *p;
65: struct timeval syst;
66:
67: syst = u.u_ru.ru_stime;
68: if (USERMODE(locr0[PS])) {
69: type |= USER;
70: u.u_ar0 = locr0;
71: }
72: switch (type) {
73:
74: default:
75: #ifdef KADB
76: if (kdb_trap(&psl))
77: return;
78: #endif
79: printf("trap type %d, code = %x, pc = %x\n", type, code, pc);
80: type &= ~USER;
81: if ((unsigned)type < TRAP_TYPES)
82: panic(trap_type[type]);
83: panic("trap");
84:
85: case T_PROTFLT+USER: /* protection fault */
86: i = SIGBUS;
87: break;
88:
89: case T_PRIVINFLT+USER: /* privileged instruction fault */
90: case T_RESADFLT+USER: /* reserved addressing fault */
91: case T_RESOPFLT+USER: /* reserved operand fault */
92: ucode = type &~ USER;
93: i = SIGILL;
94: break;
95:
96: case T_ASTFLT+USER:
97: astoff();
98: if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) {
99: addupc(pc, &u.u_prof, 1);
100: u.u_procp->p_flag &= ~SOWEUPC;
101: }
102: goto out;
103:
104: case T_ARITHTRAP+USER:
105: i = SIGFPE;
106: break;
107:
108: /*
109: * If the user SP is above the stack segment,
110: * grow the stack automatically.
111: */
112: case T_SEGFLT+USER:
113: if (grow((unsigned)locr0[SP]) || grow(code))
114: goto out;
115: i = SIGSEGV;
116: break;
117:
118: case T_TABLEFLT: /* allow page table faults in kernel mode */
119: case T_TABLEFLT+USER: /* page table fault */
120: panic("ptable fault");
121:
122: case T_PAGEFLT: /* allow page faults in kernel mode */
123: case T_PAGEFLT+USER: /* page fault */
124: pagein(code, 0);
125: if (type == T_PAGEFLT)
126: return;
127: goto out;
128:
129: case T_BPTFLT+USER: /* bpt instruction fault */
130: case T_TRCTRAP+USER: /* trace trap */
131: locr0[PS] &= ~PSL_T;
132: i = SIGTRAP;
133: break;
134:
135: case T_XFCFLT+USER: /* xfc instruction fault */
136: i = SIGEMT;
137: break;
138:
139: case T_COMPATFLT+USER: /* compatibility mode fault */
140: u.u_acflag |= ACOMPAT;
141: i = SIGILL;
142: break;
143: }
144: trapsignal(i, ucode);
145: out:
146: p = u.u_procp;
147: if (i = CURSIG(p))
148: psig(i);
149: p->p_pri = p->p_usrpri;
150: if (runrun) {
151: /*
152: * Since we are u.u_procp, clock will normally just change
153: * our priority without moving us from one queue to another
154: * (since the running process is not on a queue.)
155: * If that happened after we setrq ourselves but before we
156: * swtch()'ed, we might not be on the queue indicated by
157: * our priority.
158: */
159: (void) splclock();
160: setrq(p);
161: u.u_ru.ru_nivcsw++;
162: swtch();
163: if (i = CURSIG(p))
164: psig(i);
165: }
166: if (u.u_prof.pr_scale) {
167: int ticks;
168: struct timeval *tv = &u.u_ru.ru_stime;
169:
170: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
171: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
172: if (ticks)
173: addupc(locr0[PC], &u.u_prof, ticks);
174: }
175: curpri = p->p_pri;
176: }
177:
178: /*
179: * Called from the trap handler when a system call occurs
180: */
181: /*ARGSUSED*/
182: syscall(sp, type, code, pc, psl)
183: unsigned code;
184: {
185: register int *locr0 = ((int *)&psl)-PS;
186: register caddr_t params; /* known to be r10 below */
187: register int i; /* known to be r9 below */
188: register struct sysent *callp;
189: register struct proc *p = u.u_procp;
190: int error, opc;
191: struct args {
192: int i[8];
193: } args;
194: int rval[2];
195: struct timeval syst;
196:
197: syst = u.u_ru.ru_stime;
198: if (!USERMODE(locr0[PS]))
199: panic("syscall");
200: u.u_ar0 = locr0;
201: params = (caddr_t)locr0[AP] + NBPW;
202: opc = pc - 2;
203: if (code > 63)
204: opc -= 2;
205: if (code == 0) { /* indir */
206: code = fuword(params);
207: params += NBPW;
208: }
209: if (code >= nsysent)
210: callp = &sysent[0]; /* indir (illegal) */
211: else
212: callp = &sysent[code];
213: if ((i = callp->sy_narg * sizeof (int)) &&
214: (error = copyin(params, (caddr_t)&args, (u_int)i)) != 0) {
215: locr0[R0] = error;
216: locr0[PS] |= PSL_C; /* carry bit */
217: #ifdef KTRACE
218: if (KTRPOINT(p, KTR_SYSCALL))
219: ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
220: #endif
221: goto done;
222: }
223: #ifdef KTRACE
224: if (KTRPOINT(p, KTR_SYSCALL))
225: ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
226: #endif
227: rval[0] = 0;
228: rval[1] = locr0[R1];
229: error = (*callp->sy_call)(u.u_procp, &args, rval);
230: if (error == ERESTART)
231: pc = opc;
232: else if (error != EJUSTRETURN) {
233: if (error) {
234: locr0[R0] = error;
235: locr0[PS] |= PSL_C; /* carry bit */
236: } else {
237: locr0[R0] = rval[0];
238: locr0[R1] = rval[1];
239: locr0[PS] &= ~PSL_C;
240: }
241: }
242: /* else if (error == EJUSTRETURN) */
243: /* nothing to do */
244: done:
245: /*
246: * Reinitialize proc pointer `p' as it may be different
247: * if this is a child returning from fork syscall.
248: */
249: p = u.u_procp;
250: if (i = CURSIG(p))
251: psig(i);
252: p->p_pri = p->p_usrpri;
253: if (runrun) {
254: /*
255: * Since we are u.u_procp, clock will normally just change
256: * our priority without moving us from one queue to another
257: * (since the running process is not on a queue.)
258: * If that happened after we setrq ourselves but before we
259: * swtch()'ed, we might not be on the queue indicated by
260: * our priority.
261: */
262: (void) splclock();
263: setrq(p);
264: u.u_ru.ru_nivcsw++;
265: swtch();
266: if (i = CURSIG(p))
267: psig(i);
268: }
269: if (u.u_prof.pr_scale) {
270: int ticks;
271: struct timeval *tv = &u.u_ru.ru_stime;
272:
273: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
274: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
275: if (ticks)
276: addupc(locr0[PC], &u.u_prof, ticks);
277: }
278: curpri = p->p_pri;
279: #ifdef KTRACE
280: if (KTRPOINT(p, KTR_SYSRET))
281: ktrsysret(p->p_tracep, code, error, rval[0]);
282: #endif
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.