Annotation of 43BSDTahoe/sys/tahoe/machdep.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982,1987,1988 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) 5/26/88
                      7:  */
                      8: 
                      9: #include "param.h"
                     10: #include "systm.h"
                     11: #include "dir.h"
                     12: #include "user.h"
                     13: #include "kernel.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 "inode.h"
                     21: #include "file.h"
                     22: #include "text.h"
                     23: #include "clist.h"
                     24: #include "callout.h"
                     25: #include "cmap.h"
                     26: #include "malloc.h"
                     27: #include "mbuf.h"
                     28: #include "msgbuf.h"
                     29: #include "quota.h"
                     30: 
                     31: #include "cpu.h"
                     32: #include "reg.h"
                     33: #include "pte.h"
                     34: #include "psl.h"
                     35: #include "mem.h"
                     36: #include "mtpr.h"
                     37: #include "cp.h"
                     38: 
                     39: #include "../tahoevba/vbavar.h"
                     40: 
                     41: /*
                     42:  * Declare these as initialized data so we can patch them.
                     43:  */
                     44: int    nswbuf = 0;
                     45: #ifdef NBUF
                     46: int    nbuf = NBUF;
                     47: #else
                     48: int    nbuf = 0;
                     49: #endif
                     50: #ifdef BUFPAGES
                     51: int    bufpages = BUFPAGES;
                     52: #else
                     53: int    bufpages = 0;
                     54: #endif
                     55: #include "yc.h"
                     56: #if NCY > 0
                     57: #include "../tahoevba/cyreg.h"
                     58: #endif
                     59: int    msgbufmapped;           /* set when safe to use msgbuf */
                     60: 
                     61: /*
                     62:  * Machine-dependent startup code
                     63:  */
                     64: startup(firstaddr)
                     65:        int firstaddr;
                     66: {
                     67:        register int unixsize;
                     68:        register unsigned i;
                     69:        register struct pte *pte;
                     70:        int mapaddr, j;
                     71:        register caddr_t v;
                     72:        int maxbufs, base, residual;
                     73: 
                     74:        /*
                     75:         * Initialize error message buffer (at end of core).
                     76:         */
                     77:        maxmem -= btoc(sizeof (struct msgbuf));
                     78:        pte = msgbufmap;
                     79:        for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
                     80:                *(int *)pte++ = PG_V | PG_KW | (maxmem + i);
                     81:        mtpr(TBIA, 1);
                     82:        msgbufmapped = 1;
                     83: #ifdef KADB
                     84:        kdb_init();                     /* startup kernel debugger */
                     85: #endif
                     86:        /*
                     87:         * Good {morning,afternoon,evening,night}.
                     88:         */
                     89:        printf(version);
                     90:        printf("real mem  = %d\n", ctob(physmem));
                     91: 
                     92:        /*
                     93:         * Allocate space for system data structures.
                     94:         * The first available real memory address is in "firstaddr".
                     95:         * The first available kernel virtual address is in "v".
                     96:         * As pages of kernel virtual memory are allocated, "v" is incremented.
                     97:         * As pages of memory are allocated and cleared,
                     98:         * "firstaddr" is incremented.
                     99:         * An index into the kernel page table corresponding to the
                    100:         * virtual memory address maintained in "v" is kept in "mapaddr".
                    101:         */
                    102:        v = (caddr_t)(0xc0000000 | (firstaddr * NBPG));
                    103: #define        valloc(name, type, num) \
                    104:            (name) = (type *)v; v = (caddr_t)((name)+(num))
                    105: #define        valloclim(name, type, num, lim) \
                    106:            (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
                    107: #if NCY > 0
                    108:        /*
                    109:         * Allocate raw buffers for tapemaster controllers
                    110:         * first, as they need buffers in the first megabyte.
                    111:         */
                    112:        valloc(cybuf, char, NCY * CYMAXIO);
                    113: #endif
                    114:        valloclim(inode, struct inode, ninode, inodeNINODE);
                    115:        valloclim(file, struct file, nfile, fileNFILE);
                    116:        valloclim(proc, struct proc, nproc, procNPROC);
                    117:        valloclim(text, struct text, ntext, textNTEXT);
                    118:        valloc(cfree, struct cblock, nclist);
                    119:        valloc(callout, struct callout, ncallout);
                    120:        valloc(swapmap, struct map, nswapmap = nproc * 2);
                    121:        valloc(argmap, struct map, ARGMAPSIZE);
                    122:        valloc(kernelmap, struct map, nproc);
                    123:        valloc(mbmap, struct map, nmbclusters/4);
                    124:        valloc(namecache, struct namecache, nchsize);
                    125:        valloc(kmemmap, struct map, ekmempt - kmempt);
                    126:        valloc(kmemusage, struct kmemusage, ekmempt - kmempt);
                    127: #ifdef QUOTA
                    128:        valloclim(quota, struct quota, nquota, quotaNQUOTA);
                    129:        valloclim(dquot, struct dquot, ndquot, dquotNDQUOT);
                    130: #endif
                    131:        
                    132:        /*
                    133:         * Determine how many buffers to allocate.
                    134:         * Use 10% of memory for the first 2 Meg, 5% of the remaining
                    135:         * memory. Insure a minimum of 16 buffers.
                    136:         * We allocate 1/2 as many swap buffer headers as file i/o buffers.
                    137:         */
                    138:        if (bufpages == 0)
                    139:                if (physmem < (2 * 1024 * 1024))
                    140:                        bufpages = physmem / 10 / CLSIZE;
                    141:                else
                    142:                        bufpages = ((2 * 1024 * 1024 + physmem) / 20) / CLSIZE;
                    143:        if (nbuf == 0) {
                    144:                nbuf = bufpages / 2;
                    145:                if (nbuf < 16)
                    146:                        nbuf = 16;
                    147:        }
                    148:        if (nswbuf == 0) {
                    149:                nswbuf = (nbuf / 2) &~ 1;       /* force even */
                    150:                if (nswbuf > 256)
                    151:                        nswbuf = 256;           /* sanity */
                    152:        }
                    153:        valloc(swbuf, struct buf, nswbuf);
                    154: 
                    155:        /*
                    156:         * Now the amount of virtual memory remaining for buffers
                    157:         * can be calculated, estimating needs for the cmap.
                    158:         */
                    159:        ncmap = (maxmem*NBPG - ((int)v &~ 0xc0000000)) /
                    160:                (CLBYTES + sizeof(struct cmap)) + 2;
                    161:        maxbufs = ((SYSPTSIZE * NBPG) -
                    162:            ((int)(v + ncmap * sizeof(struct cmap)) - 0xc0000000)) /
                    163:                (MAXBSIZE + sizeof(struct buf));
                    164:        if (maxbufs < 16)
                    165:                panic("sys pt too small");
                    166:        if (nbuf > maxbufs) {
                    167:                printf("SYSPTSIZE limits number of buffers to %d\n", maxbufs);
                    168:                nbuf = maxbufs;
                    169:        }
                    170:        if (bufpages > nbuf * (MAXBSIZE / CLBYTES))
                    171:                bufpages = nbuf * (MAXBSIZE / CLBYTES);
                    172:        valloc(buf, struct buf, nbuf);
                    173: 
                    174:        /*
                    175:         * Allocate space for core map.
                    176:         * Allow space for all of phsical memory minus the amount 
                    177:         * dedicated to the system. The amount of physical memory
                    178:         * dedicated to the system is the total virtual memory of
                    179:         * the system thus far, plus core map, buffer pages,
                    180:         * and buffer headers not yet allocated.
                    181:         * Add 2: 1 because the 0th entry is unused, 1 for rounding.
                    182:         */
                    183:        ncmap = (maxmem*NBPG - ((int)(v + bufpages*CLBYTES) &~ 0xc0000000)) /
                    184:                (CLBYTES + sizeof(struct cmap)) + 2;
                    185:        valloclim(cmap, struct cmap, ncmap, ecmap);
                    186: 
                    187:        /*
                    188:         * Clear space allocated thus far, and make r/w entries
                    189:         * for the space in the kernel map.
                    190:         */
                    191:        unixsize = btoc((int)v &~ 0xc0000000);
                    192:        while (firstaddr < unixsize) {
                    193:                *(int *)(&Sysmap[firstaddr]) = PG_V | PG_KW | firstaddr;
                    194:                clearseg((unsigned)firstaddr);
                    195:                firstaddr++;
                    196:        }
                    197: 
                    198:        /*
                    199:         * Now allocate buffers proper.  They are different than the above
                    200:         * in that they usually occupy more virtual memory than physical.
                    201:         */
                    202:        v = (caddr_t) ((int)(v + PGOFSET) &~ PGOFSET);
                    203:        valloc(buffers, char, MAXBSIZE * nbuf);
                    204:        base = bufpages / nbuf;
                    205:        residual = bufpages % nbuf;
                    206:        mapaddr = firstaddr;
                    207:        for (i = 0; i < residual; i++) {
                    208:                for (j = 0; j < (base + 1) * CLSIZE; j++) {
                    209:                        *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr;
                    210:                        clearseg((unsigned)firstaddr);
                    211:                        firstaddr++;
                    212:                }
                    213:                mapaddr += MAXBSIZE / NBPG;
                    214:        }
                    215:        for (i = residual; i < nbuf; i++) {
                    216:                for (j = 0; j < base * CLSIZE; j++) {
                    217:                        *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr;
                    218:                        clearseg((unsigned)firstaddr);
                    219:                        firstaddr++;
                    220:                }
                    221:                mapaddr += MAXBSIZE / NBPG;
                    222:        }
                    223: 
                    224:        unixsize = btoc((int)v &~ 0xc0000000);
                    225:        if (firstaddr >= physmem - 8*UPAGES)
                    226:                panic("no memory");
                    227:        mtpr(TBIA, 1);                  /* After we just cleared it all! */
                    228: 
                    229:        /*
                    230:         * Initialize callouts
                    231:         */
                    232:        callfree = callout;
                    233:        for (i = 1; i < ncallout; i++)
                    234:                callout[i-1].c_next = &callout[i];
                    235: 
                    236:        /*
                    237:         * Initialize memory allocator and swap
                    238:         * and user page table maps.
                    239:         *
                    240:         * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''
                    241:         * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.
                    242:         */
                    243:        meminit(firstaddr, maxmem);
                    244:        maxmem = freemem;
                    245:        printf("avail mem = %d\n", ctob(maxmem));
                    246:        printf("using %d buffers containing %d bytes of memory\n",
                    247:                nbuf, bufpages * CLBYTES);
                    248:        rminit(kernelmap, (long)USRPTSIZE, (long)1,
                    249:            "usrpt", nproc);
                    250:        rminit(mbmap, (long)(nmbclusters * CLSIZE), (long)CLSIZE,
                    251:            "mbclusters", nmbclusters/4);
                    252:        kmeminit();             /* now safe to do malloc/free */
                    253:        intenable = 1;          /* Enable interrupts from now on */
                    254: 
                    255:        /*
                    256:         * Set up CPU-specific registers, cache, etc.
                    257:         */
                    258:        initcpu();
                    259: 
                    260:        /*
                    261:         * Set up buffers, so they can be used to read disk labels.
                    262:         */
                    263:        bhinit();
                    264:        binit();
                    265: 
                    266:        /*
                    267:         * Configure the system.
                    268:         */
                    269:        configure();
                    270: }
                    271: 
                    272: #ifdef PGINPROF
                    273: /*
                    274:  * Return the difference (in microseconds)
                    275:  * between the  current time and a previous
                    276:  * time as represented  by the arguments.
                    277:  * If there is a pending clock interrupt
                    278:  * which has not been serviced due to high
                    279:  * ipl, return error code.
                    280:  */
                    281: /*ARGSUSED*/
                    282: vmtime(otime, olbolt, oicr)
                    283:        register int otime, olbolt, oicr;
                    284: {
                    285: 
                    286:        return (((time.tv_sec-otime)*60 + lbolt-olbolt)*16667);
                    287: }
                    288: #endif
                    289: 
                    290: /*
                    291:  * Send an interrupt to process.
                    292:  *
                    293:  * Stack is set up to allow sigcode stored
                    294:  * in u. to call routine, followed by kcall
                    295:  * to sigreturn routine below.  After sigreturn
                    296:  * resets the signal mask, the stack, and the
                    297:  * frame pointer, it returns to the user
                    298:  * specified pc, psl.
                    299:  */
                    300: sendsig(p, sig, mask)
                    301:        int (*p)(), sig, mask;
                    302: {
                    303:        register struct sigcontext *scp;
                    304:        register int *regs;
                    305:        register struct sigframe {
                    306:                int     sf_signum;
                    307:                int     sf_code;
                    308:                struct  sigcontext *sf_scp;
                    309:                int     (*sf_handler)();
                    310:                int     sf_regs[6];             /* r0-r5 */
                    311:                struct  sigcontext *sf_scpcopy;
                    312:        } *fp;
                    313:        int oonstack;
                    314: 
                    315:        regs = u.u_ar0;
                    316:        oonstack = u.u_onstack;
                    317:        /*
                    318:         * Allocate and validate space for the signal handler
                    319:         * context. Note that if the stack is in P0 space, the
                    320:         * call to grow() is a nop, and the useracc() check
                    321:         * will fail if the process has not already allocated
                    322:         * the space with a `brk'.
                    323:         */
                    324:        if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) {
                    325:                scp = (struct sigcontext *)u.u_sigsp - 1;
                    326:                u.u_onstack = 1;
                    327:        } else
                    328:                scp = (struct sigcontext *)regs[SP] - 1;
                    329:        fp = (struct sigframe *)scp - 1;
                    330:        if ((int)fp <= USRSTACK - ctob(u.u_ssize)) 
                    331:                (void) grow((unsigned)fp);
                    332:        if (useracc((caddr_t)fp, sizeof (*fp) + sizeof (*scp), B_WRITE) == 0) {
                    333:                /*
                    334:                 * Process has trashed its stack; give it an illegal
                    335:                 * instruction to halt it in its tracks.
                    336:                 */
                    337:                u.u_signal[SIGILL] = SIG_DFL;
                    338:                sig = sigmask(SIGILL);
                    339:                u.u_procp->p_sigignore &= ~sig;
                    340:                u.u_procp->p_sigcatch &= ~sig;
                    341:                u.u_procp->p_sigmask &= ~sig;
                    342:                psignal(u.u_procp, SIGILL);
                    343:                return;
                    344:        }
                    345:        /* 
                    346:         * Build the argument list for the signal handler.
                    347:         */
                    348:        fp->sf_signum = sig;
                    349:        if (sig == SIGILL || sig == SIGFPE) {
                    350:                fp->sf_code = u.u_code;
                    351:                u.u_code = 0;
                    352:        } else
                    353:                fp->sf_code = 0;
                    354:        fp->sf_scp = scp;
                    355:        fp->sf_handler = p;
                    356:        /*
                    357:         * Build the callf argument frame to be used to call sigreturn.
                    358:         */
                    359:        fp->sf_scpcopy = scp;
                    360:        /*
                    361:         * Build the signal context to be used by sigreturn.
                    362:         */
                    363:        scp->sc_onstack = oonstack;
                    364:        scp->sc_mask = mask;
                    365:        scp->sc_sp = regs[SP];
                    366:        scp->sc_fp = regs[FP];
                    367:        scp->sc_pc = regs[PC];
                    368:        scp->sc_ps = regs[PS];
                    369:        regs[SP] = (int)fp;
                    370:        regs[PC] = (int)u.u_pcb.pcb_sigc;
                    371: }
                    372: 
                    373: /*
                    374:  * System call to cleanup state after a signal
                    375:  * has been taken.  Reset signal mask and
                    376:  * stack state from context left by sendsig (above).
                    377:  * Return to previous pc and psl as specified by
                    378:  * context left by sendsig. Check carefully to
                    379:  * make sure that the user has not modified the
                    380:  * psl to gain improper priviledges or to cause
                    381:  * a machine fault.
                    382:  */
                    383: sigreturn()
                    384: {
                    385:        struct a {
                    386:                struct sigcontext *sigcntxp;
                    387:        };
                    388:        register struct sigcontext *scp;
                    389:        register int *regs = u.u_ar0;
                    390: 
                    391:        scp = ((struct a *)(u.u_ap))->sigcntxp;
                    392:        if (useracc((caddr_t)scp, sizeof (*scp), 0) == 0) {
                    393:                u.u_error = EINVAL;
                    394:                return;
                    395:        }
                    396:        if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_IS)) != 0 ||
                    397:            (scp->sc_ps & (PSL_PRVMOD|PSL_CURMOD)) != (PSL_PRVMOD|PSL_CURMOD)) {
                    398:                u.u_error = EINVAL;
                    399:                return;
                    400:        }
                    401:        u.u_eosys = JUSTRETURN;
                    402:        u.u_onstack = scp->sc_onstack & 01;
                    403:        u.u_procp->p_sigmask = scp->sc_mask &~
                    404:            (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
                    405:        regs[FP] = scp->sc_fp;
                    406:        regs[SP] = scp->sc_sp;
                    407:        regs[PC] = scp->sc_pc;
                    408:        regs[PS] = scp->sc_ps;
                    409: }
                    410: 
                    411: /* XXX - BEGIN 4.2 COMPATIBILITY */
                    412: /*
                    413:  * Compatibility with 4.2 kcall $139 used by longjmp()
                    414:  */
                    415: osigcleanup()
                    416: {
                    417:        register struct sigcontext *scp;
                    418:        register int *regs = u.u_ar0;
                    419: 
                    420:        scp = (struct sigcontext *)fuword((caddr_t)regs[SP]);
                    421:        if ((int)scp == -1)
                    422:                return;
                    423:        if (useracc((caddr_t)scp, 3 * sizeof (int), 0) == 0)
                    424:                return;
                    425:        u.u_onstack = scp->sc_onstack & 01;
                    426:        u.u_procp->p_sigmask = scp->sc_mask &~
                    427:            (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
                    428:        regs[SP] = scp->sc_sp;
                    429: }
                    430: /* XXX - END 4.2 COMPATIBILITY */
                    431: 
                    432: int    waittime = -1;
                    433: 
                    434: boot(arghowto)
                    435:        int arghowto;
                    436: {
                    437:        register long dummy;            /* r12 is reserved */
                    438:        register int howto;             /* r11 == how to boot */
                    439:        register int devtype;           /* r10 == major of root dev */
                    440:        extern char *panicstr;
                    441: 
                    442:        howto = arghowto;
                    443:        if ((howto&RB_NOSYNC) == 0 && waittime < 0 && bfreelist[0].b_forw) {
                    444:                register struct buf *bp;
                    445:                int iter, nbusy;
                    446: 
                    447:                waittime = 0;
                    448:                (void) splnet();
                    449:                printf("syncing disks... ");
                    450:                /*
                    451:                 * Release inodes held by texts before update.
                    452:                 */
                    453:                if (panicstr == 0)
                    454:                        xumount(NODEV);
                    455:                update();
                    456: 
                    457:                for (iter = 0; iter < 20; iter++) {
                    458:                        nbusy = 0;
                    459:                        for (bp = &buf[nbuf]; --bp >= buf; )
                    460:                                if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
                    461:                                        nbusy++;
                    462:                        if (nbusy == 0)
                    463:                                break;
                    464:                        printf("%d ", nbusy);
                    465:                        DELAY(40000 * iter);
                    466:                }
                    467:                if (nbusy)
                    468:                        printf("giving up\n");
                    469:                else
                    470:                        printf("done\n");
                    471:                DELAY(10000);                   /* wait for printf to finish */
                    472:        }
                    473:        mtpr(IPL, 0x1f);                        /* extreme priority */
                    474:        devtype = major(rootdev);
                    475:        *(int *)CPBFLG = howto;
                    476:        if (howto&RB_HALT) {
                    477:                printf("halting (in tight loop); hit ~h\n\n");
                    478:                mtpr(IPL, 0x1f);
                    479:                for (;;)
                    480:                        ;
                    481:        } else {
                    482:                if (howto & RB_DUMP) {
                    483:                        doadump();              /* CPBOOT's itsself */
                    484:                        /*NOTREACHED*/
                    485:                }
                    486:                tocons(CPBOOT);
                    487:        }
                    488: #ifdef lint
                    489:        dummy = 0; dummy = dummy;
                    490:        printf("howto %d, devtype %d\n", arghowto, devtype);
                    491: #endif
                    492:        for (;;)
                    493:                asm("halt");
                    494:        /*NOTREACHED*/
                    495: }
                    496: 
                    497: struct cpdcb_o cpcontrol;
                    498: 
                    499: /*
                    500:  * Send the given comand ('c') to the console processor.
                    501:  * Assumed to be one of the last things the OS does before
                    502:  *  halting or rebooting.
                    503:  */
                    504: tocons(c)
                    505: {
                    506:        register timeout;
                    507: 
                    508:        cpcontrol.cp_hdr.cp_unit = CPUNIT;
                    509:        cpcontrol.cp_hdr.cp_comm =  (char)c;
                    510:        if (c != CPBOOT) 
                    511:                cpcontrol.cp_hdr.cp_count = 1;  /* Just for sanity */
                    512:        else {
                    513:                cpcontrol.cp_hdr.cp_count = 4;
                    514:                *(int *)cpcontrol.cp_buf = 0;   /* r11 value for reboot */
                    515:        }
                    516:        timeout = 100000;                               /* Delay loop */
                    517:        while (timeout-- && (cnlast->cp_unit&CPDONE) == 0)
                    518:                uncache(&cnlast->cp_unit);
                    519:        /* give up, force it to listen */
                    520:        mtpr(CPMDCB, vtoph((struct proc *)0, (unsigned)&cpcontrol));
                    521: }
                    522: 
                    523: #if CLSIZE != 1
                    524: /*
                    525:  * Invalidate single all pte's in a cluster
                    526:  */
                    527: tbiscl(v)
                    528:        unsigned v;
                    529: {
                    530:        register caddr_t addr;          /* must be first reg var */
                    531:        register int i;
                    532: 
                    533:        addr = ptob(v);
                    534:        for (i = 0; i < CLSIZE; i++) {
                    535:                mtpr(TBIS, addr);
                    536:                addr += NBPG;
                    537:        }
                    538: }
                    539: #endif
                    540: 
                    541: int    dumpmag = 0x8fca0101;   /* magic number for savecore */
                    542: int    dumpsize = 0;           /* also for savecore */
                    543: /*
                    544:  * Doadump comes here after turning off memory management and
                    545:  * getting on the dump stack, either when called above, or by
                    546:  * the auto-restart code.
                    547:  */
                    548: dumpsys()
                    549: {
                    550: 
                    551:        if (dumpdev == NODEV)
                    552:                return;
                    553: #ifdef notdef
                    554:        if ((minor(dumpdev)&07) != 1)
                    555:                return;
                    556: #endif
                    557:        dumpsize = physmem;
                    558:        printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
                    559:        printf("dump ");
                    560:        switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
                    561: 
                    562:        case ENXIO:
                    563:                printf("device bad\n");
                    564:                break;
                    565: 
                    566:        case EFAULT:
                    567:                printf("device not ready\n");
                    568:                break;
                    569: 
                    570:        case EINVAL:
                    571:                printf("area improper\n");
                    572:                break;
                    573: 
                    574:        case EIO:
                    575:                printf("i/o error\n");
                    576:                break;
                    577: 
                    578:        default:
                    579:                printf("succeeded\n");
                    580:                break;
                    581:        }
                    582:        printf("\n\n");
                    583:        DELAY(1000);
                    584:        tocons(CPBOOT);
                    585: }
                    586: 
                    587: /*
                    588:  * Bus error 'recovery' code.
                    589:  * Print out the buss frame and then give up.
                    590:  * (More information from special registers can be printed here.)
                    591:  */
                    592: 
                    593: /*
                    594:  * Frame for bus error
                    595:  */
                    596: struct buserframe {
                    597:        int     which_bus;              /* primary or secondary */
                    598:        int     memerreg;               /* memory error register */
                    599:        int     trp_pc;                 /* trapped pc */
                    600:        int     trp_psl;                /* trapped psl */
                    601: };
                    602: 
                    603: char   *mem_errcd[8] = {
                    604:        "Unknown error code 0",
                    605:        "Address parity error",         /* APE */
                    606:        "Data parity error",            /* DPE */
                    607:        "Data check error",             /* DCE */
                    608:        "Versabus timeout",             /* VTO */
                    609:        "Versabus error",               /* VBE */
                    610:        "Non-existent memory",          /* NEM */
                    611:        "Unknown error code 7",
                    612: };
                    613: 
                    614: buserror(v)
                    615:        caddr_t v;
                    616: {
                    617:        register struct buserframe *busef = (struct buserframe *)v;
                    618:        register long reg;
                    619: 
                    620:        printf("bus error, address %x, psl %x\n",
                    621:            busef->trp_pc, busef->trp_psl);
                    622:        reg =  busef->memerreg;
                    623:        printf("mear %x %s\n",
                    624:            ((reg&MEAR)>>16)&0xffff, mem_errcd[reg & ERRCD]);
                    625:        if (reg&AXE)
                    626:                printf("adapter external error\n");
                    627:        printf("error master: %s\n", reg&ERM ? "versabus" : "tahoe");
                    628:        if (reg&IVV)
                    629:                printf("illegal interrupt vector from ipl %d\n", (reg>>2)&7);
                    630:        reg = busef->which_bus;
                    631:        printf("mcbr %x versabus type %x\n",
                    632:            ((reg&MCBR)>>16)&0xffff, reg & 0xffc3);
                    633:        if ((busef->memerreg&IVV) == 0)
                    634:                panic("buserror");
                    635: }
                    636: 
                    637: microtime(tvp)
                    638:        register struct timeval *tvp;
                    639: {
                    640:        int s = splhigh();
                    641: 
                    642:        *tvp = time;
                    643:        tvp->tv_usec += tick;
                    644:        while (tvp->tv_usec > 1000000) {
                    645:                tvp->tv_sec++;
                    646:                tvp->tv_usec -= 1000000;
                    647:        }
                    648:        splx(s);
                    649: }
                    650: 
                    651: initcpu()
                    652: {
                    653:        register struct proc *p;
                    654: 
                    655:        p = &proc[0];
                    656: #define        initkey(which, p, index) \
                    657:     which/**/_cache[index] = 1, which/**/_cnt[index] = 1; \
                    658:     p->p_/**/which = index;
                    659:        initkey(ckey, p, MAXCKEY);
                    660:        initkey(dkey, p, MAXDKEY);
                    661: }
                    662: 
                    663: /*
                    664:  * Clear registers on exec
                    665:  */
                    666: setregs(entry)
                    667:        u_long entry;
                    668: {
                    669: 
                    670: #ifdef notdef
                    671:        /* should pass args to init on the stack */
                    672:        for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
                    673:                *rp++ = 0;
                    674: #endif
                    675:        u.u_ar0[FP] = 0;        /* bottom of the fp chain */
                    676:        u.u_ar0[PC] = entry + 2;
                    677: }

unix.superglobalmegacorp.com

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