Research V7 development
[unix-history] / .ref-Research-V6 / usr / sys / ken / trap.c
CommitLineData
bb155176
KT
1#
2#include "../param.h"
3#include "../systm.h"
4#include "../user.h"
5#include "../proc.h"
6#include "../reg.h"
7#include "../seg.h"
8
9#define EBIT 1 /* user error bit in PS: C-bit */
10#define UMODE 0170000 /* user-mode bits in PS word */
11#define SETD 0170011 /* SETD instruction */
12#define SYS 0104400 /* sys (trap) instruction */
13#define USER 020 /* user-mode flag added to dev */
14
15/*
16 * structure of the system entry table (sysent.c)
17 */
18struct sysent {
19 int count; /* argument count */
20 int (*call)(); /* name of handler */
21} sysent[64];
22
23/*
24 * Offsets of the user's registers relative to
25 * the saved r0. See reg.h
26 */
27char regloc[9]
28{
29 R0, R1, R2, R3, R4, R5, R6, R7, RPS
30};
31
32/*
33 * Called from l40.s or l45.s when a processor trap occurs.
34 * The arguments are the words saved on the system stack
35 * by the hardware and software during the trap processing.
36 * Their order is dictated by the hardware and the details
37 * of C's calling sequence. They are peculiar in that
38 * this call is not 'by value' and changed user registers
39 * get copied back on return.
40 * dev is the kind of trap that occurred.
41 */
42trap(dev, sp, r1, nps, r0, pc, ps)
43{
44 register i, a;
45 register struct sysent *callp;
46
47 savfp();
48 if ((ps&UMODE) == UMODE)
49 dev =| USER;
50 u.u_ar0 = &r0;
51 switch(dev) {
52
53 /*
54 * Trap not expected.
55 * Usually a kernel mode bus error.
56 * The numbers printed are used to
57 * find the hardware PS/PC as follows.
58 * (all numbers in octal 18 bits)
59 * address_of_saved_ps =
60 * (ka6*0100) + aps - 0140000;
61 * address_of_saved_pc =
62 * address_of_saved_ps - 2;
63 */
64 default:
65 printf("ka6 = %o\n", *ka6);
66 printf("aps = %o\n", &ps);
67 printf("trap type %o\n", dev);
68 panic("trap");
69
70 case 0+USER: /* bus error */
71 i = SIGBUS;
72 break;
73
74 /*
75 * If illegal instructions are not
76 * being caught and the offending instruction
77 * is a SETD, the trap is ignored.
78 * This is because C produces a SETD at
79 * the beginning of every program which
80 * will trap on CPUs without 11/45 FPU.
81 */
82 case 1+USER: /* illegal instruction */
83 if(fuiword(pc-2) == SETD && u.u_signal[SIGINS] == 0)
84 goto out;
85 i = SIGINS;
86 break;
87
88 case 2+USER: /* bpt or trace */
89 i = SIGTRC;
90 break;
91
92 case 3+USER: /* iot */
93 i = SIGIOT;
94 break;
95
96 case 5+USER: /* emt */
97 i = SIGEMT;
98 break;
99
100 case 6+USER: /* sys call */
101 u.u_error = 0;
102 ps =& ~EBIT;
103 callp = &sysent[fuiword(pc-2)&077];
104 if (callp == sysent) { /* indirect */
105 a = fuiword(pc);
106 pc =+ 2;
107 i = fuword(a);
108 if ((i & ~077) != SYS)
109 i = 077; /* illegal */
110 callp = &sysent[i&077];
111 for(i=0; i<callp->count; i++)
112 u.u_arg[i] = fuword(a =+ 2);
113 } else {
114 for(i=0; i<callp->count; i++) {
115 u.u_arg[i] = fuiword(pc);
116 pc =+ 2;
117 }
118 }
119 u.u_dirp = u.u_arg[0];
120 trap1(callp->call);
121 if(u.u_intflg)
122 u.u_error = EINTR;
123 if(u.u_error < 100) {
124 if(u.u_error) {
125 ps =| EBIT;
126 r0 = u.u_error;
127 }
128 goto out;
129 }
130 i = SIGSYS;
131 break;
132
133 /*
134 * Since the floating exception is an
135 * imprecise trap, a user generated
136 * trap may actually come from kernel
137 * mode. In this case, a signal is sent
138 * to the current process to be picked
139 * up later.
140 */
141 case 8: /* floating exception */
142 psignal(u.u_procp, SIGFPT);
143 return;
144
145 case 8+USER:
146 i = SIGFPT;
147 break;
148
149 /*
150 * If the user SP is below the stack segment,
151 * grow the stack automatically.
152 * This relies on the ability of the hardware
153 * to restart a half executed instruction.
154 * On the 11/40 this is not the case and
155 * the routine backup/l40.s may fail.
156 * The classic example is on the instruction
157 * cmp -(sp),-(sp)
158 */
159 case 9+USER: /* segmentation exception */
160 a = sp;
161 if(backup(u.u_ar0) == 0)
162 if(grow(a))
163 goto out;
164 i = SIGSEG;
165 break;
166 }
167 psignal(u.u_procp, i);
168
169out:
170 if(issig())
171 psig();
172 setpri(u.u_procp);
173}
174
175/*
176 * Call the system-entry routine f (out of the
177 * sysent table). This is a subroutine for trap, and
178 * not in-line, because if a signal occurs
179 * during processing, an (abnormal) return is simulated from
180 * the last caller to savu(qsav); if this took place
181 * inside of trap, it wouldn't have a chance to clean up.
182 *
183 * If this occurs, the return takes place without
184 * clearing u_intflg; if it's still set, trap
185 * marks an error which means that a system
186 * call (like read on a typewriter) got interrupted
187 * by a signal.
188 */
189trap1(f)
190int (*f)();
191{
192
193 u.u_intflg = 1;
194 savu(u.u_qsav);
195 (*f)();
196 u.u_intflg = 0;
197}
198
199/*
200 * nonexistent system call-- set fatal error code.
201 */
202nosys()
203{
204 u.u_error = 100;
205}
206
207/*
208 * Ignored system call
209 */
210nullsys()
211{
212}