|
|
1.1 ! root 1: /* ! 2: * nautilus-specific traps ! 3: */ ! 4: ! 5: #include "sys/param.h" ! 6: #include "sys/mtpr.h" ! 7: #include "sys/psl.h" ! 8: #include "sys/systm.h" ! 9: #include "sys/user.h" ! 10: ! 11: extern long *mcrcsr; /* must read mem csr to clear NMI faults! */ ! 12: ! 13: /* ! 14: * nautilus-specific registers and bits ! 15: */ ! 16: ! 17: #define MCSTS 0x26 /* machine check status */ ! 18: #define NMIFSR 0x82 /* NMI fault status */ ! 19: #define NMIEAR 0x84 /* error address */ ! 20: #define CLRTOS 0x88 /* clear timeout sts */ ! 21: #define COR 0x85 /* cache on */ ! 22: ! 23: /* ! 24: * nmi fault ! 25: */ ! 26: ! 27: nmiflt() ! 28: { ! 29: register long fsr, addr; ! 30: register junk; ! 31: ! 32: fsr = mfpr(NMIFSR); ! 33: addr = mfpr(NMIEAR); ! 34: junk = mcrcsr[5]; /* sigh */ ! 35: printf("nmi fault %x addr %x\n", fsr, addr); ! 36: } ! 37: ! 38: /* ! 39: * machine check things ! 40: */ ! 41: struct mck { ! 42: int count; ! 43: int mcsts; ! 44: int upc; ! 45: int va; ! 46: int iber; ! 47: int cber; ! 48: int eber; ! 49: int nmifsr; ! 50: int nmiear; ! 51: int pc; ! 52: int ps; ! 53: }; ! 54: ! 55: ! 56: #define MCABORT 0x1 /* mcsts: can't possibly restart */ ! 57: ! 58: #define FSRBCOD 0x0c000000 /* nmifsr: timeout buffer code */ ! 59: #define RTO 0x08000000 /* read timeout */ ! 60: #define WTO 0x04000000 /* write timeout */ ! 61: ! 62: #define CBCERR 0x00303f00 /* cber: cache error */ ! 63: #define CBTERR 0x00070010 /* cber: trans buf error */ ! 64: #define CBRDS 0x00000006 /* cber: probably memory RDS */ ! 65: #define CBOXBAD 0x00000008 /* cber: various fatal errors */ ! 66: ! 67: #define IBOXBAD 0x000007ff /* iber: various fatal errors */ ! 68: ! 69: #define EBBERR 0x80 /* eber (each byte): b-side error */ ! 70: #define EBAERR 0x40 /* eber: a-side error */ ! 71: #define EBBSRC 0x38 /* eber: b-side source */ ! 72: #define EBASRC 0x03 /* eber: a-side source */ ! 73: ! 74: static time_t lastcache; ! 75: static int cacheon; ! 76: /* ! 77: * machine check ! 78: * if we get here, there's no desire to trap it with nofault ! 79: */ ! 80: machinecheck(ps, f) ! 81: long ps; ! 82: struct mck *f; ! 83: { ! 84: register ok; ! 85: ! 86: cacheon = mfpr(COR); ! 87: mtpr(COR, 0); /* in case that's what's broken */ ! 88: /* ! 89: * always print for now ! 90: * delays prevent console congestion ! 91: */ ! 92: printf("machine check:\n"); ! 93: DELAY(100000); ! 94: printf("mcsts %x upc %x va %x\n", f->mcsts, f->upc, f->va); ! 95: DELAY(100000); ! 96: printf("iber %x cber %x eber %x\n", f->iber, f->cber, f->eber); ! 97: DELAY(100000); ! 98: printf("nmifsr %x nmiear %x\n", f->nmifsr, f->nmiear); ! 99: printf("pc %x ps %x\n", f->pc, f->ps); ! 100: DELAY(100000); ! 101: ok = mckrec(f); ! 102: machreset(); ! 103: if (ok) ! 104: return; ! 105: if (USERMODE(ps)) { ! 106: /* ! 107: * code stolen from setrun ! 108: */ ! 109: runrun++; ! 110: aston(); ! 111: psignal(u.u_procp, SIGBUS); ! 112: return; ! 113: } ! 114: panic("mchk"); ! 115: } ! 116: ! 117: /* ! 118: * decide if the machine check is recoverable ! 119: * logic inspired by VAX/VMS ! 120: * roughly, if the microcode said it wasn't restartable (MCABORT) ! 121: * or if it seems a sufficiently nasty error (bus timeout, most ibox errors), ! 122: * say no. ! 123: */ ! 124: ! 125: mckrec(f) ! 126: struct mck *f; ! 127: { ! 128: register int i, x; ! 129: ! 130: switch (f->nmifsr & FSRBCOD) { ! 131: case RTO: ! 132: printf("read timeout\n"); ! 133: break; ! 134: ! 135: case WTO: ! 136: printf("write timeout\n"); ! 137: break; ! 138: } ! 139: if (f->cber & CBCERR) { ! 140: printf("cache\n"); ! 141: if (time < lastcache + 5) { ! 142: cacheon = 0; ! 143: printf("turned off\n"); ! 144: } ! 145: lastcache = time; ! 146: } ! 147: if (f->cber & CBTERR) ! 148: printf("tbuf\n"); ! 149: if (f->cber & CBRDS) ! 150: printf("mchk hard mem err\n"); ! 151: /* call mem err intr? */ ! 152: mtpr(COR, cacheon); ! 153: if (f->mcsts & MCABORT) ! 154: return (0); ! 155: if (f->iber & IBOXBAD ! 156: || f->cber & CBOXBAD) ! 157: return (0); ! 158: if ((f->nmifsr & FSRBCOD) != 0) ! 159: return (0); ! 160: for (x = f->eber, i = 0; i < 4; x >>= 8, i++) { ! 161: if (x & EBAERR) ! 162: switch (x & EBASRC) { ! 163: case 0: ! 164: case 4: ! 165: return (0); ! 166: } ! 167: if (x & EBBERR) ! 168: switch (x & EBBSRC) { ! 169: case 4: ! 170: return (0); ! 171: } ! 172: } ! 173: return (1); ! 174: } ! 175: ! 176: /* ! 177: * reset things after a machine check ! 178: */ ! 179: ! 180: machreset() ! 181: { ! 182: register junk; ! 183: ! 184: mtpr(MCSTS, mfpr(MCSTS)); ! 185: if (mcrcsr) ! 186: junk = mcrcsr[5]; ! 187: mtpr(CLRTOS, 0); ! 188: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.