|
|
1.1 root 1: #include "sys/param.h"
2: #include "sys/systm.h"
3: #include "sys/user.h"
4: #include "sys/proc.h"
5: #include "sys/reg.h"
6: #include "sys/trap.h"
7: #include "sys/psl.h"
8: #include "sys/mtpr.h"
9: #include "sys/vmmeter.h"
10:
11: #define USER 040 /* user-mode flag added to type */
12:
13: int syscnt[MAXSYS];
14:
15: /*
16: * Called from the trap handler when a processor trap occurs.
17: */
18: /*ARGSUSED*/
19: trap(sp, type, code, pc, psl)
20: unsigned code;
21: {
22: register int *locr0 = ((int *)&psl)-PS;
23: register int i;
24: register struct proc *p;
25: time_t syst;
26:
27: cnt.v_trap++;
28: syst = u.u_vm.vm_stime;
29: if (USERMODE(locr0[PS])) {
30: type |= USER;
31: u.u_ar0 = locr0;
32: }
33: switch (type) {
34:
35: default:
36: spl7();
37: printf("type %d sp x%x code x%x pc x%x psl x%x locr0 x%x\n",
38: type, sp, code, pc, psl, locr0);
39: panic("trap");
40:
41: case PROTFLT + USER: /* protection fault */
42: i = SIGBUS;
43: break;
44:
45: case PRIVINFLT + USER: /* privileged instruction fault */
46: case RESADFLT + USER: /* reserved addressing fault */
47: case RESOPFLT + USER: /* resereved operand fault */
48: u.u_code = type &~ USER;
49: i = SIGILL;
50: break;
51:
52: case ASTFLT + USER: /* Allow process switch */
53: astoff();
54: if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) {
55: addupc(pc, &u.u_prof, 1);
56: u.u_procp->p_flag &= ~SOWEUPC;
57: }
58: goto out;
59:
60: case ARITHTRAP + USER:
61: u.u_code = code;
62: i = SIGFPE;
63: break;
64:
65: /*
66: * If the user SP is above the stack segment,
67: * grow the stack automatically.
68: */
69: case SEGFLT + USER:
70: if (grow((unsigned)locr0[SP]) || grow(code))
71: goto out;
72: i = SIGSEGV;
73: break;
74:
75: case TABLEFLT: /* allow page table faults in kernel mode */
76: case TABLEFLT + USER: /* page table fault */
77: panic("ptable fault");
78:
79: case PAGEFLT: /* allow page faults in kernel mode */
80: case PAGEFLT + USER: /* page fault */
81: i = u.u_error;
82: pagein(code, &u);
83: u.u_error = i;
84: if (type == PAGEFLT)
85: return;
86: goto out;
87:
88: case BPTFLT + USER: /* bpt instruction fault */
89: case TRCTRAP + USER: /* trace trap */
90: locr0[PS] &= ~PSL_T;
91: i = SIGTRAP;
92: break;
93:
94: case XFCFLT + USER: /* xfc instruction fault */
95: i = SIGEMT;
96: break;
97:
98: case COMPATFLT + USER: /* compatibility mode fault */
99: u.u_code = code;
100: i = SIGILL;
101: break;
102: }
103: psignal(u.u_procp, i);
104: out:
105: p = u.u_procp;
106: if (p->p_cursig || (p->p_sig && issig()))
107: psig();
108: p->p_pri = p->p_usrpri;
109: if (runrun) {
110: /*
111: * Since we are u.u_procp, clock will normally just change
112: * our priority without moving us from one queue to another
113: * (since the running process is not on a queue.)
114: * If that happened after we setrq ourselves but before we
115: * swtch()'ed, we might not be on the queue indicated by
116: * our priority.
117: */
118: (void) spl6();
119: setrq(p);
120: swtch();
121: }
122: if (u.u_prof.pr_scale && (syst -= u.u_vm.vm_stime))
123: addupc(locr0[PC], &u.u_prof, (int)-syst);
124: curpri = p->p_pri;
125: }
126:
127: /*
128: * Called from the trap handler when a system call occurs
129: * `loathsome' is pointless, but must stay until offsets in reg.h change
130: */
131:
132: syscall(sp, loathsome, code, pc, psl)
133: register unsigned code;
134: {
135: register int *locr0 = ((int *)&psl)-PS;
136: register caddr_t params;
137: register struct sysent *callp;
138: register struct proc *p;
139: register time_t syst;
140:
141: syst = u.u_vm.vm_stime;
142: if (!USERMODE(psl))
143: panic("syscall");
144: cnt.v_syscall++;
145: u.u_ar0 = locr0;
146: params = (caddr_t)locr0[AP] + sizeof(int);
147: if (code == 0) { /* sys indir */
148: code = fuword(params);
149: params += sizeof(int);
150: }
151: if (code >= MAXSYS)
152: code = 0;
153: syscnt[code]++;
154: callp = &sysent[code];
155: if (callp->sy_narg)
156: if (copyin(params, (caddr_t)u.u_arg, callp->sy_narg*sizeof(int)))
157: goto bad;
158: u.u_ap = u.u_arg;
159: u.u_r.r_val1 = 0;
160: u.u_r.r_val2 = locr0[R1];
161: u.u_error = 0;
162: if (setjmp(u.u_qsav)) {
163: if (u.u_error == 0)
164: u.u_error = EINTR;
165: } else
166: (*(callp->sy_call))();
167: locr0[PS] &= ~PSL_C;
168: if (u.u_error) {
169: bad:
170: locr0[R0] = u.u_error;
171: locr0[PS] |= PSL_C; /* carry bit */
172: } else {
173: locr0[R0] = u.u_r.r_val1;
174: locr0[R1] = u.u_r.r_val2;
175: }
176: p = u.u_procp;
177: if (p->p_cursig || (p->p_sig && issig()))
178: psig();
179: p->p_pri = p->p_usrpri;
180: if (runrun) {
181: (void) spl6();
182: setrq(p);
183: swtch();
184: }
185: if (u.u_prof.pr_scale && (syst -= u.u_vm.vm_stime))
186: addupc(locr0[PC], &u.u_prof, (int)-syst);
187: curpri = p->p_pri;
188: }
189:
190: /*
191: * nonexistent system call-- set fatal error code.
192: */
193: nosys()
194: {
195: u.u_error = 100;
196: }
197:
198: /*
199: * Ignored system call
200: */
201: nullsys()
202: {
203:
204: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.