|
|
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.