xref: /original-bsd/sys/vax/vax/trap.c (revision 552e81d8)
1 /*	trap.c	3.6	10/02/80	*/
2 
3 
4 #include "../h/param.h"
5 #include "../h/systm.h"
6 #include "../h/dir.h"
7 #include "../h/user.h"
8 #include "../h/proc.h"
9 #include "../h/reg.h"
10 #include "../h/seg.h"
11 #include "../h/trap.h"
12 #include "../h/psl.h"
13 #include "../h/pte.h"
14 #include "../h/inline.h"
15 
16 #define	USER	040		/* user-mode flag added to type */
17 
18 struct	sysent	sysent[128];
19 
20 /*
21  * Called from the trap handler when a processor trap occurs.
22  */
23 /*ARGSUSED*/
24 trap(sp, type, code, pc, psl)
25 unsigned code;
26 {
27 	register int *locr0 = ((int *)&psl)-PS;
28 	register int i;
29 	register struct proc *p;
30 	time_t syst;
31 
32 	syst = u.u_vm.vm_stime;
33 	if (USERMODE(locr0[PS])) {
34 		type |= USER;
35 		u.u_ar0 = locr0;
36 	}
37 	switch (type) {
38 
39 	default:
40 		printf("trap type %d, code = %x\n", type, code);
41 		panic("trap");
42 
43 	case PROTFLT + USER:	/* protection fault */
44 		i = SIGBUS;
45 		break;
46 
47 	case PRIVINFLT + USER:	/* privileged instruction fault */
48 	case RESADFLT + USER:	/* reserved addressing fault */
49 	case RESOPFLT + USER:	/* resereved operand fault */
50 		i = SIGILL;
51 		break;
52 
53 	case RESCHED + USER:	/* Allow process switch */
54 		goto out;
55 
56 	case ARITHTRAP + USER:
57 		i = SIGFPE;
58 		break;
59 
60 	/*
61 	 * If the user SP is above the stack segment,
62 	 * grow the stack automatically.
63 	 */
64 	case SEGFLT + USER: /* segmentation exception */
65 		if(grow((unsigned)locr0[SP]) || grow(code))
66 			goto out;
67 		i = SIGSEGV;
68 		break;
69 
70 	case TABLEFLT:		/* allow page table faults in kernel mode */
71 	case TABLEFLT + USER:   /* page table fault */
72 		panic("page table fault");
73 
74 	case PAGEFLT:		/* allow page faults in kernel mode */
75 	case PAGEFLT + USER:	/* page fault */
76 		i = u.u_error;
77 		pagein(code);   /* bring in page containing virtual addr */
78 		u.u_error = i;
79 /*
80 		if (type == PAGEFLT)
81 */
82 			return;
83 /*
84 		goto out;
85 */
86 
87 	case BPTFLT + USER:	/* bpt instruction fault */
88 	case TRCTRAP + USER:	/* trace trap */
89 		locr0[PS] &= ~PSL_T;	/* turn off trace bit */
90 		i = SIGTRAP;
91 		break;
92 
93 	case XFCFLT + USER:	/* xfc instruction fault */
94 		i = SIGEMT;
95 		break;
96 
97 	case COMPATFLT + USER:	/* compatibility mode fault */
98 		u.u_cfcode = code;
99 		i = SIGILL;
100 		break;
101 	}
102 	psignal(u.u_procp, i);
103 out:
104 	p = u.u_procp;
105 	if (p->p_cursig || ISSIG(p))
106 		psig();
107 	p->p_pri = p->p_usrpri;
108 	if (runrun) {
109 		/*
110 		 * Since we are u.u_procp, clock will normally just change
111 		 * our priority without moving us from one queue to another
112 		 * (since the running process is not on a queue.)
113 		 * If that happened after we setrq ourselves but before we
114 		 * swtch()'ed, we might not be on the queue indicated by
115 		 * our priority.
116 		 */
117 		spl6();
118 		setrq(p);
119 		swtch();
120 	}
121 	if (u.u_prof.pr_scale && (syst -= u.u_vm.vm_stime))
122 		addupc((caddr_t)locr0[PC], &u.u_prof, (int)-syst);
123 	curpri = p->p_pri;
124 }
125 
126 /*
127  * Called from the trap handler when a system call occurs
128  */
129 /*ARGSUSED*/
130 syscall(sp, type, code, pc, psl)
131 unsigned code;
132 {
133 	register int *locr0 = ((int *)&psl)-PS;
134 	register caddr_t params;		/* known to be r10 below */
135 	register int i;				/* known to be r9 below */
136 	register struct sysent *callp;
137 	register struct proc *p;
138 	time_t syst;
139 	int opc;
140 
141 	syst = u.u_vm.vm_stime;
142 	if (!USERMODE(locr0[PS]))
143 		panic("syscall");
144 	u.u_ar0 = locr0;
145 	params = (caddr_t)locr0[AP] + NBPW;
146 	u.u_error = 0;
147 	opc = pc - 2;
148 	if (code > 63)
149 		opc -= 2;
150 	callp = &sysent[code&0177];
151 	if (callp == sysent) {
152 		i = fuword(params);
153 		params += NBPW;
154 		callp = &sysent[i&0177];
155 	}
156 	if (i = callp->sy_narg * sizeof (int)) {
157 		asm("prober $3,r9,(r10)");		/* GROT */
158 		asm("bnequ ok");			/* GROT */
159 		u.u_error = EFAULT;			/* GROT */
160 		goto bad;				/* GROT */
161 asm("ok:");						/* GROT */
162 		asm("movc3 r9,(r10),_u+U_ARG");		/* GROT */
163 	}
164 	u.u_ap = u.u_arg;
165 	u.u_dirp = (caddr_t)u.u_arg[0];
166 	u.u_r.r_val1 = 0;
167 	u.u_r.r_val2 = locr0[R1];
168 	if (setjmp(u.u_qsav)) {
169 		if (u.u_error == 0 && u.u_eosys == JUSTRETURN)
170 			u.u_error = EINTR;
171 	} else {
172 		u.u_eosys = JUSTRETURN;
173 		(*(callp->sy_call))();
174 	}
175 	locr0[PS] &= ~PSL_C;
176 	if (u.u_eosys == RESTARTSYS)
177 		pc = opc;
178 	else if (u.u_eosys == SIMULATERTI)
179 		dorti();
180 	else if (u.u_error) {
181 bad:
182 		locr0[R0] = u.u_error;
183 		locr0[PS] |= PSL_C;	/* carry bit */
184 	} else {
185 		locr0[R0] = u.u_r.r_val1;
186 		locr0[R1] = u.u_r.r_val2;
187 	}
188 	p = u.u_procp;
189 	if (p->p_cursig || ISSIG(p))
190 		psig();
191 	p->p_pri = p->p_usrpri;
192 	if (runrun) {
193 		/*
194 		 * Since we are u.u_procp, clock will normally just change
195 		 * our priority without moving us from one queue to another
196 		 * (since the running process is not on a queue.)
197 		 * If that happened after we setrq ourselves but before we
198 		 * swtch()'ed, we might not be on the queue indicated by
199 		 * our priority.
200 		 */
201 		spl6();
202 		setrq(p);
203 		swtch();
204 	}
205 	if (u.u_prof.pr_scale && (syst -= u.u_vm.vm_stime))
206 		addupc((caddr_t)locr0[PC], &u.u_prof, (int)-syst);
207 	curpri = p->p_pri;
208 }
209 
210 /*
211  * nonexistent system call-- set fatal error code.
212  */
213 nosys()
214 {
215 
216 	u.u_error = 100;
217 }
218 
219 /*
220  * Ignored system call
221  */
222 nullsys()
223 {
224 
225 }
226