|
|
1.1 root 1: /*
2: * Routines that deal closely with VAX-specific traps:
3: * machine checks, memory errors, and the like
4: */
5: #include "sys/param.h"
6: #include "sys/systm.h"
7: #include "sys/user.h"
8: #include "sys/mtpr.h"
9: #include "sys/psl.h"
10:
11: #define NMC750 8
12: char *mc750name[NMC750] = {
13: "??", "cs par", "tbuf/bus/cache", "??",
14: "??", "??", "ucode lost", "unused ird slot",
15: };
16:
17: #define BUS 2 /* the only summary code we care about */
18:
19: #define MCSR 0x17 /* machine check status */
20: #define TBDR 0x24 /* translation buffer disable */
21: #define CADR 0x25 /* cache disable */
22: #define MCESR 0x26 /* machine check error flags */
23: #define CAER 0x27 /* cache error flags */
24:
25: /*
26: * bits in various error registers
27: */
28:
29: #define TBG1T 0x100 /* mcsr: trans buf group 1 tag error */
30: #define TBG0T 0x80 /* mcsr: group 0 tag */
31: #define TBG1D 0x40 /* mcsr: group 1 data */
32: #define TBG0D 0x20 /* mcsr: group 0 data */
33: #define NXM 0x8 /* mcsr: non-existent memory/read lock timeout */
34: #define UCD 0x4 /* mcsr: uncorrectable data */
35: #define TBPAR 0x4 /* mcesr: tb parity error */
36: #define CDATA 0x4 /* cacherr: cache data error */
37: #define CTAG 0x8 /* cacherr: cache tag error */
38:
39: /*
40: * saved mode from machine check
41: */
42:
43: #define MODE 03 /* mask for just mode */
44: #define PSLMSH 24 /* shift to get mode from psl */
45:
46: /*
47: * control bits
48: */
49: #define CACHEON 0 /* cadr */
50: #define CACHEOFF 1 /* cadr */
51: #define REPL 0x8 /* tbdr: force replace */
52: #define RPL1 0x4 /* tbdr: which group to replace */
53: #define TBMG1 0x2 /* tbdr: force miss group 1 */
54: #define TBMG0 0x1 /* tbdr: force miss group 0 */
55:
56: struct mc750frame {
57: int bcnt; /* byte count == 0x28 */
58: int summary; /* summary parameter (as above) */
59: int va; /* virtual address register */
60: int errpc; /* error pc */
61: int mdr;
62: int svmode; /* saved mode register */
63: int rdtimo; /* read lock timeout */
64: int tbgpar; /* tb group parity error register */
65: int cacherr; /* cache error register */
66: int buserr; /* bus error register */
67: int mcesr; /* machine check status register */
68: int pc; /* trapped pc */
69: int psl; /* trapped psl */
70: };
71:
72: /*
73: * write timeout trap
74: * panic if in kernel mode
75: * trap if user mode
76: */
77:
78: wtimeout(ps, pc)
79: long ps, pc;
80: {
81:
82: if (USERMODE(ps)) {
83: /*
84: * code stolen from setrun
85: */
86: runrun++;
87: aston();
88: psignal(u.u_procp, SIGBUS);
89: return;
90: }
91: printf("wtmo pc %x\n", pc);
92: panic("wtmo");
93: }
94:
95: /*
96: * Machine check.
97: * If possible, recover and return;
98: * if not but in user mode, send a signal;
99: * if not and in kernel mode, panic.
100: */
101:
102: machinecheck(ps, f)
103: long ps;
104: struct mc750frame *f;
105: {
106: int ok;
107:
108: mtpr(CADR, CACHEOFF); /* should really be much earlier */
109: ok = mckrec(f);
110: machreset();
111: printf("machine check type x%x:", f->summary);
112: if (0 <= f->summary && f->summary < NMC750)
113: printf(" %s\n", mc750name[f->summary]);
114: else
115: printf("\n");
116: printf("\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n",
117: f->va, f->errpc, f->mdr, f->svmode,
118: f->rdtimo, f->tbgpar, f->cacherr);
119: printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n",
120: f->buserr, f->mcesr, f->pc, f->psl,
121: mfpr(MCSR));
122: if (ok)
123: return;
124: if (USERMODE(ps)) {
125: /*
126: * code stolen from setrun
127: */
128: runrun++;
129: aston();
130: psignal(u.u_procp, SIGBUS);
131: return;
132: }
133: panic("mchk");
134: }
135:
136: /*
137: * table of resumable instructions
138: * a table of bits, indexed by opcode
139: * this is taken straight from vms;
140: * don't ask me to justify choices
141: */
142:
143: static char mrestab[256/8] = {
144: 0x6b, /* rei ret svpctx */
145: 0x0f, /* probe? insque remque */
146: 0xbf, /* jsb */
147: 0xff,
148: 0xff,
149: 0xff,
150: 0xff,
151: 0xff,
152: 0xff,
153: 0xff,
154: 0x2f, /* emodf cvtfd adawi */
155: 0x0, /* more interlocked instructions */
156: 0x0, /* double precision floating point */
157: 0x0f, /* more double stuff */
158: 0x4a, /* more double/quad */
159: 0xc1, /* .. */
160: 0xff,
161: 0xff,
162: 0xff,
163: 0xff,
164: 0xff,
165: 0xff,
166: 0xff,
167: 0x03, /* pushr popr chm? */
168: 0xff,
169: 0xff,
170: 0xff,
171: 0xff,
172: 0xff,
173: 0xff,
174: 0xff,
175: 0x01, /* cvtlp callg calls xfc reserved */
176: };
177:
178: /*
179: * code to decide if machine check is recoverable,
180: * and recover if possible
181: */
182:
183: static time_t lastmchk;
184: static int mchkcache = CACHEON;
185:
186: mckrec(f)
187: register struct mc750frame *f;
188: {
189: register int x;
190:
191: mtpr(TBIA, 0);
192: if (f->summary != BUS)
193: return (0);
194: if (f->mcesr & TBPAR) {
195: printf("tb err\n");
196: x = mfpr(TBDR);
197: if (f->tbgpar & (TBG0D|TBG0T)) {
198: if (x & TBMG1) {
199: printf("both groups bad\n");
200: death();
201: }
202: x = TBMG0 | RPL1 | REPL;
203: }
204: else {
205: if (x & TBMG0) {
206: printf("both groups bad\n");
207: death();
208: }
209: x = TBMG1 | REPL;
210: }
211: if (lastmchk == time) {
212: mtpr(TBDR, x);
213: printf("g%d off\n", x & TBMG0 ? 0 : 1);
214: }
215: return (1);
216: }
217: if (f->cacherr & (CDATA | CTAG)) {
218: printf("cache err\n");
219: mtpr(CAER, f->cacherr); /* clear error bits */
220: mchkcache = CACHEOFF;
221: }
222: else if (f->buserr & UCD) {
223: printf("hard mem err\n");
224: memerr();
225: return (0); /* can't recover */
226: }
227: else if (f->buserr & NXM) {
228: printf("nxm\n");
229: return (0); /* can't recover */
230: }
231: else {
232: printf("unknown problem\n");
233: return (0);
234: }
235: /*
236: * if we get here, it's potentially recoverable
237: * may recover if:
238: * haven't had one in the last second
239: * and instruction didn't change modes (?)
240: * and resumable instruction
241: */
242: if (lastmchk == time)
243: return (0);
244: lastmchk = time;
245: if ((f->svmode & MODE) != ((f->psl >> PSLMSH) & MODE))
246: return (0);
247: x = *(unsigned char *)f->pc;
248: if (mrestab[x >> 3] & (1 << (x & 07)))
249: return (1);
250: return (0);
251: }
252:
253: /*
254: * reset processor error registers
255: * call if we get a machine check that's really ok,
256: * or perhaps when the system is started
257: */
258:
259: machreset()
260: {
261: mtpr(MCESR, 0xf);
262: mtpr(CADR, mchkcache);
263: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.