Annotation of researchv10dc/sys/md/mchkstar.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * routines that deal closely with
        !             3:  * machine checks and the like
        !             4:  * VAX-11/780 version
        !             5:  */
        !             6: 
        !             7: #include "sys/param.h"
        !             8: #include "sys/systm.h"
        !             9: #include "sys/psl.h"
        !            10: #include "sys/mtpr.h"
        !            11: #include "sys/user.h"
        !            12: 
        !            13: /*
        !            14:  * SBI-related registers
        !            15:  */
        !            16: 
        !            17: #define        SBIFS   48              /* SBI fault and status */
        !            18: #define        SBIMT   51              /* SBI and cache maint */
        !            19: #define        SBIER   52              /* SBI error */
        !            20: #define        SBITA   53              /* SBI timeout address */
        !            21: 
        !            22: #define        FSNEF   0x2000000       /* nested error flag in fault status */
        !            23: #define        FSIE    0x40000         /* interrupt enable for sbi faults */
        !            24: 
        !            25: #define        ERCLR   0x70c0          /* latches in error register: */
        !            26:                                /* ib timeout, ib rds, cp timeout, rds, crd */
        !            27: 
        !            28: #define        TAMODE  0xc0000000      /* mode of failure for wtmo, 3 == user */
        !            29: #define        TAPROT  0x20000000      /* protection checked reference; off -> pt */
        !            30: 
        !            31: struct mframe {
        !            32:        long count;
        !            33:        long type;
        !            34:        long ces;
        !            35:        long upc;
        !            36:        long vaddr;
        !            37:        long dr;
        !            38:        long tb0;
        !            39:        long tb1;
        !            40:        long paddr;
        !            41:        long par;
        !            42:        long sbi;
        !            43:        long pc;
        !            44:        long psl;
        !            45: };
        !            46: 
        !            47: #define        NMCK    16              /* number of possible type codes */
        !            48: static char *macher[NMCK] = {
        !            49:        "read timeout",
        !            50:        "control store parity",
        !            51:        "trans buffer parity",
        !            52:        "cache parity",
        !            53:        "-",
        !            54:        "read data substitute",
        !            55:        "microcode lost",
        !            56:        "-",
        !            57:        "-",
        !            58:        "-",
        !            59:        "ib trans buffer parity",
        !            60:        "-",
        !            61:        "ib read data substitute",
        !            62:        "ib read timeout",
        !            63:        "-",
        !            64:        "ib cache parity",
        !            65: };
        !            66: 
        !            67: int mchkcnt[NMCK];     /* number of mchecks of each type */
        !            68: int mchktime[NMCK];    /* time of last mcheck */
        !            69: 
        !            70: /*
        !            71:  * table of resumable instructions
        !            72:  * a table of bits, indexed by opcode
        !            73:  * this is taken straight from vms;
        !            74:  * don't ask me to justify choices
        !            75:  */
        !            76: 
        !            77: static char mrestab[256/8] = {
        !            78:        0x3b,   /* rei ldpctx svpctx */
        !            79:        0x3c,   /* insque remque cvtps cvtsp */
        !            80:        0xff,
        !            81:        0xff,
        !            82:        0x0,    /* packed decimal stuff */
        !            83:        0xff,
        !            84:        0xff,
        !            85:        0xfe,   /* editpc */
        !            86:        0xff,
        !            87:        0xff,
        !            88:        0x2f,   /* emodf cvtfd adawi */
        !            89:        0x0,    /* more interlocked instructions */
        !            90:        0x0,    /* double precision floating point */
        !            91:        0x0f,   /* more double stuff */
        !            92:        0x4a,   /* more double/quad */
        !            93:        0xc1,   /* .. */
        !            94:        0xff,
        !            95:        0xff,
        !            96:        0xff,
        !            97:        0xff,
        !            98:        0xff,
        !            99:        0xff,
        !           100:        0xff,
        !           101:        0xf3,   /* pushr popr */
        !           102:        0xff,
        !           103:        0xff,
        !           104:        0xff,
        !           105:        0xf4,   /* adwc sbwc mfpr */
        !           106:        0x3f,   /* bbssi bbcci */
        !           107:        0xff,
        !           108:        0xff,
        !           109:        0x0,    /* ashp cvtlp callg calls xfc reserved */
        !           110: };
        !           111: 
        !           112: /*
        !           113:  * bits in machine check type code
        !           114:  */
        !           115: 
        !           116: #define        TYPE    0xf             /* the real type code */
        !           117: #define        IB      0x8             /* set if detected by instruction prefetch */
        !           118: #define        ABORT   0xf0            /* this was an abort */
        !           119: #define        TIMEOUT 0x100           /* timeout pending */
        !           120: 
        !           121: /*
        !           122:  * types
        !           123:  */
        !           124: 
        !           125: #define        CPTIMEOUT       0       /* read timeout */
        !           126: #define        CSPAR           1       /* control store parity */
        !           127: #define        TBUFPAR         2       /* translation buffer parity */
        !           128: #define        CACHEPAR        3       /* cache parity */
        !           129: #define        RDSUBST         5       /* read data substitute */
        !           130: #define        IBROMCHK        6       /* confused microcode */
        !           131: #define        IBTBUF          10      /* ib-detected translation buffer parity */
        !           132: #define        IBRDSUB         12      /* ib-detected read substitute */
        !           133: #define        IBTIMEOUT       13      /* ib-detected read timeout */
        !           134: #define        IBCACHE         15      /* ib-detected cache parity */
        !           135: 
        !           136: /*
        !           137:  * bits in cache error register
        !           138:  */
        !           139: 
        !           140: #define        G0OK    0x3f8           /* `ok' bits for group 0 */
        !           141: 
        !           142: /*
        !           143:  * bits in sbi maint register
        !           144:  */
        !           145: 
        !           146: #define        G1REPL  0x2000          /* force replace in group 1 */
        !           147: #define        G0REPL  0x4000          /* force replace in group 0 */
        !           148: #define        G1MISS  0x8000          /* force miss in group 1 */
        !           149: #define        G0MISS  0x10000         /* force miss in group 0 */
        !           150: #define        SBIINV  0x200000        /* enable sbi invalidate */
        !           151: 
        !           152: #define        CACHEOFF        (G0REPL|G1MISS|G0MISS|SBIINV)
        !           153: 
        !           154: static int mchkkill;   /* number of times we've recovered by killing */
        !           155: static int mchklock;   /* reentrancy lock */
        !           156: static int mchkcache = SBIINV; /* current state of cache disable bits */
        !           157: 
        !           158: /*
        !           159:  * sbi fault
        !           160:  * yell and hope for the best
        !           161:  */
        !           162: 
        !           163: sbifault()
        !           164: {
        !           165:        register int fs, er;
        !           166: 
        !           167:        fs = mfpr(SBIFS);
        !           168:        er = mfpr(SBIER);
        !           169:        machreset();
        !           170:        printf("sbi fault: fs %x er %x\n", fs, er);
        !           171: }
        !           172: 
        !           173: /*
        !           174:  * SBI write timeout
        !           175:  * no recovery;
        !           176:  * panic if kernel or if updating page table
        !           177:  * else just signal
        !           178:  */
        !           179: 
        !           180: machwtmo()
        !           181: {
        !           182:        register int fs, er, ta;
        !           183: 
        !           184:        fs = mfpr(SBIFS);
        !           185:        er = mfpr(SBIER);
        !           186:        ta = mfpr(SBITA);
        !           187:        machreset();
        !           188:        printf("sbi write timeout: fs %x er %x ta %x\n", fs, er, ta);
        !           189:        if ((ta & (TAMODE | TAPROT)) != (TAMODE | TAPROT))
        !           190:                panic("wtmo");
        !           191:        runrun++;
        !           192:        aston();
        !           193:        psignal(u.u_procp, SIGBUS);
        !           194: }
        !           195: 
        !           196: /*
        !           197:  * clear latches in sbi error registers
        !           198:  */
        !           199: 
        !           200: machreset()
        !           201: {
        !           202:        mtpr(SBIFS, (mfpr(SBIFS) &~ FSNEF)|FSIE);
        !           203:        mtpr(SBIER, mfpr(SBIER) | ERCLR);
        !           204: }
        !           205: 
        !           206: /*
        !           207:  * Machine check.
        !           208:  * If possible, recover and return;
        !           209:  * if not but in user mode, send a signal;
        !           210:  * if not and in kernel mode, panic.
        !           211:  */
        !           212: 
        !           213: machinecheck(ps, f)
        !           214: long ps;
        !           215: struct mframe *f;
        !           216: {
        !           217:        int ok;
        !           218: 
        !           219:        ok = mckrec(f);
        !           220:        machreset();
        !           221:        printf("\nMachine check, type %x\n", f->type);
        !           222:        if ((f->type & ABORT) == 0)
        !           223:                printf("%s fault\n", macher[f->type & TYPE]);
        !           224:        else
        !           225:                printf("%s abort\n", macher[f->type & TYPE]);
        !           226:        printf("pc %x psl %x\n", f->pc, f->psl);
        !           227:        printf("v/p addr %x/%x\n", f->vaddr, f->paddr<<2);
        !           228:        printf("ces %x sbi %x\n", f->ces, f->sbi);
        !           229:        if (ok)
        !           230:                return;
        !           231:        if (USERMODE(ps)) {
        !           232:                /*
        !           233:                 * code stolen from setrun
        !           234:                 */
        !           235:                runrun++;
        !           236:                aston();
        !           237:                psignal(u.u_procp, SIGBUS);
        !           238:                return;
        !           239:        }
        !           240:        panic("mchk");
        !           241: }
        !           242: 
        !           243: /*
        !           244:  * here to look at machine check type
        !           245:  * and arrange for recovery if possible
        !           246:  * cache is still turned off when we start
        !           247:  * return nonzero if we recovered
        !           248:  */
        !           249: 
        !           250: int
        !           251: mckrec(f)
        !           252: register struct mframe *f;
        !           253: {
        !           254:        register int x;
        !           255: 
        !           256:        mchkcnt[f->type & TYPE]++;
        !           257:        switch (f->type & TYPE) {
        !           258:        case TBUFPAR:           /* trans buffer parity */
        !           259:        case IBTBUF:
        !           260:                mtpr(TBIA, 0);  /* clear the buffer */
        !           261:                mtpr(SBIMT, mchkcache);
        !           262:                break;
        !           263: 
        !           264:        case IBROMCHK:          /* unexpected microcode confusion */
        !           265:        case CSPAR:             /* control store parity */
        !           266:                mtpr(SBIMT, mchkcache);
        !           267:                return (0);     /* can never recover */
        !           268: 
        !           269:        case CACHEPAR:          /* cache parity error */
        !           270:        case IBCACHE:
        !           271:                /*
        !           272:                 * force bad stuff to be replaced
        !           273:                 * in both cache groups
        !           274:                 */
        !           275:                x = *(char *)f->vaddr;
        !           276:                mtpr(SBIMT, CACHEOFF);
        !           277:                x = 0;          /* defeat optimizer */
        !           278:                x = *(char *)f->vaddr;
        !           279:                if ((f->par & G0OK) != G0OK) {
        !           280:                        printf("group 0 off\n");
        !           281:                        mchkcache |= G0MISS | G0REPL;
        !           282:                        mchkcache &=~ G1REPL;   /* don't replace both groups */
        !           283:                }
        !           284:                else {
        !           285:                        printf("group 1 off\n");
        !           286:                        mchkcache |= G1MISS | G1REPL;
        !           287:                        mchkcache &=~ G0REPL;
        !           288:                }
        !           289:                mtpr(SBIMT, mchkcache);
        !           290:                break;
        !           291: 
        !           292:        case CPTIMEOUT:
        !           293:        case IBTIMEOUT:
        !           294:                mtpr(SBIMT, mchkcache);
        !           295:                break;
        !           296: 
        !           297:        case RDSUBST:           /* read data substitute == hard mem err */
        !           298:        case IBRDSUB:
        !           299:                mtpr(SBIMT, mchkcache);
        !           300:                memerr();
        !           301:                return (0);
        !           302: 
        !           303:        default:
        !           304:                mtpr(SBIMT, mchkcache);
        !           305:                panic("weird mcheck");
        !           306:        }
        !           307:        /*
        !           308:         * if we get here, it's potentially recoverable
        !           309:         * may recover if:
        !           310:         * haven't had one in the last second
        !           311:         * not an abort or timeout
        !           312:         * detected by lookahead, or resumable instruction
        !           313:         */
        !           314:        if (mchktime[f->type & TYPE] == time)
        !           315:                return (0);
        !           316:        mchktime[f->type & TYPE] = time;
        !           317:        if (f->type & (ABORT | TIMEOUT))
        !           318:                return (0);
        !           319:        if (f->type & IB)
        !           320:                return (1);
        !           321:        x = *(char *)f->pc & 0377;
        !           322:        if (mrestab[x >> 3] & (1 << (x & 07)))
        !           323:                return (1);
        !           324:        return (0);
        !           325: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.