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