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: */
18: struct 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: */
27: char 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: */
42: trap(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:
169: out:
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: */
189: trap1(f)
190: int (*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: */
202: nosys()
203: {
204: u.u_error = 100;
205: }
206:
207: /*
208: * Ignored system call
209: */
210: nullsys()
211: {
212: }
Defined functions
trap
defined in line
42; used 2 times
Defined variables
Defined struct's
Defined macros
EBIT
defined in line
9; used 2 times
SETD
defined in line
11; used 1 times
SYS
defined in line
12; used 1 times
UMODE
defined in line
10; used 2 times
USER
defined in line
13; used 1 times