Annotation of 43BSD/sys/vax/machdep.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 1986 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  *
        !             6:  *     @(#)machdep.c   7.1 (Berkeley) 6/5/86
        !             7:  */
        !             8: 
        !             9: #include "reg.h"
        !            10: #include "pte.h"
        !            11: #include "psl.h"
        !            12: 
        !            13: #include "param.h"
        !            14: #include "systm.h"
        !            15: #include "dir.h"
        !            16: #include "user.h"
        !            17: #include "kernel.h"
        !            18: #include "map.h"
        !            19: #include "vm.h"
        !            20: #include "proc.h"
        !            21: #include "buf.h"
        !            22: #include "reboot.h"
        !            23: #include "conf.h"
        !            24: #include "inode.h"
        !            25: #include "file.h"
        !            26: #include "text.h"
        !            27: #include "clist.h"
        !            28: #include "callout.h"
        !            29: #include "cmap.h"
        !            30: #include "mbuf.h"
        !            31: #include "msgbuf.h"
        !            32: #include "quota.h"
        !            33: 
        !            34: #include "frame.h"
        !            35: #include "clock.h"
        !            36: #include "cons.h"
        !            37: #include "cpu.h"
        !            38: #include "mem.h"
        !            39: #include "mtpr.h"
        !            40: #include "rpb.h"
        !            41: #include "ka630.h"
        !            42: #include "../vaxuba/ubavar.h"
        !            43: #include "../vaxuba/ubareg.h"
        !            44: 
        !            45: /*
        !            46:  * Declare these as initialized data so we can patch them.
        !            47:  */
        !            48: int    nswbuf = 0;
        !            49: #ifdef NBUF
        !            50: int    nbuf = NBUF;
        !            51: #else
        !            52: int    nbuf = 0;
        !            53: #endif
        !            54: #ifdef BUFPAGES
        !            55: int    bufpages = BUFPAGES;
        !            56: #else
        !            57: int    bufpages = 0;
        !            58: #endif
        !            59: 
        !            60: /*
        !            61:  * Machine-dependent startup code
        !            62:  */
        !            63: startup(firstaddr)
        !            64:        int firstaddr;
        !            65: {
        !            66:        register int unixsize;
        !            67:        register unsigned i;
        !            68:        register struct pte *pte;
        !            69:        int mapaddr, j;
        !            70:        register caddr_t v;
        !            71:        int maxbufs, base, residual;
        !            72: 
        !            73: #if VAX630
        !            74:        /*
        !            75:         * Leave last 5k of phys. memory as console work area.
        !            76:         */
        !            77:        if (cpu == VAX_630)
        !            78:                maxmem -= 10;
        !            79: #endif
        !            80:        /*
        !            81:         * Initialize error message buffer (at end of core).
        !            82:         */
        !            83:        maxmem -= btoc(sizeof (struct msgbuf));
        !            84:        pte = msgbufmap;
        !            85:        for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
        !            86:                *(int *)pte++ = PG_V | PG_KW | (maxmem + i);
        !            87:        mtpr(TBIA, 0);
        !            88: 
        !            89:        /*
        !            90:         * Good {morning,afternoon,evening,night}.
        !            91:         */
        !            92:        printf(version);
        !            93:        printf("real mem  = %d\n", ctob(physmem));
        !            94: 
        !            95:        /*
        !            96:         * Allocate space for system data structures.
        !            97:         * The first available real memory address is in "firstaddr".
        !            98:         * The first available kernel virtual address is in "v".
        !            99:         * As pages of kernel virtual memory are allocated, "v" is incremented.
        !           100:         * As pages of memory are allocated and cleared,
        !           101:         * "firstaddr" is incremented.
        !           102:         * An index into the kernel page table corresponding to the
        !           103:         * virtual memory address maintained in "v" is kept in "mapaddr".
        !           104:         */
        !           105:        v = (caddr_t)(0x80000000 | (firstaddr * NBPG));
        !           106: #define        valloc(name, type, num) \
        !           107:            (name) = (type *)v; v = (caddr_t)((name)+(num))
        !           108: #define        valloclim(name, type, num, lim) \
        !           109:            (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
        !           110:        valloclim(inode, struct inode, ninode, inodeNINODE);
        !           111:        valloclim(file, struct file, nfile, fileNFILE);
        !           112:        valloclim(proc, struct proc, nproc, procNPROC);
        !           113:        valloclim(text, struct text, ntext, textNTEXT);
        !           114:        valloc(cfree, struct cblock, nclist);
        !           115:        valloc(callout, struct callout, ncallout);
        !           116:        valloc(swapmap, struct map, nswapmap = nproc * 2);
        !           117:        valloc(argmap, struct map, ARGMAPSIZE);
        !           118:        valloc(kernelmap, struct map, nproc);
        !           119:        valloc(mbmap, struct map, nmbclusters/4);
        !           120:        valloc(namecache, struct namecache, nchsize);
        !           121: #ifdef QUOTA
        !           122:        valloclim(quota, struct quota, nquota, quotaNQUOTA);
        !           123:        valloclim(dquot, struct dquot, ndquot, dquotNDQUOT);
        !           124: #endif
        !           125:        
        !           126:        /*
        !           127:         * Determine how many buffers to allocate.
        !           128:         * Use 10% of memory for the first 2 Meg, 5% of the remaining
        !           129:         * memory. Insure a minimum of 16 buffers.
        !           130:         * We allocate 1/2 as many swap buffer headers as file i/o buffers.
        !           131:         */
        !           132:        if (bufpages == 0)
        !           133:                if (physmem < (2 * 1024 * CLSIZE))
        !           134:                        bufpages = physmem / 10 / CLSIZE;
        !           135:                else
        !           136:                        bufpages = ((2 * 1024 * CLSIZE + physmem) / 20) / CLSIZE;
        !           137:        if (nbuf == 0) {
        !           138:                nbuf = bufpages / 2;
        !           139:                if (nbuf < 16)
        !           140:                        nbuf = 16;
        !           141:        }
        !           142:        if (nswbuf == 0) {
        !           143:                nswbuf = (nbuf / 2) &~ 1;       /* force even */
        !           144:                if (nswbuf > 256)
        !           145:                        nswbuf = 256;           /* sanity */
        !           146:        }
        !           147:        valloc(swbuf, struct buf, nswbuf);
        !           148: 
        !           149:        /*
        !           150:         * Now the amount of virtual memory remaining for buffers
        !           151:         * can be calculated, estimating needs for the cmap.
        !           152:         */
        !           153:        ncmap = (maxmem*NBPG - ((int)v &~ 0x80000000)) /
        !           154:                (CLBYTES + sizeof(struct cmap)) + 2;
        !           155:        maxbufs = ((SYSPTSIZE * NBPG) -
        !           156:            ((int)(v + ncmap * sizeof(struct cmap)) - 0x80000000)) /
        !           157:                (MAXBSIZE + sizeof(struct buf));
        !           158:        if (maxbufs < 16)
        !           159:                panic("sys pt too small");
        !           160:        if (nbuf > maxbufs) {
        !           161:                printf("SYSPTSIZE limits number of buffers to %d\n", maxbufs);
        !           162:                nbuf = maxbufs;
        !           163:        }
        !           164:        if (bufpages > nbuf * (MAXBSIZE / CLBYTES))
        !           165:                bufpages = nbuf * (MAXBSIZE / CLBYTES);
        !           166:        valloc(buf, struct buf, nbuf);
        !           167: 
        !           168:        /*
        !           169:         * Allocate space for core map.
        !           170:         * Allow space for all of phsical memory minus the amount 
        !           171:         * dedicated to the system. The amount of physical memory
        !           172:         * dedicated to the system is the total virtual memory of
        !           173:         * the system thus far, plus core map, buffer pages,
        !           174:         * and buffer headers not yet allocated.
        !           175:         * Add 2: 1 because the 0th entry is unused, 1 for rounding.
        !           176:         */
        !           177:        ncmap = (maxmem*NBPG - ((int)(v + bufpages*CLBYTES) &~ 0x80000000)) /
        !           178:                (CLBYTES + sizeof(struct cmap)) + 2;
        !           179:        valloclim(cmap, struct cmap, ncmap, ecmap);
        !           180: 
        !           181:        /*
        !           182:         * Clear space allocated thus far, and make r/w entries
        !           183:         * for the space in the kernel map.
        !           184:         */
        !           185:        unixsize = btoc((int)v &~ 0x80000000);
        !           186:        while (firstaddr < unixsize) {
        !           187:                *(int *)(&Sysmap[firstaddr]) = PG_V | PG_KW | firstaddr;
        !           188:                clearseg((unsigned)firstaddr);
        !           189:                firstaddr++;
        !           190:        }
        !           191: 
        !           192:        /*
        !           193:         * Now allocate buffers proper.  They are different than the above
        !           194:         * in that they usually occupy more virtual memory than physical.
        !           195:         */
        !           196:        v = (caddr_t) ((int)(v + PGOFSET) &~ PGOFSET);
        !           197:        valloc(buffers, char, MAXBSIZE * nbuf);
        !           198:        base = bufpages / nbuf;
        !           199:        residual = bufpages % nbuf;
        !           200:        mapaddr = firstaddr;
        !           201:        for (i = 0; i < residual; i++) {
        !           202:                for (j = 0; j < (base + 1) * CLSIZE; j++) {
        !           203:                        *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr;
        !           204:                        clearseg((unsigned)firstaddr);
        !           205:                        firstaddr++;
        !           206:                }
        !           207:                mapaddr += MAXBSIZE / NBPG;
        !           208:        }
        !           209:        for (i = residual; i < nbuf; i++) {
        !           210:                for (j = 0; j < base * CLSIZE; j++) {
        !           211:                        *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr;
        !           212:                        clearseg((unsigned)firstaddr);
        !           213:                        firstaddr++;
        !           214:                }
        !           215:                mapaddr += MAXBSIZE / NBPG;
        !           216:        }
        !           217: 
        !           218:        unixsize = btoc((int)v &~ 0x80000000);
        !           219:        if (firstaddr >= physmem - 8*UPAGES)
        !           220:                panic("no memory");
        !           221:        mtpr(TBIA, 0);                  /* After we just cleared it all! */
        !           222: 
        !           223:        /*
        !           224:         * Initialize callouts
        !           225:         */
        !           226:        callfree = callout;
        !           227:        for (i = 1; i < ncallout; i++)
        !           228:                callout[i-1].c_next = &callout[i];
        !           229: 
        !           230:        /*
        !           231:         * Initialize memory allocator and swap
        !           232:         * and user page table maps.
        !           233:         *
        !           234:         * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''
        !           235:         * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.
        !           236:         */
        !           237:        meminit(firstaddr, maxmem);
        !           238:        maxmem = freemem;
        !           239:        printf("avail mem = %d\n", ctob(maxmem));
        !           240:        printf("using %d buffers containing %d bytes of memory\n",
        !           241:                nbuf, bufpages * CLBYTES);
        !           242:        rminit(kernelmap, (long)USRPTSIZE, (long)1,
        !           243:            "usrpt", nproc);
        !           244:        rminit(mbmap, (long)(nmbclusters * CLSIZE), (long)CLSIZE,
        !           245:            "mbclusters", nmbclusters/4);
        !           246: 
        !           247:        /*
        !           248:         * Set up CPU-specific registers, cache, etc.
        !           249:         */
        !           250:        initcpu();
        !           251: 
        !           252:        /*
        !           253:         * Configure the system.
        !           254:         */
        !           255:        configure();
        !           256: 
        !           257:        /*
        !           258:         * Clear restart inhibit flags.
        !           259:         */
        !           260:        tocons(TXDB_CWSI);
        !           261:        tocons(TXDB_CCSI);
        !           262: }
        !           263: 
        !           264: #ifdef PGINPROF
        !           265: /*
        !           266:  * Return the difference (in microseconds)
        !           267:  * between the  current time and a previous
        !           268:  * time as represented  by the arguments.
        !           269:  * If there is a pending clock interrupt
        !           270:  * which has not been serviced due to high
        !           271:  * ipl, return error code.
        !           272:  */
        !           273: vmtime(otime, olbolt, oicr)
        !           274:        register int otime, olbolt, oicr;
        !           275: {
        !           276: 
        !           277:        if (mfpr(ICCS)&ICCS_INT)
        !           278:                return(-1);
        !           279:        else
        !           280:                return(((time.tv_sec-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr);
        !           281: }
        !           282: #endif
        !           283: 
        !           284: /*
        !           285:  * Clear registers on exec
        !           286:  */
        !           287: setregs(entry)
        !           288:        u_long entry;
        !           289: {
        !           290: #ifdef notdef
        !           291:        register int *rp;
        !           292: 
        !           293:        /* should pass args to init on the stack */
        !           294:        /* should also fix this code before using it, it's wrong */
        !           295:        /* wanna clear the scb? */
        !           296:        for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
        !           297:                *rp++ = 0;
        !           298: #endif
        !           299:        u.u_ar0[PC] = entry + 2;
        !           300: }
        !           301: 
        !           302: /*
        !           303:  * Send an interrupt to process.
        !           304:  *
        !           305:  * Stack is set up to allow sigcode stored
        !           306:  * in u. to call routine, followed by chmk
        !           307:  * to sigreturn routine below.  After sigreturn
        !           308:  * resets the signal mask, the stack, the frame 
        !           309:  * pointer, and the argument pointer, it returns
        !           310:  * to the user specified pc, psl.
        !           311:  */
        !           312: sendsig(p, sig, mask)
        !           313:        int (*p)(), sig, mask;
        !           314: {
        !           315:        register struct sigcontext *scp;
        !           316:        register int *regs;
        !           317:        register struct sigframe {
        !           318:                int     sf_signum;
        !           319:                int     sf_code;
        !           320:                struct  sigcontext *sf_scp;
        !           321:                int     (*sf_handler)();
        !           322:                int     sf_argcount;
        !           323:                struct  sigcontext *sf_scpcopy;
        !           324:        } *fp;
        !           325:        int oonstack;
        !           326: 
        !           327:        regs = u.u_ar0;
        !           328:        oonstack = u.u_onstack;
        !           329:        /*
        !           330:         * Allocate and validate space for the signal handler
        !           331:         * context. Note that if the stack is in P0 space, the
        !           332:         * call to grow() is a nop, and the useracc() check
        !           333:         * will fail if the process has not already allocated
        !           334:         * the space with a `brk'.
        !           335:         */
        !           336:        if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) {
        !           337:                scp = (struct sigcontext *)u.u_sigsp - 1;
        !           338:                u.u_onstack = 1;
        !           339:        } else
        !           340:                scp = (struct sigcontext *)regs[SP] - 1;
        !           341:        fp = (struct sigframe *)scp - 1;
        !           342:        if ((int)fp <= USRSTACK - ctob(u.u_ssize)) 
        !           343:                (void)grow((unsigned)fp);
        !           344:        if (useracc((caddr_t)fp, sizeof (*fp) + sizeof (*scp), B_WRITE) == 0) {
        !           345:                /*
        !           346:                 * Process has trashed its stack; give it an illegal
        !           347:                 * instruction to halt it in its tracks.
        !           348:                 */
        !           349:                u.u_signal[SIGILL] = SIG_DFL;
        !           350:                sig = sigmask(SIGILL);
        !           351:                u.u_procp->p_sigignore &= ~sig;
        !           352:                u.u_procp->p_sigcatch &= ~sig;
        !           353:                u.u_procp->p_sigmask &= ~sig;
        !           354:                psignal(u.u_procp, SIGILL);
        !           355:                return;
        !           356:        }
        !           357:        /* 
        !           358:         * Build the argument list for the signal handler.
        !           359:         */
        !           360:        fp->sf_signum = sig;
        !           361:        if (sig == SIGILL || sig == SIGFPE) {
        !           362:                fp->sf_code = u.u_code;
        !           363:                u.u_code = 0;
        !           364:        } else
        !           365:                fp->sf_code = 0;
        !           366:        fp->sf_scp = scp;
        !           367:        fp->sf_handler = p;
        !           368:        /*
        !           369:         * Build the calls argument frame to be used to call sigreturn
        !           370:         */
        !           371:        fp->sf_argcount = 1;
        !           372:        fp->sf_scpcopy = scp;
        !           373:        /*
        !           374:         * Build the signal context to be used by sigreturn.
        !           375:         */
        !           376:        scp->sc_onstack = oonstack;
        !           377:        scp->sc_mask = mask;
        !           378:        scp->sc_sp = regs[SP];
        !           379:        scp->sc_fp = regs[FP];
        !           380:        scp->sc_ap = regs[AP];
        !           381:        scp->sc_pc = regs[PC];
        !           382:        scp->sc_ps = regs[PS];
        !           383:        regs[SP] = (int)fp;
        !           384:        regs[PS] &= ~(PSL_CM|PSL_FPD);
        !           385:        regs[PC] = (int)u.u_pcb.pcb_sigc;
        !           386:        return;
        !           387: }
        !           388: 
        !           389: /*
        !           390:  * System call to cleanup state after a signal
        !           391:  * has been taken.  Reset signal mask and
        !           392:  * stack state from context left by sendsig (above).
        !           393:  * Return to previous pc and psl as specified by
        !           394:  * context left by sendsig. Check carefully to
        !           395:  * make sure that the user has not modified the
        !           396:  * psl to gain improper priviledges or to cause
        !           397:  * a machine fault.
        !           398:  */
        !           399: sigreturn()
        !           400: {
        !           401:        struct a {
        !           402:                struct sigcontext *sigcntxp;
        !           403:        };
        !           404:        register struct sigcontext *scp;
        !           405:        register int *regs = u.u_ar0;
        !           406: 
        !           407:        scp = ((struct a *)(u.u_ap))->sigcntxp;
        !           408:        if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0)
        !           409:                return;
        !           410:        if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_IS)) != 0 ||
        !           411:            (scp->sc_ps & (PSL_PRVMOD|PSL_CURMOD)) != (PSL_PRVMOD|PSL_CURMOD) ||
        !           412:            ((scp->sc_ps & PSL_CM) &&
        !           413:             (scp->sc_ps & (PSL_FPD|PSL_DV|PSL_FU|PSL_IV)) != 0)) {
        !           414:                u.u_error = EINVAL;
        !           415:                return;
        !           416:        }
        !           417:        u.u_eosys = JUSTRETURN;
        !           418:        u.u_onstack = scp->sc_onstack & 01;
        !           419:        u.u_procp->p_sigmask = scp->sc_mask &~
        !           420:            (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
        !           421:        regs[FP] = scp->sc_fp;
        !           422:        regs[AP] = scp->sc_ap;
        !           423:        regs[SP] = scp->sc_sp;
        !           424:        regs[PC] = scp->sc_pc;
        !           425:        regs[PS] = scp->sc_ps;
        !           426: }
        !           427: 
        !           428: /* XXX - BEGIN 4.2 COMPATIBILITY */
        !           429: /*
        !           430:  * Compatibility with 4.2 chmk $139 used by longjmp()
        !           431:  */
        !           432: osigcleanup()
        !           433: {
        !           434:        register struct sigcontext *scp;
        !           435:        register int *regs = u.u_ar0;
        !           436: 
        !           437:        scp = (struct sigcontext *)fuword((caddr_t)regs[SP]);
        !           438:        if ((int)scp == -1)
        !           439:                return;
        !           440:        if (useracc((caddr_t)scp, 3 * sizeof (int), B_WRITE) == 0)
        !           441:                return;
        !           442:        u.u_onstack = scp->sc_onstack & 01;
        !           443:        u.u_procp->p_sigmask = scp->sc_mask &~
        !           444:            (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
        !           445:        regs[SP] = scp->sc_sp;
        !           446: }
        !           447: /* XXX - END 4.2 COMPATIBILITY */
        !           448: 
        !           449: #ifdef notdef
        !           450: dorti()
        !           451: {
        !           452:        struct frame frame;
        !           453:        register int sp;
        !           454:        register int reg, mask;
        !           455:        extern int ipcreg[];
        !           456: 
        !           457:        (void) copyin((caddr_t)u.u_ar0[FP], (caddr_t)&frame, sizeof (frame));
        !           458:        sp = u.u_ar0[FP] + sizeof (frame);
        !           459:        u.u_ar0[PC] = frame.fr_savpc;
        !           460:        u.u_ar0[FP] = frame.fr_savfp;
        !           461:        u.u_ar0[AP] = frame.fr_savap;
        !           462:        mask = frame.fr_mask;
        !           463:        for (reg = 0; reg <= 11; reg++) {
        !           464:                if (mask&1) {
        !           465:                        u.u_ar0[ipcreg[reg]] = fuword((caddr_t)sp);
        !           466:                        sp += 4;
        !           467:                }
        !           468:                mask >>= 1;
        !           469:        }
        !           470:        sp += frame.fr_spa;
        !           471:        u.u_ar0[PS] = (u.u_ar0[PS] & 0xffff0000) | frame.fr_psw;
        !           472:        if (frame.fr_s)
        !           473:                sp += 4 + 4 * (fuword((caddr_t)sp) & 0xff);
        !           474:        /* phew, now the rei */
        !           475:        u.u_ar0[PC] = fuword((caddr_t)sp);
        !           476:        sp += 4;
        !           477:        u.u_ar0[PS] = fuword((caddr_t)sp);
        !           478:        sp += 4;
        !           479:        u.u_ar0[PS] |= PSL_USERSET;
        !           480:        u.u_ar0[PS] &= ~PSL_USERCLR;
        !           481:        u.u_ar0[SP] = (int)sp;
        !           482: }
        !           483: #endif
        !           484: 
        !           485: /*
        !           486:  * Memenable enables the memory controlle corrected data reporting.
        !           487:  * This runs at regular intervals, turning on the interrupt.
        !           488:  * The interrupt is turned off, per memory controller, when error
        !           489:  * reporting occurs.  Thus we report at most once per memintvl.
        !           490:  */
        !           491: int    memintvl = MEMINTVL;
        !           492: 
        !           493: memenable()
        !           494: {
        !           495:        register struct mcr *mcr;
        !           496:        register int m;
        !           497: 
        !           498: #if VAX630
        !           499:        if (cpu == VAX_630)
        !           500:                return;
        !           501: #endif
        !           502: #ifdef VAX8600
        !           503:        if (cpu == VAX_8600) {
        !           504:                M8600_ENA;
        !           505:        } else
        !           506: #endif
        !           507:        for (m = 0; m < nmcr; m++) {
        !           508:                mcr = mcraddr[m];
        !           509:                switch (mcrtype[m]) {
        !           510: #if VAX780
        !           511:                case M780C:
        !           512:                        M780C_ENA(mcr);
        !           513:                        break;
        !           514:                case M780EL:
        !           515:                        M780EL_ENA(mcr);
        !           516:                        break;
        !           517:                case M780EU:
        !           518:                        M780EU_ENA(mcr);
        !           519:                        break;
        !           520: #endif
        !           521: #if VAX750
        !           522:                case M750:
        !           523:                        M750_ENA(mcr);
        !           524:                        break;
        !           525: #endif
        !           526: #if VAX730
        !           527:                case M730:
        !           528:                        M730_ENA(mcr);
        !           529:                        break;
        !           530: #endif
        !           531:                }
        !           532:        }
        !           533:        if (memintvl > 0)
        !           534:                timeout(memenable, (caddr_t)0, memintvl*hz);
        !           535: }
        !           536: 
        !           537: /*
        !           538:  * Memerr is the interrupt routine for corrected read data
        !           539:  * interrupts.  It looks to see which memory controllers have
        !           540:  * unreported errors, reports them, and disables further
        !           541:  * reporting for a time on those controller.
        !           542:  */
        !           543: memerr()
        !           544: {
        !           545: #ifdef VAX8600
        !           546:        register int reg11;     /* known to be r11 below */
        !           547: #endif
        !           548:        register struct mcr *mcr;
        !           549:        register int m;
        !           550: 
        !           551: #if VAX630
        !           552:        if (cpu == VAX_630)
        !           553:                return;
        !           554: #endif
        !           555: #ifdef VAX8600
        !           556:        if (cpu == VAX_8600) {
        !           557:                int mdecc, mear, mstat1, mstat2, array;
        !           558: 
        !           559:                /*
        !           560:                 * Scratchpad registers in the Ebox must be read by
        !           561:                 * storing their ID number in ESPA and then immediately
        !           562:                 * reading ESPD's contents with no other intervening
        !           563:                 * machine instructions!
        !           564:                 *
        !           565:                 * The asm's below have a number of constants which
        !           566:                 * are defined correctly in mem.h and mtpr.h.
        !           567:                 */
        !           568: #ifdef lint
        !           569:                reg11 = 0;
        !           570: #else
        !           571:                asm("mtpr $0x27,$0x4e; mfpr $0x4f,r11");
        !           572: #endif
        !           573:                mdecc = reg11;  /* must acknowledge interrupt? */
        !           574:                if (M8600_MEMERR(mdecc)) {
        !           575:                        asm("mtpr $0x2a,$0x4e; mfpr $0x4f,r11");
        !           576:                        mear = reg11;
        !           577:                        asm("mtpr $0x25,$0x4e; mfpr $0x4f,r11");
        !           578:                        mstat1 = reg11;
        !           579:                        asm("mtpr $0x26,$0x4e; mfpr $0x4f,r11");
        !           580:                        mstat2 = reg11;
        !           581:                        array = M8600_ARRAY(mear);
        !           582: 
        !           583:                        printf("mcr0: ecc error, addr %x (array %d) syn %x\n",
        !           584:                                M8600_ADDR(mear), array, M8600_SYN(mdecc));
        !           585:                        printf("\tMSTAT1 = %b\n\tMSTAT2 = %b\n",
        !           586:                                    mstat1, M8600_MSTAT1_BITS,
        !           587:                                    mstat2, M8600_MSTAT2_BITS);
        !           588:                        M8600_INH;
        !           589:                }
        !           590:        } else
        !           591: #endif
        !           592:        for (m = 0; m < nmcr; m++) {
        !           593:                mcr = mcraddr[m];
        !           594:                switch (mcrtype[m]) {
        !           595: #if VAX780
        !           596:                case M780C:
        !           597:                        if (M780C_ERR(mcr)) {
        !           598:                                printf("mcr%d: soft ecc addr %x syn %x\n",
        !           599:                                    m, M780C_ADDR(mcr), M780C_SYN(mcr));
        !           600: #ifdef TRENDATA
        !           601:                                memlog(m, mcr);
        !           602: #endif
        !           603:                                M780C_INH(mcr);
        !           604:                        }
        !           605:                        break;
        !           606: 
        !           607:                case M780EL:
        !           608:                        if (M780EL_ERR(mcr)) {
        !           609:                                printf("mcr%d: soft ecc addr %x syn %x\n",
        !           610:                                    m, M780EL_ADDR(mcr), M780EL_SYN(mcr));
        !           611:                                M780EL_INH(mcr);
        !           612:                        }
        !           613:                        break;
        !           614: 
        !           615:                case M780EU:
        !           616:                        if (M780EU_ERR(mcr)) {
        !           617:                                printf("mcr%d: soft ecc addr %x syn %x\n",
        !           618:                                    m, M780EU_ADDR(mcr), M780EU_SYN(mcr));
        !           619:                                M780EU_INH(mcr);
        !           620:                        }
        !           621:                        break;
        !           622: #endif
        !           623: #if VAX750
        !           624:                case M750:
        !           625:                        if (M750_ERR(mcr)) {
        !           626:                                struct mcr amcr;
        !           627:                                amcr.mc_reg[0] = mcr->mc_reg[0];
        !           628:                                printf("mcr%d: %s",
        !           629:                                    m, (amcr.mc_reg[0] & M750_UNCORR) ?
        !           630:                                    "hard error" : "soft ecc");
        !           631:                                printf(" addr %x syn %x\n",
        !           632:                                    M750_ADDR(&amcr), M750_SYN(&amcr));
        !           633:                                M750_INH(mcr);
        !           634:                        }
        !           635:                        break;
        !           636: #endif
        !           637: #if VAX730
        !           638:                case M730: {
        !           639:                        struct mcr amcr;
        !           640: 
        !           641:                        /*
        !           642:                         * Must be careful on the 730 not to use invalid
        !           643:                         * instructions in I/O space, so make a copy;
        !           644:                         */
        !           645:                        amcr.mc_reg[0] = mcr->mc_reg[0];
        !           646:                        amcr.mc_reg[1] = mcr->mc_reg[1];
        !           647:                        if (M730_ERR(&amcr)) {
        !           648:                                printf("mcr%d: %s",
        !           649:                                    m, (amcr.mc_reg[1] & M730_UNCORR) ?
        !           650:                                    "hard error" : "soft ecc");
        !           651:                                printf(" addr %x syn %x\n",
        !           652:                                    M730_ADDR(&amcr), M730_SYN(&amcr));
        !           653:                                M730_INH(mcr);
        !           654:                        }
        !           655:                        break;
        !           656:                }
        !           657: #endif
        !           658:                }
        !           659:        }
        !           660: }
        !           661: 
        !           662: #ifdef TRENDATA
        !           663: /*
        !           664:  * Figure out what chip to replace on Trendata boards.
        !           665:  * Assumes all your memory is Trendata or the non-Trendata
        !           666:  * memory never fails..
        !           667:  */
        !           668: struct {
        !           669:        u_char  m_syndrome;
        !           670:        char    m_chip[4];
        !           671: } memlogtab[] = {
        !           672:        0x01,   "C00",  0x02,   "C01",  0x04,   "C02",  0x08,   "C03",
        !           673:        0x10,   "C04",  0x19,   "L01",  0x1A,   "L02",  0x1C,   "L04",
        !           674:        0x1F,   "L07",  0x20,   "C05",  0x38,   "L00",  0x3B,   "L03",
        !           675:        0x3D,   "L05",  0x3E,   "L06",  0x40,   "C06",  0x49,   "L09",
        !           676:        0x4A,   "L10",  0x4c,   "L12",  0x4F,   "L15",  0x51,   "L17",
        !           677:        0x52,   "L18",  0x54,   "L20",  0x57,   "L23",  0x58,   "L24",
        !           678:        0x5B,   "L27",  0x5D,   "L29",  0x5E,   "L30",  0x68,   "L08",
        !           679:        0x6B,   "L11",  0x6D,   "L13",  0x6E,   "L14",  0x70,   "L16",
        !           680:        0x73,   "L19",  0x75,   "L21",  0x76,   "L22",  0x79,   "L25",
        !           681:        0x7A,   "L26",  0x7C,   "L28",  0x7F,   "L31",  0x80,   "C07",
        !           682:        0x89,   "U01",  0x8A,   "U02",  0x8C,   "U04",  0x8F,   "U07",
        !           683:        0x91,   "U09",  0x92,   "U10",  0x94,   "U12",  0x97,   "U15",
        !           684:        0x98,   "U16",  0x9B,   "U19",  0x9D,   "U21",  0x9E,   "U22",
        !           685:        0xA8,   "U00",  0xAB,   "U03",  0xAD,   "U05",  0xAE,   "U06",
        !           686:        0xB0,   "U08",  0xB3,   "U11",  0xB5,   "U13",  0xB6,   "U14",
        !           687:        0xB9,   "U17",  0xBA,   "U18",  0xBC,   "U20",  0xBF,   "U23",
        !           688:        0xC1,   "U25",  0xC2,   "U26",  0xC4,   "U28",  0xC7,   "U31",
        !           689:        0xE0,   "U24",  0xE3,   "U27",  0xE5,   "U29",  0xE6,   "U30"
        !           690: };
        !           691: 
        !           692: memlog (m, mcr)
        !           693:        int m;
        !           694:        struct mcr *mcr;
        !           695: {
        !           696:        register i;
        !           697: 
        !           698:        switch (mcrtype[m]) {
        !           699: 
        !           700: #if VAX780
        !           701:        case M780C:
        !           702:        for (i = 0; i < (sizeof (memlogtab) / sizeof (memlogtab[0])); i++)
        !           703:                if ((u_char)(M780C_SYN(mcr)) == memlogtab[i].m_syndrome) {
        !           704:                        printf (
        !           705:        "mcr%d: replace %s chip in %s bank of memory board %d (0-15)\n",
        !           706:                                m,
        !           707:                                memlogtab[i].m_chip,
        !           708:                                (M780C_ADDR(mcr) & 0x8000) ? "upper" : "lower",
        !           709:                                (M780C_ADDR(mcr) >> 16));
        !           710:                        return;
        !           711:                }
        !           712:        printf ("mcr%d: multiple errors, not traceable\n", m);
        !           713:        break;
        !           714: #endif
        !           715:        }
        !           716: }
        !           717: #endif
        !           718: 
        !           719: /*
        !           720:  * Invalidate single all pte's in a cluster
        !           721:  */
        !           722: tbiscl(v)
        !           723:        unsigned v;
        !           724: {
        !           725:        register caddr_t addr;          /* must be first reg var */
        !           726:        register int i;
        !           727: 
        !           728:        asm(".set TBIS,58");
        !           729:        addr = ptob(v);
        !           730:        for (i = 0; i < CLSIZE; i++) {
        !           731: #ifdef lint
        !           732:                mtpr(TBIS, addr);
        !           733: #else
        !           734:                asm("mtpr r11,$TBIS");
        !           735: #endif
        !           736:                addr += NBPG;
        !           737:        }
        !           738: }
        !           739:   
        !           740: int    waittime = -1;
        !           741: 
        !           742: boot(paniced, arghowto)
        !           743:        int paniced, arghowto;
        !           744: {
        !           745:        register int howto;             /* r11 == how to boot */
        !           746:        register int devtype;           /* r10 == major of root dev */
        !           747: 
        !           748: #ifdef lint
        !           749:        howto = 0; devtype = 0;
        !           750:        printf("howto %d, devtype %d\n", arghowto, devtype);
        !           751: #endif
        !           752:        howto = arghowto;
        !           753:        if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) {
        !           754:                waittime = 0;
        !           755:                (void) splnet();
        !           756:                printf("syncing disks... ");
        !           757:                /*
        !           758:                 * Release inodes held by texts before update.
        !           759:                 */
        !           760:                xumount(NODEV);
        !           761:                update();
        !           762:                { register struct buf *bp;
        !           763:                  int iter, nbusy;
        !           764: 
        !           765:                  for (iter = 0; iter < 20; iter++) {
        !           766:                        nbusy = 0;
        !           767:                        for (bp = &buf[nbuf]; --bp >= buf; )
        !           768:                                if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
        !           769:                                        nbusy++;
        !           770:                        if (nbusy == 0)
        !           771:                                break;
        !           772:                        printf("%d ", nbusy);
        !           773:                        DELAY(40000 * iter);
        !           774:                  }
        !           775:                }
        !           776:                printf("done\n");
        !           777:                /*
        !           778:                 * If we've been adjusting the clock, the todr
        !           779:                 * will be out of synch; adjust it now.
        !           780:                 */
        !           781:                resettodr();
        !           782:        }
        !           783:        splx(0x1f);                     /* extreme priority */
        !           784:        devtype = major(rootdev);
        !           785:        if (howto&RB_HALT) {
        !           786:                printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n");
        !           787:                mtpr(IPL, 0x1f);
        !           788:                for (;;)
        !           789:                        ;
        !           790:        } else {
        !           791:                if (paniced == RB_PANIC) {
        !           792:                        doadump();              /* TXDB_BOOT's itself */
        !           793:                        /*NOTREACHED*/
        !           794:                }
        !           795:                tocons(TXDB_BOOT);
        !           796:        }
        !           797: #if defined(VAX750) || defined(VAX730) || defined(VAX630)
        !           798:        if (cpu == VAX_750 || cpu == VAX_730 || cpu == VAX_630)
        !           799:                { asm("movl r11,r5"); }         /* boot flags go in r5 */
        !           800: #endif
        !           801:        for (;;)
        !           802:                asm("halt");
        !           803:        /*NOTREACHED*/
        !           804: }
        !           805: 
        !           806: tocons(c)
        !           807: {
        !           808:        register oldmask;
        !           809: 
        !           810:        while (((oldmask = mfpr(TXCS)) & TXCS_RDY) == 0)
        !           811:                continue;
        !           812: 
        !           813:        switch (cpu) {
        !           814: 
        !           815: #if VAX780 || VAX750 || VAX730 || VAX630
        !           816:        case VAX_780:
        !           817:        case VAX_750:
        !           818:        case VAX_730:
        !           819:        case VAX_630:
        !           820:                c |= TXDB_CONS;
        !           821:                break;
        !           822: #endif
        !           823: 
        !           824: #if VAX8600
        !           825:        case VAX_8600:
        !           826:                mtpr(TXCS, TXCS_LCONS | TXCS_WMASK);
        !           827:                while ((mfpr(TXCS) & TXCS_RDY) == 0)
        !           828:                        continue;
        !           829:                break;
        !           830: #endif
        !           831:        }
        !           832: 
        !           833:        mtpr(TXDB, c);
        !           834: 
        !           835: #if VAX8600
        !           836:        switch (cpu) {
        !           837: 
        !           838:        case VAX_8600:
        !           839:                while ((mfpr(TXCS) & TXCS_RDY) == 0)
        !           840:                        continue;
        !           841:                mtpr(TXCS, oldmask | TXCS_WMASK);
        !           842:                break;
        !           843:        }
        !           844: #endif
        !           845: }
        !           846: 
        !           847: int    dumpmag = 0x8fca0101;   /* magic number for savecore */
        !           848: int    dumpsize = 0;           /* also for savecore */
        !           849: /*
        !           850:  * Doadump comes here after turning off memory management and
        !           851:  * getting on the dump stack, either when called above, or by
        !           852:  * the auto-restart code.
        !           853:  */
        !           854: dumpsys()
        !           855: {
        !           856: 
        !           857:        rpb.rp_flag = 1;
        !           858: #ifdef notdef
        !           859:        if ((minor(dumpdev)&07) != 1)
        !           860:                return;
        !           861: #endif
        !           862:        dumpsize = physmem;
        !           863:        printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
        !           864:        printf("dump ");
        !           865:        switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
        !           866: 
        !           867:        case ENXIO:
        !           868:                printf("device bad\n");
        !           869:                break;
        !           870: 
        !           871:        case EFAULT:
        !           872:                printf("device not ready\n");
        !           873:                break;
        !           874: 
        !           875:        case EINVAL:
        !           876:                printf("area improper\n");
        !           877:                break;
        !           878: 
        !           879:        case EIO:
        !           880:                printf("i/o error");
        !           881:                break;
        !           882: 
        !           883:        default:
        !           884:                printf("succeeded");
        !           885:                break;
        !           886:        }
        !           887: }
        !           888: 
        !           889: /*
        !           890:  * Machine check error recovery code.
        !           891:  * Print out the machine check frame and then give up.
        !           892:  */
        !           893: #if VAX8600
        !           894: #define NMC8600        7
        !           895: char *mc8600[] = {
        !           896:        "unkn type",    "fbox error",   "ebox error",   "ibox error",
        !           897:        "mbox error",   "tbuf error",   "mbox 1D error"
        !           898: };
        !           899: /* codes for above */
        !           900: #define        MC_FBOX         1
        !           901: #define        MC_EBOX         2
        !           902: #define        MC_IBOX         3
        !           903: #define        MC_MBOX         4
        !           904: #define        MC_TBUF         5
        !           905: #define        MC_MBOX1D       6
        !           906: 
        !           907: /* error bits */
        !           908: #define        MBOX_FE         0x8000          /* Mbox fatal error */
        !           909: #define        FBOX_SERV       0x10000000      /* Fbox service error */
        !           910: #define        IBOX_ERR        0x2000          /* Ibox error */
        !           911: #define        EBOX_ERR        0x1e00          /* Ebox error */
        !           912: #define        MBOX_1D         0x81d0000       /* Mbox 1D error */
        !           913: #define EDP_PE         0x200
        !           914: #endif
        !           915: 
        !           916: #if defined(VAX780) || defined(VAX750)
        !           917: char *mc780[] = {
        !           918:        "cp read",      "ctrl str par", "cp tbuf par",  "cp cache par",
        !           919:        "cp rdtimo",    "cp rds",       "ucode lost",   0,
        !           920:        0,              0,              "ib tbuf par",  0,
        !           921:        "ib rds",       "ib rd timo",   0,              "ib cache par"
        !           922: };
        !           923: #define MC750_TBERR    2               /* type code of cp tbuf par */
        !           924: #define        MC750_TBPAR     4               /* tbuf par bit in mcesr */
        !           925: #endif
        !           926: 
        !           927: #if VAX730
        !           928: #define        NMC730  12
        !           929: char *mc730[] = {
        !           930:        "tb par",       "bad retry",    "bad intr id",  "cant write ptem",
        !           931:        "unkn mcr err", "iib rd err",   "nxm ref",      "cp rds",
        !           932:        "unalgn ioref", "nonlw ioref",  "bad ioaddr",   "unalgn ubaddr",
        !           933: };
        !           934: #endif
        !           935: #if VAX630
        !           936: #define NMC630 10
        !           937: extern struct ka630cpu ka630cpu;
        !           938: char *mc630[] = {
        !           939:        0,              "immcr (fsd)",  "immcr (ssd)",  "fpu err 0",
        !           940:        "fpu err 7",    "mmu st(tb)",   "mmu st(m=0)",  "pte in p0",
        !           941:        "pte in p1",    "un intr id",
        !           942: };
        !           943: #endif
        !           944: 
        !           945: /*
        !           946:  * Frame for each cpu
        !           947:  */
        !           948: struct mc780frame {
        !           949:        int     mc8_bcnt;               /* byte count == 0x28 */
        !           950:        int     mc8_summary;            /* summary parameter (as above) */
        !           951:        int     mc8_cpues;              /* cpu error status */
        !           952:        int     mc8_upc;                /* micro pc */
        !           953:        int     mc8_vaviba;             /* va/viba register */
        !           954:        int     mc8_dreg;               /* d register */
        !           955:        int     mc8_tber0;              /* tbuf error reg 0 */
        !           956:        int     mc8_tber1;              /* tbuf error reg 1 */
        !           957:        int     mc8_timo;               /* timeout address divided by 4 */
        !           958:        int     mc8_parity;             /* parity */
        !           959:        int     mc8_sbier;              /* sbi error register */
        !           960:        int     mc8_pc;                 /* trapped pc */
        !           961:        int     mc8_psl;                /* trapped psl */
        !           962: };
        !           963: struct mc750frame {
        !           964:        int     mc5_bcnt;               /* byte count == 0x28 */
        !           965:        int     mc5_summary;            /* summary parameter (as above) */
        !           966:        int     mc5_va;                 /* virtual address register */
        !           967:        int     mc5_errpc;              /* error pc */
        !           968:        int     mc5_mdr;
        !           969:        int     mc5_svmode;             /* saved mode register */
        !           970:        int     mc5_rdtimo;             /* read lock timeout */
        !           971:        int     mc5_tbgpar;             /* tb group parity error register */
        !           972:        int     mc5_cacherr;            /* cache error register */
        !           973:        int     mc5_buserr;             /* bus error register */
        !           974:        int     mc5_mcesr;              /* machine check status register */
        !           975:        int     mc5_pc;                 /* trapped pc */
        !           976:        int     mc5_psl;                /* trapped psl */
        !           977: };
        !           978: struct mc730frame {
        !           979:        int     mc3_bcnt;               /* byte count == 0xc */
        !           980:        int     mc3_summary;            /* summary parameter */
        !           981:        int     mc3_parm[2];            /* parameter 1 and 2 */
        !           982:        int     mc3_pc;                 /* trapped pc */
        !           983:        int     mc3_psl;                /* trapped psl */
        !           984: };
        !           985: struct mc630frame {
        !           986:        int     mc63_bcnt;              /* byte count == 0xc */
        !           987:        int     mc63_summary;           /* summary parameter */
        !           988:        int     mc63_mrvaddr;           /* most recent vad */
        !           989:        int     mc63_istate;            /* internal state */
        !           990:        int     mc63_pc;                        /* trapped pc */
        !           991:        int     mc63_psl;               /* trapped psl */
        !           992: };
        !           993: struct mc8600frame {
        !           994:        int     mc6_bcnt;               /* byte count == 0x58 */
        !           995:        int     mc6_ehmsts;
        !           996:        int     mc6_evmqsav;
        !           997:        int     mc6_ebcs;
        !           998:        int     mc6_edpsr;
        !           999:        int     mc6_cslint;
        !          1000:        int     mc6_ibesr;
        !          1001:        int     mc6_ebxwd1;
        !          1002:        int     mc6_ebxwd2;
        !          1003:        int     mc6_ivasav;
        !          1004:        int     mc6_vibasav;
        !          1005:        int     mc6_esasav;
        !          1006:        int     mc6_isasav;
        !          1007:        int     mc6_cpc;
        !          1008:        int     mc6_mstat1;
        !          1009:        int     mc6_mstat2;
        !          1010:        int     mc6_mdecc;
        !          1011:        int     mc6_merg;
        !          1012:        int     mc6_cshctl;
        !          1013:        int     mc6_mear;
        !          1014:        int     mc6_medr;
        !          1015:        int     mc6_accs;
        !          1016:        int     mc6_cses;
        !          1017:        int     mc6_pc;                 /* trapped pc */
        !          1018:        int     mc6_psl;                /* trapped psl */
        !          1019: };
        !          1020: 
        !          1021: machinecheck(cmcf)
        !          1022:        caddr_t cmcf;
        !          1023: {
        !          1024:        register u_int type = ((struct mc780frame *)cmcf)->mc8_summary;
        !          1025: 
        !          1026:        printf("machine check %x: ", type);
        !          1027:        switch (cpu) {
        !          1028: #if VAX8600
        !          1029:        case VAX_8600: {
        !          1030:                register struct mc8600frame *mcf = (struct mc8600frame *)cmcf;
        !          1031: 
        !          1032:                if (mcf->mc6_ebcs & MBOX_FE)
        !          1033:                        mcf->mc6_ehmsts |= MC_MBOX;
        !          1034:                else if (mcf->mc6_ehmsts & FBOX_SERV)
        !          1035:                        mcf->mc6_ehmsts |= MC_FBOX;
        !          1036:                else if (mcf->mc6_ebcs & EBOX_ERR) {
        !          1037:                        if (mcf->mc6_ebcs & EDP_PE)
        !          1038:                                mcf->mc6_ehmsts |= MC_MBOX;
        !          1039:                        else
        !          1040:                                mcf->mc6_ehmsts |= MC_EBOX;
        !          1041:                } else if (mcf->mc6_ehmsts & IBOX_ERR)
        !          1042:                        mcf->mc6_ehmsts |= MC_IBOX;
        !          1043:                else if (mcf->mc6_mstat1 & M8600_TB_ERR)
        !          1044:                        mcf->mc6_ehmsts |= MC_TBUF;
        !          1045:                else if ((mcf->mc6_cslint & MBOX_1D) == MBOX_1D)
        !          1046:                        mcf->mc6_ehmsts |= MC_MBOX1D;
        !          1047: 
        !          1048:                type = mcf->mc6_ehmsts & 0x7;
        !          1049:                if (type < NMC8600)
        !          1050:                        printf("machine check %x: %s", type, mc8600[type]);
        !          1051:                printf("\n");
        !          1052:                printf("\tehm.sts %x evmqsav %x ebcs %x edpsr %x cslint %x\n",
        !          1053:                    mcf->mc6_ehmsts, mcf->mc6_evmqsav, mcf->mc6_ebcs,
        !          1054:                    mcf->mc6_edpsr, mcf->mc6_cslint);
        !          1055:                printf("\tibesr %x ebxwd %x %x ivasav %x vibasav %x\n",
        !          1056:                    mcf->mc6_ibesr, mcf->mc6_ebxwd1, mcf->mc6_ebxwd2,
        !          1057:                    mcf->mc6_ivasav, mcf->mc6_vibasav);
        !          1058:                printf("\tesasav %x isasav %x cpc %x mstat %x %x mdecc %x\n",
        !          1059:                    mcf->mc6_esasav, mcf->mc6_isasav, mcf->mc6_cpc,
        !          1060:                    mcf->mc6_mstat1, mcf->mc6_mstat2, mcf->mc6_mdecc);
        !          1061:                printf("\tmerg %x cshctl %x mear %x medr %x accs %x cses %x\n",
        !          1062:                    mcf->mc6_merg, mcf->mc6_cshctl, mcf->mc6_mear,
        !          1063:                    mcf->mc6_medr, mcf->mc6_accs, mcf->mc6_cses);
        !          1064:                printf("\tpc %x psl %x\n", mcf->mc6_pc, mcf->mc6_psl);
        !          1065:                mtpr(EHSR, 0);
        !          1066:                break;
        !          1067:        };
        !          1068: #endif
        !          1069: #if VAX780
        !          1070:        case VAX_780: {
        !          1071:                register struct mc780frame *mcf = (struct mc780frame *)cmcf;
        !          1072: 
        !          1073:                register int sbifs;
        !          1074:                printf("%s%s\n", mc780[type&0xf],
        !          1075:                    (type&0xf0) ? " abort" : " fault"); 
        !          1076:                printf("\tcpues %x upc %x va/viba %x dreg %x tber %x %x\n",
        !          1077:                   mcf->mc8_cpues, mcf->mc8_upc, mcf->mc8_vaviba,
        !          1078:                   mcf->mc8_dreg, mcf->mc8_tber0, mcf->mc8_tber1);
        !          1079:                sbifs = mfpr(SBIFS);
        !          1080:                printf("\ttimo %x parity %x sbier %x pc %x psl %x sbifs %x\n",
        !          1081:                   mcf->mc8_timo*4, mcf->mc8_parity, mcf->mc8_sbier,
        !          1082:                   mcf->mc8_pc, mcf->mc8_psl, sbifs);
        !          1083:                /* THE FUNNY BITS IN THE FOLLOWING ARE FROM THE ``BLACK */
        !          1084:                /* BOOK'' AND SHOULD BE PUT IN AN ``sbi.h'' */
        !          1085:                mtpr(SBIFS, sbifs &~ 0x2000000);
        !          1086:                mtpr(SBIER, mfpr(SBIER) | 0x70c0);
        !          1087:                break;
        !          1088:        }
        !          1089: #endif
        !          1090: #if VAX750
        !          1091:        case VAX_750: {
        !          1092:                register struct mc750frame *mcf = (struct mc750frame *)cmcf;
        !          1093: 
        !          1094:                int mcsr = mfpr(MCSR);
        !          1095:                printf("%s%s\n", mc780[type&0xf],
        !          1096:                    (type&0xf0) ? " abort" : " fault"); 
        !          1097:                mtpr(TBIA, 0);
        !          1098:                mtpr(MCESR, 0xf);
        !          1099:                printf("\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n",
        !          1100:                    mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode,
        !          1101:                    mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr);
        !          1102:                printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n",
        !          1103:                    mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl,
        !          1104:                    mcsr);
        !          1105:                if (type == MC750_TBERR && (mcf->mc5_mcesr&0xe) == MC750_TBPAR){
        !          1106:                        printf("tbuf par: flushing and returning\n");
        !          1107:                        return;
        !          1108:                }
        !          1109:                break;
        !          1110:                }
        !          1111: #endif
        !          1112: #if VAX730
        !          1113:        case VAX_730: {
        !          1114:                register struct mc730frame *mcf = (struct mc730frame *)cmcf;
        !          1115: 
        !          1116:                if (type < NMC730)
        !          1117:                        printf("%s", mc730[type]);
        !          1118:                printf("\n");
        !          1119:                printf("params %x,%x pc %x psl %x mcesr %x\n",
        !          1120:                    mcf->mc3_parm[0], mcf->mc3_parm[1],
        !          1121:                    mcf->mc3_pc, mcf->mc3_psl, mfpr(MCESR));
        !          1122:                mtpr(MCESR, 0xf);
        !          1123:                break;
        !          1124:                }
        !          1125: #endif
        !          1126: #if VAX630
        !          1127:        case VAX_630: {
        !          1128:                register struct ka630cpu *ka630addr = &ka630cpu;
        !          1129:                register struct mc630frame *mcf = (struct mc630frame *)cmcf;
        !          1130:                printf("vap %x istate %x pc %x psl %x\n",
        !          1131:                    mcf->mc63_mrvaddr, mcf->mc63_istate,
        !          1132:                    mcf->mc63_pc, mcf->mc63_psl);
        !          1133:                if (ka630addr->ka630_mser & KA630MSER_MERR) {
        !          1134:                        printf("mser=0x%x ",ka630addr->ka630_mser);
        !          1135:                        if (ka630addr->ka630_mser & KA630MSER_CPUER)
        !          1136:                                printf("page=%d",ka630addr->ka630_cear);
        !          1137:                        if (ka630addr->ka630_mser & KA630MSER_DQPE)
        !          1138:                                printf("page=%d",ka630addr->ka630_dear);
        !          1139:                        printf("\n");
        !          1140:                }
        !          1141:                break;
        !          1142:                }
        !          1143: #endif
        !          1144:        }
        !          1145:        memerr();
        !          1146:        panic("mchk");
        !          1147: }
        !          1148: 
        !          1149: /*
        !          1150:  * Return the best possible estimate of the time in the timeval
        !          1151:  * to which tvp points.  We do this by reading the interval count
        !          1152:  * register to determine the time remaining to the next clock tick.
        !          1153:  * We must compensate for wraparound which is not yet reflected in the time
        !          1154:  * (which happens when the ICR hits 0 and wraps after the splhigh(),
        !          1155:  * but before the mfpr(ICR)).  Also check that this time is no less than
        !          1156:  * any previously-reported time, which could happen around the time
        !          1157:  * of a clock adjustment.  Just for fun, we guarantee that the time
        !          1158:  * will be greater than the value obtained by a previous call.
        !          1159:  */
        !          1160: microtime(tvp)
        !          1161:        register struct timeval *tvp;
        !          1162: {
        !          1163:        int s = splhigh();
        !          1164:        static struct timeval lasttime;
        !          1165:        register long t;
        !          1166: 
        !          1167:        *tvp = time;
        !          1168:        t =  mfpr(ICR);
        !          1169:        if (t < -tick / 2 && (mfpr(ICCS) & ICCS_INT))
        !          1170:                t += tick;
        !          1171:        tvp->tv_usec += tick + t;
        !          1172:        if (tvp->tv_usec > 1000000) {
        !          1173:                tvp->tv_sec++;
        !          1174:                tvp->tv_usec -= 1000000;
        !          1175:        }
        !          1176:        if (tvp->tv_sec == lasttime.tv_sec &&
        !          1177:            tvp->tv_usec <= lasttime.tv_usec &&
        !          1178:            (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
        !          1179:                tvp->tv_sec++;
        !          1180:                tvp->tv_usec -= 1000000;
        !          1181:        }
        !          1182:        lasttime = *tvp;
        !          1183:        splx(s);
        !          1184: }
        !          1185: 
        !          1186: physstrat(bp, strat, prio)
        !          1187:        struct buf *bp;
        !          1188:        int (*strat)(), prio;
        !          1189: {
        !          1190:        int s;
        !          1191: 
        !          1192:        (*strat)(bp);
        !          1193:        /* pageout daemon doesn't wait for pushed pages */
        !          1194:        if (bp->b_flags & B_DIRTY)
        !          1195:                return;
        !          1196:        s = splbio();
        !          1197:        while ((bp->b_flags & B_DONE) == 0)
        !          1198:                sleep((caddr_t)bp, prio);
        !          1199:        splx(s);
        !          1200: }
        !          1201: 
        !          1202: initcpu()
        !          1203: {
        !          1204:        /*
        !          1205:         * Enable cache.
        !          1206:         */
        !          1207:        switch (cpu) {
        !          1208: 
        !          1209: #if VAX780
        !          1210:        case VAX_780:
        !          1211:                mtpr(SBIMT, 0x200000);
        !          1212:                break;
        !          1213: #endif
        !          1214: #if VAX750
        !          1215:        case VAX_750:
        !          1216:                mtpr(CADR, 0);
        !          1217:                break;
        !          1218: #endif
        !          1219: #if VAX8600
        !          1220:        case VAX_8600:
        !          1221:                mtpr(CSWP, 3);
        !          1222:                break;
        !          1223: #endif
        !          1224:        default:
        !          1225:                break;
        !          1226:        }
        !          1227: 
        !          1228:        /*
        !          1229:         * Enable floating point accelerator if it exists
        !          1230:         * and has control register.
        !          1231:         */
        !          1232:        switch(cpu) {
        !          1233: 
        !          1234: #if VAX8600 || VAX780
        !          1235:        case VAX_780:
        !          1236:        case VAX_8600:
        !          1237:                if ((mfpr(ACCS) & 0xff) != 0) {
        !          1238:                        printf("Enabling FPA\n");
        !          1239:                        mtpr(ACCS, 0x8000);
        !          1240:                }
        !          1241: #endif
        !          1242:        default:
        !          1243:                break;
        !          1244:        }
        !          1245: }

unix.superglobalmegacorp.com

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