Annotation of 43BSDReno/sys/vax/machdep.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982,1986,1988,1990 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.30 (Berkeley) 6/28/90
                      7:  */
                      8: 
                      9: #include "param.h"
                     10: #include "systm.h"
                     11: #include "user.h"
                     12: #include "kernel.h"
                     13: #include "malloc.h"
                     14: #include "map.h"
                     15: #include "vm.h"
                     16: #include "proc.h"
                     17: #include "buf.h"
                     18: #include "reboot.h"
                     19: #include "conf.h"
                     20: #include "file.h"
                     21: #include "text.h"
                     22: #include "clist.h"
                     23: #include "callout.h"
                     24: #include "cmap.h"
                     25: #include "mbuf.h"
                     26: #include "msgbuf.h"
                     27: #ifdef SYSVSHM
                     28: #include "shm.h"
                     29: #endif
                     30: 
                     31: #include "reg.h"
                     32: #include "pte.h"
                     33: #include "psl.h"
                     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 "ka650.h"
                     43: 
                     44: #include "../vaxuba/ubavar.h"
                     45: #include "../vaxuba/ubareg.h"
                     46: 
                     47: /*
                     48:  * Declare these as initialized data so we can patch them.
                     49:  */
                     50: int    nswbuf = 0;
                     51: #ifdef NBUF
                     52: int    nbuf = NBUF;
                     53: #else
                     54: int    nbuf = 0;
                     55: #endif
                     56: #ifdef BUFPAGES
                     57: int    bufpages = BUFPAGES;
                     58: #else
                     59: int    bufpages = 0;
                     60: #endif
                     61: int    msgbufmapped;           /* set when safe to use msgbuf */
                     62: int    physmem = MAXMEM;       /* max supported memory, changes to actual */
                     63: 
                     64: /*
                     65:  * Machine-dependent startup code
                     66:  */
                     67: startup(firstaddr)
                     68:        int firstaddr;
                     69: {
                     70:        register int unixsize;
                     71:        register unsigned i;
                     72:        register struct pte *pte;
                     73:        int mapaddr, j, n;
                     74:        register caddr_t v;
                     75:        int maxbufs, base, residual;
                     76: 
                     77:        /*
                     78:         * Initialize error message buffer (at end of core).
                     79:         */
                     80:        maxmem = physmem - btoc(sizeof (struct msgbuf));
                     81:        pte = msgbufmap;
                     82:        for (i = 1; i < btoc(sizeof (struct msgbuf)) + 1; i++)
                     83:                *(int *)pte++ = PG_V | PG_KW | (physmem - i);
                     84:        mtpr(TBIA, 0);
                     85:        msgbufmapped = 1;
                     86: 
                     87: #ifdef QBA
                     88: #include "qv.h"
                     89: #if NQV > 0
                     90:        /*
                     91:         * redirect console to qvss if it exists
                     92:         */
                     93:        qvcons_init();
                     94: #endif 
                     95: #include "qd.h"
                     96: #if NQD > 0
                     97:        /*
                     98:         * redirect console to qdss if it exists
                     99:         */
                    100:        qdcons_init();
                    101: #endif
                    102: #endif
                    103: 
                    104: #ifdef KADB
                    105:        kdb_init();
                    106:        (void) cnopen(makedev(0, 0), 0);        /* open console XXX */
                    107: #endif
                    108:        /*
                    109:         * Good {morning,afternoon,evening,night}.
                    110:         */
                    111:        printf(version);
                    112:        printf("real mem = %d\n", ctob(physmem));
                    113: 
                    114:        /*
                    115:         * Allocate space for system data structures.
                    116:         * The first available real memory address is in "firstaddr".
                    117:         * The first available kernel virtual address is in "v".
                    118:         * As pages of kernel virtual memory are allocated, "v" is incremented.
                    119:         * As pages of memory are allocated and cleared,
                    120:         * "firstaddr" is incremented.
                    121:         * An index into the kernel page table corresponding to the
                    122:         * virtual memory address maintained in "v" is kept in "mapaddr".
                    123:         */
                    124:        v = (caddr_t)(KERNBASE | (firstaddr * NBPG));
                    125: #define        valloc(name, type, num) \
                    126:            (name) = (type *)v; v = (caddr_t)((name)+(num))
                    127: #define        valloclim(name, type, num, lim) \
                    128:            (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
                    129:        valloclim(file, struct file, nfile, fileNFILE);
                    130:        valloclim(proc, struct proc, nproc, procNPROC);
                    131:        valloclim(text, struct text, ntext, textNTEXT);
                    132:        valloc(cfree, struct cblock, nclist);
                    133:        valloc(callout, struct callout, ncallout);
                    134:        valloc(swapmap, struct map, nswapmap = nproc * 2);
                    135:        valloc(argmap, struct map, ARGMAPSIZE);
                    136:        valloc(kernelmap, struct map, nproc);
                    137:        valloc(mbmap, struct map, nmbclusters/4);
                    138:        valloc(kmemmap, struct map, ekmempt - kmempt);
                    139:        valloc(kmemusage, struct kmemusage, ekmempt - kmempt);
                    140: #ifdef SYSVSHM
                    141:        valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
                    142: #endif
                    143:        
                    144:        /*
                    145:         * Determine how many buffers to allocate.
                    146:         * Use 10% of memory for the first 2 Meg, 5% of the remaining
                    147:         * memory. Insure a minimum of 16 buffers.
                    148:         * We allocate 1/2 as many swap buffer headers as file i/o buffers.
                    149:         */
                    150:        if (bufpages == 0)
                    151:                if (physmem < (2 * 1024 * CLSIZE))
                    152:                        bufpages = physmem / 10 / CLSIZE;
                    153:                else
                    154:                        bufpages = ((2 * 1024 * CLSIZE + physmem) / 20) / CLSIZE;
                    155:        if (nbuf == 0) {
                    156:                nbuf = bufpages / 2;
                    157:                if (nbuf < 16)
                    158:                        nbuf = 16;
                    159:        }
                    160:        if (nswbuf == 0) {
                    161:                nswbuf = (nbuf / 2) &~ 1;       /* force even */
                    162:                if (nswbuf > 256)
                    163:                        nswbuf = 256;           /* sanity */
                    164:        }
                    165:        valloc(swbuf, struct buf, nswbuf);
                    166: 
                    167:        /*
                    168:         * Now the amount of virtual memory remaining for buffers
                    169:         * can be calculated, estimating needs for the cmap.
                    170:         */
                    171:        ncmap = (maxmem*NBPG - ((int)v &~ KERNBASE)) /
                    172:                (CLBYTES + sizeof(struct cmap)) + 2;
                    173:        maxbufs = ((SYSPTSIZE * NBPG) -
                    174:            ((int)(v + ncmap * sizeof(struct cmap)) - KERNBASE)) /
                    175:                (MAXBSIZE + sizeof(struct buf));
                    176:        if (maxbufs < 16)
                    177:                panic("sys pt too small");
                    178:        if (nbuf > maxbufs) {
                    179:                printf("SYSPTSIZE limits number of buffers to %d\n", maxbufs);
                    180:                nbuf = maxbufs;
                    181:        }
                    182:        if (bufpages > nbuf * (MAXBSIZE / CLBYTES))
                    183:                bufpages = nbuf * (MAXBSIZE / CLBYTES);
                    184:        valloc(buf, struct buf, nbuf);
                    185: 
                    186:        /*
                    187:         * Allocate space for core map.
                    188:         * Allow space for all of phsical memory minus the amount 
                    189:         * dedicated to the system. The amount of physical memory
                    190:         * dedicated to the system is the total virtual memory of
                    191:         * the system thus far, plus core map, buffer pages,
                    192:         * and buffer headers not yet allocated.
                    193:         * Add 2: 1 because the 0th entry is unused, 1 for rounding.
                    194:         */
                    195:        ncmap = (maxmem*NBPG - ((int)(v + bufpages*CLBYTES) &~ KERNBASE)) /
                    196:                (CLBYTES + sizeof(struct cmap)) + 2;
                    197:        valloclim(cmap, struct cmap, ncmap, ecmap);
                    198: 
                    199:        /*
                    200:         * Clear space allocated thus far, and make r/w entries
                    201:         * for the space in the kernel map.
                    202:         */
                    203:        unixsize = btoc((int)v &~ KERNBASE);
                    204:        while (firstaddr < unixsize) {
                    205:                *(int *)(&Sysmap[firstaddr]) = PG_V | PG_KW | firstaddr;
                    206:                clearseg((unsigned)firstaddr);
                    207:                firstaddr++;
                    208:        }
                    209: 
                    210:        /*
                    211:         * Now allocate buffers proper.  They are different than the above
                    212:         * in that they usually occupy more virtual memory than physical.
                    213:         */
                    214:        v = (caddr_t) ((int)(v + PGOFSET) &~ PGOFSET);
                    215:        valloc(buffers, char, MAXBSIZE * nbuf);
                    216:        base = bufpages / nbuf;
                    217:        residual = bufpages % nbuf;
                    218:        mapaddr = firstaddr;
                    219:        for (i = 0; i < nbuf; i++) {
                    220:                n = (i < residual ? base + 1 : base) * CLSIZE;
                    221:                for (j = 0; j < n; j++) {
                    222:                        *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr;
                    223:                        clearseg((unsigned)firstaddr);
                    224:                        firstaddr++;
                    225:                }
                    226:                mapaddr += MAXBSIZE / NBPG;
                    227:        }
                    228: 
                    229:        unixsize = btoc((int)v &~ KERNBASE);
                    230:        if (firstaddr >= physmem - 8*UPAGES)
                    231:                panic("no memory");
                    232:        mtpr(TBIA, 0);                  /* After we just cleared it all! */
                    233: 
                    234:        /*
                    235:         * Initialize callouts
                    236:         */
                    237:        callfree = callout;
                    238:        for (i = 1; i < ncallout; i++)
                    239:                callout[i-1].c_next = &callout[i];
                    240: 
                    241:        /*
                    242:         * Initialize memory allocator and swap
                    243:         * and user page table maps.
                    244:         *
                    245:         * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''
                    246:         * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.
                    247:         */
                    248:        meminit(firstaddr, maxmem);
                    249:        maxmem = freemem;
                    250:        printf("avail mem = %d\n", ctob(maxmem));
                    251:        printf("using %d buffers containing %d bytes of memory\n",
                    252:                nbuf, bufpages * CLBYTES);
                    253:        rminit(kernelmap, (long)USRPTSIZE, (long)1,
                    254:            "usrpt", nproc);
                    255:        rminit(mbmap, (long)(nmbclusters * CLSIZE), (long)CLSIZE,
                    256:            "mbclusters", nmbclusters/4);
                    257:        kmeminit();     /* now safe to do malloc/free */
                    258: 
                    259:        /*
                    260:         * Set up CPU-specific registers, cache, etc.
                    261:         */
                    262:        initcpu();
                    263: 
                    264:        /*
                    265:         * Set up buffers, so they can be used to read disk labels.
                    266:         */
                    267:        bhinit();
                    268:        binit();
                    269: 
                    270:        /*
                    271:         * Configure the system.
                    272:         */
                    273:        configure();
                    274: 
                    275:        /*
                    276:         * Clear restart inhibit flags.
                    277:         */
                    278:        tocons(TXDB_CWSI);
                    279:        tocons(TXDB_CCSI);
                    280: }
                    281: 
                    282: #ifdef PGINPROF
                    283: /*
                    284:  * Return the difference (in microseconds)
                    285:  * between the  current time and a previous
                    286:  * time as represented  by the arguments.
                    287:  * If there is a pending clock interrupt
                    288:  * which has not been serviced due to high
                    289:  * ipl, return error code.
                    290:  */
                    291: vmtime(otime, olbolt, oicr)
                    292:        register int otime, olbolt, oicr;
                    293: {
                    294: 
                    295:        if (mfpr(ICCS)&ICCS_INT)
                    296:                return(-1);
                    297:        else
                    298:                return(((time.tv_sec-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr);
                    299: }
                    300: #endif
                    301: 
                    302: /*
                    303:  * Clear registers on exec
                    304:  */
                    305: /* ARGSUSED */
                    306: setregs(entry, retval)
                    307:        u_long entry;
                    308:        int *retval;
                    309: {
                    310: #ifdef notdef
                    311:        register int *rp;
                    312: 
                    313:        /* should pass args to init on the stack */
                    314:        /* should also fix this code before using it, it's wrong */
                    315:        /* wanna clear the scb? */
                    316:        for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
                    317:                *rp++ = 0;
                    318: #endif
                    319:        u.u_ar0[PC] = entry + 2;
                    320: }
                    321: 
                    322: /*
                    323:  * Send an interrupt to process.
                    324:  *
                    325:  * Stack is set up to allow sigcode stored
                    326:  * in u. to call routine, followed by chmk
                    327:  * to sigreturn routine below.  After sigreturn
                    328:  * resets the signal mask, the stack, the frame 
                    329:  * pointer, and the argument pointer, it returns
                    330:  * to the user specified pc, psl.
                    331:  */
                    332: sendsig(catcher, sig, mask, code)
                    333:        sig_t catcher;
                    334:        int sig, mask;
                    335:        unsigned code;
                    336: {
                    337:        register struct sigcontext *scp;
                    338:        register struct proc *p = u.u_procp;
                    339:        register int *regs;
                    340:        register struct sigframe {
                    341:                int     sf_signum;
                    342:                int     sf_code;
                    343:                struct  sigcontext *sf_scp;
                    344:                sig_t   sf_handler;
                    345:                int     sf_argcount;
                    346:                struct  sigcontext *sf_scpcopy;
                    347:        } *fp;
                    348:        int oonstack;
                    349: 
                    350:        regs = u.u_ar0;
                    351:        oonstack = u.u_onstack;
                    352:        /*
                    353:         * Allocate and validate space for the signal handler
                    354:         * context. Note that if the stack is in P0 space, the
                    355:         * call to grow() is a nop, and the useracc() check
                    356:         * will fail if the process has not already allocated
                    357:         * the space with a `brk'.
                    358:         */
                    359:        if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) {
                    360:                scp = (struct sigcontext *)u.u_sigsp - 1;
                    361:                u.u_onstack = 1;
                    362:        } else
                    363:                scp = (struct sigcontext *)regs[SP] - 1;
                    364:        fp = (struct sigframe *)scp - 1;
                    365:        if ((int)fp <= USRSTACK - ctob(u.u_ssize)) 
                    366:                (void)grow((unsigned)fp);
                    367:        if (useracc((caddr_t)fp, sizeof (*fp) + sizeof (*scp), B_WRITE) == 0) {
                    368:                /*
                    369:                 * Process has trashed its stack; give it an illegal
                    370:                 * instruction to halt it in its tracks.
                    371:                 */
                    372:                SIGACTION(p, SIGILL) = SIG_DFL;
                    373:                sig = sigmask(SIGILL);
                    374:                p->p_sigignore &= ~sig;
                    375:                p->p_sigcatch &= ~sig;
                    376:                p->p_sigmask &= ~sig;
                    377:                psignal(p, SIGILL);
                    378:                return;
                    379:        }
                    380:        /* 
                    381:         * Build the argument list for the signal handler.
                    382:         */
                    383:        fp->sf_signum = sig;
                    384:        fp->sf_code = code;
                    385:        fp->sf_scp = scp;
                    386:        fp->sf_handler = catcher;
                    387:        /*
                    388:         * Build the calls argument frame to be used to call sigreturn
                    389:         */
                    390:        fp->sf_argcount = 1;
                    391:        fp->sf_scpcopy = scp;
                    392:        /*
                    393:         * Build the signal context to be used by sigreturn.
                    394:         */
                    395:        scp->sc_onstack = oonstack;
                    396:        scp->sc_mask = mask;
                    397:        scp->sc_sp = regs[SP];
                    398:        scp->sc_fp = regs[FP];
                    399:        scp->sc_ap = regs[AP];
                    400:        scp->sc_pc = regs[PC];
                    401:        scp->sc_ps = regs[PS];
                    402:        regs[SP] = (int)fp;
                    403:        regs[PS] &= ~(PSL_CM|PSL_FPD);
                    404:        regs[PC] = (int)u.u_pcb.pcb_sigc;
                    405:        return;
                    406: }
                    407: 
                    408: /*
                    409:  * System call to cleanup state after a signal
                    410:  * has been taken.  Reset signal mask and
                    411:  * stack state from context left by sendsig (above).
                    412:  * Return to previous pc and psl as specified by
                    413:  * context left by sendsig. Check carefully to
                    414:  * make sure that the user has not modified the
                    415:  * psl to gain improper priviledges or to cause
                    416:  * a machine fault.
                    417:  */
                    418: /* ARGSUSED */
                    419: sigreturn(p, uap, retval)
                    420:        struct proc *p;
                    421:        struct args {
                    422:                struct sigcontext *sigcntxp;
                    423:        } *uap;
                    424:        int *retval;
                    425: {
                    426:        register struct sigcontext *scp;
                    427:        register int *regs = u.u_ar0;
                    428: 
                    429:        scp = uap->sigcntxp;
                    430:        if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0)
                    431:                return (EINVAL);
                    432:        if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_IS)) != 0 ||
                    433:            (scp->sc_ps & (PSL_PRVMOD|PSL_CURMOD)) != (PSL_PRVMOD|PSL_CURMOD) ||
                    434:            ((scp->sc_ps & PSL_CM) &&
                    435:             (scp->sc_ps & (PSL_FPD|PSL_DV|PSL_FU|PSL_IV)) != 0))
                    436:                return (EINVAL);
                    437:        u.u_onstack = scp->sc_onstack & 01;
                    438:        p->p_sigmask = scp->sc_mask &~ sigcantmask;
                    439:        regs[FP] = scp->sc_fp;
                    440:        regs[AP] = scp->sc_ap;
                    441:        regs[SP] = scp->sc_sp;
                    442:        regs[PC] = scp->sc_pc;
                    443:        regs[PS] = scp->sc_ps;
                    444:        return (EJUSTRETURN);
                    445: }
                    446: 
                    447: /*
                    448:  * Memenable enables memory controller corrected data reporting.
                    449:  * This runs at regular intervals, turning on the interrupt.
                    450:  * The interrupt is turned off, per memory controller, when error
                    451:  * reporting occurs.  Thus we report at most once per memintvl.
                    452:  */
                    453: int    memintvl = MEMINTVL;
                    454: 
                    455: memenable()
                    456: {
                    457: 
                    458:        (*cpuops->cpu_memenable)();
                    459:        if (memintvl > 0)
                    460:                timeout(memenable, (caddr_t)0, memintvl*hz);
                    461: }
                    462: 
                    463: /*
                    464:  * Memerr is the interrupt routine for corrected read data
                    465:  * interrupts.  It looks to see which memory controllers have
                    466:  * unreported errors, reports them, and disables further
                    467:  * reporting for a time on those controller.
                    468:  */
                    469: memerr()
                    470: {
                    471: 
                    472:        (*cpuops->cpu_memerr)();
                    473: }
                    474: 
                    475: /*
                    476:  * Invalidate single all pte's in a cluster
                    477:  */
                    478: tbiscl(v)
                    479:        unsigned v;
                    480: {
                    481:        register caddr_t addr;          /* must be first reg var */
                    482:        register int i;
                    483: 
                    484:        asm(".set TBIS,58");
                    485:        addr = ptob(v);
                    486:        for (i = 0; i < CLSIZE; i++) {
                    487: #ifdef lint
                    488:                mtpr(TBIS, addr);
                    489: #else
                    490:                asm("mtpr r11,$TBIS");
                    491: #endif
                    492:                addr += NBPG;
                    493:        }
                    494: }
                    495:   
                    496: int    waittime = -1;
                    497: 
                    498: boot(howto)
                    499:        register int howto;             /* r11 == how to boot */
                    500: {
                    501:        register int devtype;           /* r10 == major of root dev */
                    502:        extern char *panicstr;
                    503: 
                    504:        if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) {
                    505:                register struct buf *bp;
                    506:                int iter, nbusy;
                    507: 
                    508:                waittime = 0;
                    509:                (void) splnet();
                    510:                printf("syncing disks... ");
                    511:                /*
                    512:                 * Release vnodes held by texts before sync.
                    513:                 */
                    514:                if (panicstr == 0)
                    515:                        xumount(NULL);
                    516:                sync();
                    517: 
                    518:                for (iter = 0; iter < 20; iter++) {
                    519:                        nbusy = 0;
                    520:                        for (bp = &buf[nbuf]; --bp >= buf; )
                    521:                                if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
                    522:                                        nbusy++;
                    523:                        if (nbusy == 0)
                    524:                                break;
                    525:                        printf("%d ", nbusy);
                    526:                        DELAY(40000 * iter);
                    527:                }
                    528:                if (nbusy)
                    529:                        printf("giving up\n");
                    530:                else
                    531:                        printf("done\n");
                    532:                /*
                    533:                 * If we've been adjusting the clock, the todr
                    534:                 * will be out of synch; adjust it now.
                    535:                 */
                    536:                resettodr();
                    537:        }
                    538:        splx(0x1f);                     /* extreme priority */
                    539:        devtype = major(rootdev);
                    540:        if (howto&RB_HALT) {
                    541:                switch (cpu) {
                    542: 
                    543:                /* 630 can be told to halt, but how? */
                    544: #if VAX650
                    545:                case VAX_650:
                    546:                        ka650ssc.ssc_cpmbx &= ~CPMB650_HALTACT;
                    547:                        ka650ssc.ssc_cpmbx |= CPMB650_HALT;
                    548:                        asm("halt");
                    549: #endif
                    550:                }
                    551:                printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n");
                    552:                for (;;)
                    553:                        ;
                    554:        } else {
                    555:                if (howto & RB_DUMP)
                    556:                        doadump();
                    557:                vaxboot();
                    558:        }
                    559: #ifdef lint
                    560:        devtype = devtype;
                    561: #endif
                    562:        /*NOTREACHED*/
                    563: }
                    564: 
                    565: /*
                    566:  * Reboot after panic or via reboot system call.  Note that r11
                    567:  * and r10 must already have the proper boot values (`call by voodoo').
                    568:  */
                    569: vaxboot()
                    570: {
                    571: 
                    572:        switch (cpu) {
                    573: 
                    574: #ifdef VAX8200
                    575:        case VAX_8200:
                    576:                /*
                    577:                 * TXDB_BOOT erases memory!  Instead we set the `did
                    578:                 * a dump' flag in the rpb.
                    579:                 */
                    580:                *(int *)&Sysmap[0] &= ~PG_PROT;
                    581:                *(int *)&Sysmap[0] |= PG_KW;
                    582:                mtpr(TBIS, &rpb);
                    583:                rpb.rp_flag = 1;
                    584:                break;
                    585: #endif
                    586: 
                    587: #ifdef VAX650
                    588:        case VAX_650:
                    589:                /* set boot-on-halt flag in "console mailbox" */
                    590:                ka650ssc.ssc_cpmbx &= ~CPMB650_HALTACT;
                    591:                ka650ssc.ssc_cpmbx |= CPMB650_REBOOT;
                    592:                break;
                    593: #endif
                    594: 
                    595:        default:
                    596:                tocons(TXDB_BOOT);
                    597:        }
                    598: 
                    599:        /*
                    600:         * Except on 780s and 8600s, boot flags go in r5.  SBI
                    601:         * VAXen do not care, so copy boot flags to r5 always.
                    602:         */
                    603:        asm("movl r11,r5");
                    604:        for (;;) {
                    605:                asm("halt");
                    606:        }
                    607: }
                    608: 
                    609: tocons(c)
                    610: {
                    611:        register int oldmask;
                    612: 
                    613:        while (((oldmask = mfpr(TXCS)) & TXCS_RDY) == 0)
                    614:                continue;
                    615: 
                    616:        switch (cpu) {
                    617: 
                    618: #if VAX8200 || VAX780 || VAX750 || VAX730 || VAX630
                    619:        case VAX_8200:
                    620:        case VAX_780:
                    621:        case VAX_750:
                    622:        case VAX_730:
                    623:        case VAX_630:
                    624:                c |= TXDB_CONS;
                    625:                break;
                    626: #endif
                    627: 
                    628: #if VAX8600
                    629:        case VAX_8600:
                    630:                mtpr(TXCS, TXCS_LCONS | TXCS_WMASK);
                    631:                while ((mfpr(TXCS) & TXCS_RDY) == 0)
                    632:                        continue;
                    633:                break;
                    634: #endif
                    635: 
                    636: #if VAX650
                    637:        case VAX_650:
                    638:                /* everything is a real console terminal character on ka650 */
                    639:                return;
                    640: #endif
                    641:        }
                    642: 
                    643:        mtpr(TXDB, c);
                    644: 
                    645: #if VAX8600
                    646:        switch (cpu) {
                    647: 
                    648:        case VAX_8600:
                    649:                while ((mfpr(TXCS) & TXCS_RDY) == 0)
                    650:                        continue;
                    651:                mtpr(TXCS, oldmask | TXCS_WMASK);
                    652:                break;
                    653:        }
                    654: #endif
                    655: #ifdef lint
                    656:        oldmask = oldmask;
                    657: #endif
                    658: }
                    659: 
                    660: int    dumpmag = 0x8fca0101;   /* magic number for savecore */
                    661: int    dumpsize = 0;           /* also for savecore */
                    662: 
                    663: dumpconf()
                    664: {
                    665:        int nblks;
                    666: 
                    667:        dumpsize = physmem;
                    668:        if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
                    669:                nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
                    670:                if (dumpsize > btoc(dbtob(nblks - dumplo)))
                    671:                        dumpsize = btoc(dbtob(nblks - dumplo));
                    672:                else if (dumplo == 0)
                    673:                        dumplo = nblks - btodb(ctob(physmem));
                    674:        }
                    675:        /*
                    676:         * Don't dump on the first CLSIZE pages,
                    677:         * in case the dump device includes a disk label.
                    678:         */
                    679:        if (dumplo < CLSIZE)
                    680:                dumplo = CLSIZE;
                    681: }
                    682: 
                    683: /*
                    684:  * Doadump comes here after turning off memory management and
                    685:  * getting on the dump stack, either when called above, or by
                    686:  * the auto-restart code.
                    687:  */
                    688: dumpsys()
                    689: {
                    690: 
                    691:        rpb.rp_flag = 1;
                    692:        msgbufmapped = 0;
                    693:        if (dumpdev == NODEV)
                    694:                return;
                    695:        /*
                    696:         * For dumps during autoconfiguration,
                    697:         * if dump device has already configured...
                    698:         */
                    699:        if (dumpsize == 0)
                    700:                dumpconf();
                    701:        if (dumplo < 0)
                    702:                return;
                    703:        printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
                    704:        printf("dump ");
                    705:        switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
                    706: 
                    707:        case ENXIO:
                    708:                printf("device bad\n");
                    709:                break;
                    710: 
                    711:        case EFAULT:
                    712:                printf("device not ready\n");
                    713:                break;
                    714: 
                    715:        case EINVAL:                                    /* XXX */
                    716:                printf("area improper\n");
                    717:                break;
                    718: 
                    719:        case EIO:
                    720:                printf("i/o error");
                    721:                break;
                    722: 
                    723:        default:
                    724:                printf("succeeded");
                    725:                break;
                    726:        }
                    727: }
                    728: 
                    729: /*
                    730:  * Machine check error recovery code.
                    731:  */
                    732: machinecheck(cmcf)
                    733:        caddr_t cmcf;
                    734: {
                    735: 
                    736:        if ((*cpuops->cpu_mchk)(cmcf) == MCHK_RECOVERED)
                    737:                return;
                    738:        (*cpuops->cpu_memerr)();
                    739:        panic("mchk");
                    740: }
                    741: 
                    742: #if defined(VAX780) || defined(VAX750)
                    743: /*
                    744:  * These strings are shared between the 780 and 750 machine check code
                    745:  * in ka780.c and ka730.c.
                    746:  */
                    747: char *mc780750[16] = {
                    748:        "cp read",      "ctrl str par", "cp tbuf par",  "cp cache par",
                    749:        "cp rdtimo",    "cp rds",       "ucode lost",   0,
                    750:        0,              0,              "ib tbuf par",  0,
                    751:        "ib rds",       "ib rd timo",   0,              "ib cache par"
                    752: };
                    753: #endif
                    754: 
                    755: /*
                    756:  * Return the best possible estimate of the time in the timeval
                    757:  * to which tvp points.  We do this by reading the interval count
                    758:  * register to determine the time remaining to the next clock tick.
                    759:  * We must compensate for wraparound which is not yet reflected in the time
                    760:  * (which happens when the ICR hits 0 and wraps after the splhigh(),
                    761:  * but before the mfpr(ICR)).  Also check that this time is no less than
                    762:  * any previously-reported time, which could happen around the time
                    763:  * of a clock adjustment.  Just for fun, we guarantee that the time
                    764:  * will be greater than the value obtained by a previous call.
                    765:  */
                    766: microtime(tvp)
                    767:        register struct timeval *tvp;
                    768: {
                    769:        int s = splhigh();
                    770:        static struct timeval lasttime;
                    771:        register long t;
                    772: 
                    773:        *tvp = time;
                    774:        t =  mfpr(ICR);
                    775:        if (t < -tick / 2 && (mfpr(ICCS) & ICCS_INT))
                    776:                t += tick;
                    777:        tvp->tv_usec += tick + t;
                    778:        if (tvp->tv_usec > 1000000) {
                    779:                tvp->tv_sec++;
                    780:                tvp->tv_usec -= 1000000;
                    781:        }
                    782:        if (tvp->tv_sec == lasttime.tv_sec &&
                    783:            tvp->tv_usec <= lasttime.tv_usec &&
                    784:            (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
                    785:                tvp->tv_sec++;
                    786:                tvp->tv_usec -= 1000000;
                    787:        }
                    788:        lasttime = *tvp;
                    789:        splx(s);
                    790: }
                    791: 
                    792: initcpu()
                    793: {
                    794:        /*
                    795:         * Enable cache.
                    796:         */
                    797:        switch (cpu) {
                    798: 
                    799: #if VAX8600
                    800:        case VAX_8600:
                    801:                mtpr(CSWP, 3);
                    802:                break;
                    803: #endif
                    804: #if VAX8200
                    805:        case VAX_8200:
                    806:                mtpr(CADR, 0);
                    807:                break;
                    808: #endif
                    809: #if VAX780
                    810:        case VAX_780:
                    811:                mtpr(SBIMT, 0x200000);
                    812:                break;
                    813: #endif
                    814: #if VAX750
                    815:        case VAX_750:
                    816:                mtpr(CADR, 0);
                    817:                break;
                    818: #endif
                    819:        default:
                    820:                break;
                    821:        }
                    822: 
                    823:        /*
                    824:         * Enable floating point accelerator if it exists
                    825:         * and has control register.
                    826:         */
                    827:        switch(cpu) {
                    828: 
                    829: #if VAX8600 || VAX780
                    830:        case VAX_8600:
                    831:        case VAX_780:
                    832:                if ((mfpr(ACCS) & 0xff) != 0) {
                    833:                        printf("Enabling FPA\n");
                    834:                        mtpr(ACCS, 0x8000);
                    835:                }
                    836: #endif
                    837:        default:
                    838:                break;
                    839:        }
                    840: }
                    841: 
                    842: /*
                    843:  * Return a reasonable approximation of the time of day register.
                    844:  * More precisely, return a number that increases by one about
                    845:  * once every ten milliseconds.
                    846:  */
                    847: todr()
                    848: {
                    849: 
                    850:        switch (cpu) {
                    851: 
                    852: #if VAX8600 || VAX8200 || VAX780 || VAX750 || VAX730 || VAX650
                    853:        case VAX_8600:
                    854:        case VAX_8200:
                    855:        case VAX_780:
                    856:        case VAX_750:
                    857:        case VAX_730:
                    858:        case VAX_650:
                    859:                return (mfpr(TODR));
                    860: #endif
                    861: 
                    862: #if VAX630
                    863:        case VAX_630:
                    864:                /* XXX crude */
                    865:                { static int t; DELAY(10000); return (++t); }
                    866: #endif
                    867: 
                    868:        default:
                    869:                panic("todr");
                    870:        }
                    871:        /* NOTREACHED */
                    872: }

unix.superglobalmegacorp.com

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