Annotation of researchv9/sys.vax/sys/machdep.c, revision 1.1.1.1

1.1       root        1: /*     machdep.c       4.36    81/05/09        */
                      2: 
                      3: #include "../h/param.h"
                      4: #include "../h/systm.h"
                      5: #include "../h/dir.h"
                      6: #include "../h/user.h"
                      7: #include "../h/map.h"
                      8: #include "../h/reg.h"
                      9: #include "../h/mtpr.h"
                     10: #include "../h/clock.h"
                     11: #include "../h/pte.h"
                     12: #include "../h/vm.h"
                     13: #include "../h/lnode.h"
                     14: #include "../h/proc.h"
                     15: #include "../h/psl.h"
                     16: #include "../h/buf.h"
                     17: #include "../h/nexus.h"
                     18: #include "../h/ubavar.h"
                     19: #include "../h/ubareg.h"
                     20: #include "../h/cons.h"
                     21: #include "../h/reboot.h"
                     22: #include "../h/conf.h"
                     23: #include "../h/mem.h"
                     24: #include "../h/cpu.h"
                     25: #include "../h/inode.h"
                     26: #include "../h/file.h"
                     27: #include "../h/text.h"
                     28: #include "../h/callout.h"
                     29: #include "../h/cmap.h"
                     30: #include <frame.h>
                     31: #include "../h/rpb.h"
                     32: #include <time.h>
                     33: 
                     34: int    icode[] =
                     35: {
                     36:        0x9f19af9f,     /* pushab [&"init",0]; pushab */
                     37:        0x02dd09af,     /* "/etc/init"; pushl $2 */
                     38:        0xbc5c5ed0,     /* movl sp,ap; chmk */
                     39:        0x2ffe110b,     /* $exec; brb .; "/ */
                     40:        0x2f637465,     /* etc/ */
                     41:        0x74696e69,     /* init" */
                     42:        0x00000000,     /* \0\0\0";  0 */
                     43:        0x00000014,     /* [&"init", */
                     44:        0x00000000,     /* 0] */
                     45: };
                     46: int    szicode = sizeof(icode);
                     47:  
                     48: /*
                     49:  * Declare these as initialized data so we can patch them.
                     50:  */
                     51: int    nbuf = 0;
                     52: int    nswbuf = 0;
                     53: 
                     54: /*
                     55:  * Machine-dependent startup code
                     56:  */
                     57: startup(firstaddr)
                     58:        int firstaddr;
                     59: {
                     60:        register int unixsize;
                     61:        register unsigned i;
                     62:        register struct pte *pte;
                     63:        register caddr_t v;
                     64: 
                     65:        /*
                     66:         * Initialize error message buffer (at end of core).
                     67:         */
                     68:        maxmem -= CLSIZE;
                     69:        pte = msgbufmap;
                     70:        for (i = 0; i < CLSIZE; i++)
                     71:                *(int *)pte++ = PG_V | PG_KW | (maxmem + i);
                     72:        mtpr(TBIA, 1);
                     73: 
                     74:        /*
                     75:         * Good {morning,afternoon,evening,night}.
                     76:         */
                     77:        printf(version);
                     78:        
                     79:        /*
                     80:         * First determine how many buffers are reasonable.
                     81:         * Current alg is 32 per megabyte, with min of 32.
                     82:         * We allocate 1/2 as many swap buffer headers as file i/o buffers.
                     83:         */
                     84:        if (nbuf == 0) {
                     85:                nbuf = (32 * physmem) / btoc(1024*1024);
                     86:                if (nbuf < 32)
                     87:                        nbuf = 32;
                     88:        }
                     89:        if (nswbuf == 0) {
                     90:                nswbuf = (nbuf / 2) &~ 1;       /* force even */
                     91:                if (nswbuf > 256)
                     92:                        nswbuf = 256;           /* sanity */
                     93:        }
                     94:        printf("real mem = %d nbuf = %d nswbuf = %d\n", ctob(maxmem),
                     95:                nbuf, nswbuf);
                     96: 
                     97:        /*
                     98:         * Allocate space for system data structures.
                     99:         */
                    100:        v = (caddr_t)(0x80000000 | (firstaddr * NBPG));
                    101: #define        valloc(name, type, num) \
                    102:            (name) = (type *)(v); (v) = (caddr_t)((name)+(num))
                    103: #define        valloclim(name, type, num, lim) \
                    104:            (name) = (type *)(v); (v) = (caddr_t)((lim) = ((name)+(num)))
                    105:        valloc(buffers, char, BUFSIZE*nbuf);
                    106:        valloc(buf, struct buf, nbuf);
                    107:        valloc(swbuf, struct buf, nswbuf);
                    108:        valloc(swsize, short, nswbuf);  /* note: nswbuf is even */
                    109:        valloc(swpf, int, nswbuf);
                    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:        valloclim(lnodes, struct kern_lnode, maxusers, lnodesMAXUSERS);
                    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: 
                    120:        /*
                    121:         * Now allocate space for core map
                    122:         */
                    123:        ncmap = (physmem*NBPG - ((int)v &~ 0x80000000)) /
                    124:                    (NBPG*CLSIZE + sizeof (struct cmap));
                    125:        valloclim(cmap, struct cmap, ncmap, ecmap);
                    126:        if ((((int)(ecmap+1))&~0x80000000) > SYSPTSIZE*NBPG)
                    127:                panic("sys pt too small");
                    128: 
                    129:        /*
                    130:         * Clear allocated space, and make r/w entries
                    131:         * for the space in the kernel map.
                    132:         */
                    133:        unixsize = btoc((int)(ecmap+1) &~ 0x80000000);
                    134:        if (unixsize >= physmem - 8*UPAGES)
                    135:                panic("no memory");
                    136:        for (i = firstaddr; i < unixsize; i++) {
                    137:                *(int *)(&Sysmap[i]) = PG_V | PG_KW | i;
                    138:                clearseg(i);
                    139:        }
                    140:        mtpr(TBIA, 1);
                    141: 
                    142:        /*
                    143:         * Initialize callouts
                    144:         */
                    145:        callfree = callout;
                    146:        for (i = 1; i < ncallout; i++)
                    147:                callout[i-1].c_next = &callout[i];
                    148: 
                    149:        /*
                    150:         * Initialize memory allocator and swap
                    151:         * and user page table maps.
                    152:         *
                    153:         * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''
                    154:         * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.
                    155:         */
                    156:        meminit(unixsize, maxmem);
                    157:        maxmem = freemem;
                    158:        printf("avail mem = %d\n", ctob(maxmem));
                    159:        rminit(kernelmap, USRPTSIZE, 1, "usrpt", nproc);
                    160: 
                    161:        /*
                    162:         * Configure the system.
                    163:         */
                    164:        configure();
                    165: 
                    166:        /*
                    167:         * Clear restart inhibit flags.
                    168:         */
                    169:        tocons(TXDB_CWSI);
                    170:        tocons(TXDB_CCSI);
                    171: }
                    172: 
                    173: /*
                    174:  * set up a physical address
                    175:  * into users virtual address space.
                    176:  */
                    177: sysphys()
                    178: {
                    179: 
                    180:        if(!suser())
                    181:                return;
                    182:        u.u_error = EINVAL;
                    183: }
                    184: 
                    185: /*
                    186:  * Initialze the clock, based on the time base which is, e.g.
                    187:  * from a filesystem.  Base provides the time to within six months,
                    188:  * and the time of year clock provides the rest.
                    189:  */
                    190: clkinit(base)
                    191:        time_t base;
                    192: {
                    193:        register unsigned todr = mfpr(TODR);
                    194:        long deltat;
                    195:        int year = YRREF;
                    196:        unsigned secyr;
                    197: 
                    198: #ifdef MVAX
                    199:        /*
                    200:         * Get the MicroVAX-II's toy register.
                    201:         * Convert it to the time format that the todr is
                    202:         * normally kept in.
                    203:         */
                    204:        if( cpu == M_VAX ) {
                    205:                todr = gettoy();
                    206:                for (;;) {
                    207:                        secyr = SECYR;
                    208:                        if (LEAPYEAR(year))
                    209:                                secyr += SECDAY;
                    210:                        if (todr < secyr)
                    211:                                break;
                    212:                        todr -= secyr;
                    213:                        year++;
                    214:                        }
                    215:                year = YRREF;
                    216:                todr = TODRZERO + todr*100;
                    217:        }
                    218: #endif MVAX
                    219:        if (base < 5*SECYR) {
                    220:                printf("WARNING: preposterous time in file system");
                    221:                time = 6*SECYR + 186*SECDAY + SECDAY/2;
                    222:                clkset();
                    223:                goto check;
                    224:        }
                    225:        /*
                    226:         * Have been told that VMS keeps time internally with base TODRZERO.
                    227:         * If this is correct, then this routine and VMS should maintain
                    228:         * the same date, and switching shouldn't be painful.
                    229:         * (Unfortunately, VMS keeps local time, so when you run UNIX
                    230:         * and VMS, VMS runs on GMT...).
                    231:         */
                    232:        if (todr < TODRZERO) {
                    233:                printf("WARNING: todr too small");
                    234:                time = base;
                    235:                /*
                    236:                 * Believe the time in the file system for lack of
                    237:                 * anything better, resetting the TODR.
                    238:                 */
                    239:                clkset();
                    240:                goto check;
                    241:        }
                    242:        /*
                    243:         * Sneak to within 6 month of the time in the filesystem,
                    244:         * by starting with the time of the year suggested by the TODR,
                    245:         * and advancing through succesive years.  Adding the number of
                    246:         * seconds in the current year takes us to the end of the current year
                    247:         * and then around into the next year to the same position.
                    248:         */
                    249:        for (time = (todr-TODRZERO)/100; time < base-SECYR/2; time += SECYR) {
                    250:                if (LEAPYEAR(year))
                    251:                        time += SECDAY;
                    252:                year++;
                    253:        }
                    254: 
                    255:        /*
                    256:         * The hardware and software clocks are now in sync, so it is
                    257:         * safe to call clkset() to get its side effect, which is to
                    258:         * initialize yearbase.
                    259:         */
                    260:        clkset();
                    261: 
                    262:        /*
                    263:         * See if we gained/lost two or more days;
                    264:         * if so, assume something is amiss.
                    265:         */
                    266:        deltat = time - base;
                    267:        if (deltat < 0)
                    268:                deltat = -deltat;
                    269:        if (deltat < 2*SECDAY)
                    270:                return;
                    271:        printf("WARNING: clock %s %d days",
                    272:            time < base ? "lost" : "gained", deltat / SECDAY);
                    273: check:
                    274:        printf(" -- CHECK AND RESET THE DATE!\n");
                    275: }
                    276: 
                    277: /* Time in seconds from the epoch to the start of the current year */
                    278: time_t yearbase;
                    279: 
                    280: /*
                    281:  * Reset the TODR based on the time value; used when the TODR
                    282:  * has a preposterous value and also when the time is reset
                    283:  * by the stime system call.  Also called when the TODR goes past
                    284:  * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
                    285:  * to wrap the TODR around.
                    286:  *
                    287:  * Side effect: yearbase is set appropriately.
                    288:  */
                    289: 
                    290: clkset()
                    291: {
                    292:        int year = YRREF;
                    293:        unsigned secyr;
                    294:        unsigned yrtime = time;
                    295: 
                    296:        yearbase = 0;
                    297: 
                    298:        /*
                    299:         * Whittle the time down to an offset in the current year,
                    300:         * by subtracting off whole years as long as possible.
                    301:         */
                    302: #ifdef MVAX
                    303:        if( cpu == M_VAX ) {
                    304:                settoy( yrtime );
                    305:                return;
                    306:        }
                    307: #endif MVAX
                    308:        for (;;) {
                    309:                secyr = SECYR;
                    310:                if (LEAPYEAR(year))
                    311:                        secyr += SECDAY;
                    312:                if (yrtime < secyr)
                    313:                        break;
                    314:                yrtime -= secyr;
                    315:                yearbase += secyr;
                    316:                year++;
                    317:        }
                    318:        mtpr(TODR, TODRZERO + yrtime*100);
                    319: }
                    320: 
                    321: #ifdef MVAX
                    322: /*
                    323:  * This routine sets the time of year clock on the MicroVAX-II.
                    324:  */
                    325: static int     dmsize[12] =
                    326:     { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
                    327: 
                    328: #define        dysize(A) (((A)%4)? 365: 366)
                    329: 
                    330: gettoy()
                    331: {
                    332:        int i, sec=0;
                    333:        struct tm tm;
                    334:        int s;
                    335:        register struct qb_regs *qb_regs = (struct qb_regs *)nexus;
                    336: 
                    337:        /*
                    338:         * Copy the toy register contents into tm so that we can
                    339:         * work with. The toy must be completely read in 2.5 millisecs.
                    340:         *
                    341:         *
                    342:         * Wait for update in progress to be done.
                    343:         */
                    344:        while( qb_regs->qb_toycsra & QBT_UIP )
                    345:                ;
                    346:        s = spl7();
                    347:        tm.tm_sec = qb_regs->qb_toysecs;
                    348:        tm.tm_min = qb_regs->qb_toymins;
                    349:        tm.tm_hour = qb_regs->qb_toyhours;
                    350:        tm.tm_mday = qb_regs->qb_toyday;
                    351:        tm.tm_mon = qb_regs->qb_toymonth;
                    352:        tm.tm_year = qb_regs->qb_toyyear;
                    353:        splx( s );
                    354:        /*
                    355:         * sanity check the clock
                    356:         */
                    357:        if( tm.tm_sec < 0 || tm.tm_sec >59  ||
                    358:                tm.tm_min < 0 || tm.tm_min > 59 ||
                    359:                tm.tm_hour < 0 || tm.tm_hour > 23  ||
                    360:                tm.tm_mday < 1 || tm.tm_mday > 31 ||
                    361:                tm.tm_mon < 1 || tm.tm_mon >12 ||
                    362:                tm.tm_year < 70 || tm.tm_year > 99 )
                    363:                        return 0;
                    364:        /*
                    365:         * Added up the seconds since the epoch
                    366:         */
                    367:        tm.tm_year += 1900;
                    368:        for (i = 1970; i < tm.tm_year; i++)
                    369:                sec += dysize(i);
                    370:        /* 
                    371:         * Leap tm.tm_year 
                    372:         */
                    373:        if (dysize(tm.tm_year) == 366 && tm.tm_mon >= 3)
                    374:                sec++;
                    375:        /*
                    376:         * Do the current tm.tm_year
                    377:         */
                    378:        for( i=0 ; i < tm.tm_mon-1 ; i++ )
                    379:                sec += dmsize[i];
                    380:        sec += tm.tm_mday-1;
                    381:        sec = 24*sec + tm.tm_hour;
                    382:        sec = 60*sec + tm.tm_min;
                    383:        sec = 60*sec + tm.tm_sec;
                    384:        return (sec);
                    385: }
                    386: 
                    387: /*
                    388:  * This routine is used to set the MicroVAX-II toy register.
                    389:  */
                    390: settoy( tim )
                    391: {
                    392:        register int d0, d1;
                    393:        long hms, day;
                    394:        register int *tp;
                    395:        struct tm xtime;
                    396:        int s;
                    397:        register struct qb_regs *qb_regs = (struct qb_regs *)nexus;
                    398: 
                    399:        /*
                    400:         * break initial number into days
                    401:         */
                    402:        hms = tim % 86400;
                    403:        day = tim / 86400;
                    404:        if (hms<0) {
                    405:                hms += 86400;
                    406:                day -= 1;
                    407:        }
                    408:        tp = (int *)&xtime;
                    409: 
                    410:        /*
                    411:         * generate hours:minutes:seconds
                    412:         */
                    413:        *tp++ = hms%60;
                    414:        d1 = hms/60;
                    415:        *tp++ = d1%60;
                    416:        d1 /= 60;
                    417:        *tp++ = d1;
                    418: 
                    419:        /*
                    420:         * year number
                    421:         */
                    422:        if (day>=0) for(d1=70; day >= dysize(d1); d1++)
                    423:                day -= dysize(d1);
                    424:        else for (d1=70; day<0; d1--)
                    425:                day += dysize(d1-1);
                    426:        xtime.tm_year = d1;
                    427:        xtime.tm_yday = d0 = day;
                    428: 
                    429:        /*
                    430:         * generate month
                    431:         */
                    432: 
                    433:        if (dysize(d1)==366)
                    434:                dmsize[1] = 29;
                    435:        for(d1=0; d0 >= dmsize[d1]; d1++)
                    436:                d0 -= dmsize[d1];
                    437:        dmsize[1] = 28;
                    438:        *tp++ = d0+1;
                    439:        *tp++ = d1+1;
                    440:        xtime.tm_isdst = 0;
                    441:        /*
                    442:         * Copy the time into the toy.
                    443:         */
                    444:        qb_regs->qb_toycsrb = QBT_SETUP;
                    445:        s = spl7();
                    446:        qb_regs->qb_toysecs = xtime.tm_sec;
                    447:        qb_regs->qb_toymins = xtime.tm_min;
                    448:        qb_regs->qb_toyhours = xtime.tm_hour;
                    449:        qb_regs->qb_toyday = xtime.tm_mday;
                    450:        qb_regs->qb_toymonth = xtime.tm_mon;
                    451:        qb_regs->qb_toyyear = xtime.tm_year;
                    452:        splx( s );
                    453:        /*
                    454:         * Start the clock again.
                    455:         */
                    456:        qb_regs->qb_toycsra = QBT_SETA;
                    457:        qb_regs->qb_toycsrb = QBT_SETB;
                    458: }
                    459: #endif MVAX
                    460: 
                    461: 
                    462: unsigned trimprof[3];
                    463: 
                    464: /*
                    465:  * Tweak the rate of the software clock
                    466:  * to track the hardware clock accurately.
                    467:  * This routine is called once a second,
                    468:  * immediately after 'time' has been incremented.
                    469:  */
                    470: clktrim()
                    471: {
                    472:        register long delta;
                    473:        register long incr;
                    474:        register unsigned todr = mfpr(TODR);
                    475: 
                    476: #ifdef MVAX
                    477:        /*
                    478:         * Get the MicroVAX-II's toy register.
                    479:         * Convert it to the time format that the todr is
                    480:         * normally kept in.
                    481:         */
                    482:        if( cpu == M_VAX ) {
                    483:                int year = YRREF;
                    484:                unsigned secyr;
                    485: 
                    486:                todr = gettoy();
                    487:                for (;;) {
                    488:                        secyr = SECYR;
                    489:                        if (LEAPYEAR(year))
                    490:                                secyr += SECDAY;
                    491:                        if (todr < secyr)
                    492:                                break;
                    493:                        todr -= secyr;
                    494:                        year++;
                    495:                        }
                    496:                todr = TODRZERO + todr*100;
                    497:        }
                    498: #endif MVAX
                    499: 
                    500:        delta = 100 * (time - yearbase) - todr + TODRZERO;
                    501: 
                    502:        /*
                    503:         * If delta > 0, the software clock is running fast.
                    504:         * It is measured in centiseconds, the units of the
                    505:         * hardware clock.  If delta is non-zero, we will
                    506:         * stretch or shrink each tick by 111 microseconds
                    507:         * from the nominal, for a drift of about 2/3 of a
                    508:         * percent.  This should result by changing delta by
                    509:         * about 2/3 each second, thus making it very unlikely
                    510:         * that we will overshoot delta == 0.  On the other
                    511:         * hand, we will be able to absorb 16 minutes of drift
                    512:         * each day.  We also count each kind of tweak.
                    513:         */
                    514:        
                    515:        incr = -16667;          /* -1/60 of a second, in microseconds */
                    516:        if (delta > 0) {
                    517:                        incr -= 111;
                    518:                        trimprof[2]++;
                    519:        } else if (delta < 0) {
                    520:                        incr += 111;
                    521:                        trimprof[0]++;
                    522:        } else {
                    523:                trimprof[1]++;
                    524:        }
                    525: 
                    526:        /* tell the hardware about it */
                    527:        /* unfortunately this does nothing on the MVAX */
                    528:        mtpr (NICR, incr);
                    529: }
                    530: 
                    531: /*
                    532:  * This system call sets the time of year clock without touching
                    533:  * the software clock.  It returns the previous clock value.  If
                    534:  * the argument is zero or the caller is not the super-user, it
                    535:  * does not change the clock.
                    536:  */
                    537: settod()
                    538: {
                    539:        register struct a {
                    540:                long unsigned tod;
                    541:        } *uap;
                    542:        register unsigned todr = mfpr(TODR);
                    543: 
                    544: #ifdef MVAX
                    545:        /*
                    546:         * Get the MicroVAX-II's toy register.
                    547:         * Convert it to the time format that the todr is
                    548:         * normally kept in.
                    549:         */
                    550:        if( cpu == M_VAX ) {
                    551:                int year = YRREF;
                    552:                unsigned secyr;
                    553: 
                    554:                todr = gettoy();
                    555:                for (;;) {
                    556:                        secyr = SECYR;
                    557:                        if (LEAPYEAR(year))
                    558:                                secyr += SECDAY;
                    559:                        if (todr < secyr)
                    560:                                break;
                    561:                        todr -= secyr;
                    562:                        year++;
                    563:                        }
                    564:                todr = TODRZERO + todr*100;
                    565:        }
                    566: #endif MVAX
                    567: 
                    568:        uap = (struct a *) u.u_ap;
                    569:        u.u_r.r_val1 = todr;
                    570: #ifdef MVAX
                    571:        if (uap->tod != 0 && suser() && cpu == M_VAX) {
                    572:                settoy(uap->tod);
                    573:                return;
                    574:        }
                    575: #endif MVAX
                    576:        if (uap->tod != 0 && suser())
                    577:                mtpr (TODR, uap->tod);
                    578: }
                    579: 
                    580: /*
                    581:  * Return the difference (in microseconds)
                    582:  * between the  current time and a previous
                    583:  * time as represented  by the arguments.
                    584:  * If there is a pending clock interrupt
                    585:  * which has not been serviced due to high
                    586:  * ipl, return error code.
                    587:  */
                    588: vmtime(otime, olbolt, oicr)
                    589:        register int otime, olbolt, oicr;
                    590: {
                    591: 
                    592:        if (mfpr(ICCS)&ICCS_INT)
                    593:                return(-1);
                    594:        else
                    595:                return(((time-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr);
                    596: }
                    597: 
                    598: /*
                    599:  * Send an interrupt to process
                    600:  *
                    601:  * SHOULD CHANGE THIS TO PASS ONE MORE WORK SO THAT ALL INFORMATION
                    602:  * PROVIDED BY HARDWARE IS AVAILABLE TO THE USER PROCESS.
                    603:  */
                    604: sendsig(p, n)
                    605:        int (*p)();
                    606: {
                    607:        register int *usp, *regs;
                    608: 
                    609:        regs = u.u_ar0;
                    610:        usp = (int *)regs[SP];
                    611:        usp -= 5;
                    612:        if ((int)usp <= USRSTACK - ctob(u.u_ssize))
                    613:                (void) grow((unsigned)usp);
                    614:        ;                       /* Avoid asm() label botch */
                    615: #ifndef lint
                    616:        asm("probew $3,$20,(r11)");
                    617:        asm("beql bad");
                    618: #else
                    619:        if (useracc((caddr_t)usp, 0x20, 1))
                    620:                goto bad;
                    621: #endif
                    622:        *usp++ = n;
                    623:        if (n == SIGILL || n == SIGFPE) {
                    624:                *usp++ = u.u_code;
                    625:                u.u_code = 0;
                    626:        } else
                    627:                *usp++ = 0;
                    628:        *usp++ = (int)p;
                    629:        *usp++ = regs[PC];
                    630:        *usp++ = regs[PS];
                    631:        regs[SP] = (int)(usp - 5);
                    632:        regs[PS] &= ~(PSL_CM|PSL_FPD);
                    633:        regs[PC] = (int)u.u_pcb.pcb_sigc;
                    634:        return;
                    635: 
                    636: asm("bad:");
                    637: bad:
                    638:        /*
                    639:         * Process has trashed its stack; give it an illegal
                    640:         * instruction to halt it in its tracks.
                    641:         */
                    642:        u.u_signal[SIGILL] = SIG_DFL;
                    643:        u.u_procp->p_siga0 &= ~(1<<(SIGILL-1));
                    644:        u.u_procp->p_siga1 &= ~(1<<(SIGILL-1));
                    645:        psignal(u.u_procp, SIGILL);
                    646: }
                    647: 
                    648: int userreg[] = {R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, AP, FP, SP, PC};
                    649: 
                    650: dorti()
                    651: {
                    652:        struct frame frame;
                    653:        register int sp;
                    654:        register int reg, mask;
                    655: 
                    656:        (void) copyin((caddr_t)u.u_ar0[FP], (caddr_t)&frame, sizeof (frame));
                    657:        sp = u.u_ar0[FP] + sizeof (frame);
                    658:        u.u_ar0[PC] = frame.fr_savpc;
                    659:        u.u_ar0[FP] = frame.fr_savfp;
                    660:        u.u_ar0[AP] = frame.fr_savap;
                    661:        mask = frame.fr_mask;
                    662:        for (reg = 0; reg <= 11; reg++) {
                    663:                if (mask&1) {
                    664:                        u.u_ar0[userreg[reg]] = fuword((caddr_t)sp);
                    665:                        sp += 4;
                    666:                }
                    667:                mask >>= 1;
                    668:        }
                    669:        sp += frame.fr_spa;
                    670:        u.u_ar0[PS] = (u.u_ar0[PS] & 0xffff0000) | frame.fr_psw;
                    671:        if (frame.fr_s)
                    672:                sp += 4 + 4 * (fuword((caddr_t)sp) & 0xff);
                    673:        /* phew, now the rei */
                    674:        u.u_ar0[PC] = fuword((caddr_t)sp);
                    675:        sp += 4;
                    676:        u.u_ar0[PS] = fuword((caddr_t)sp);
                    677:        sp += 4;
                    678:        u.u_ar0[PS] |= PSL_USERSET;
                    679:        u.u_ar0[PS] &= ~PSL_USERCLR;
                    680:        u.u_ar0[SP] = (int)sp;
                    681: }
                    682: 
                    683: /*
                    684:  * Invalidate single all pte's in a cluster
                    685:  */
                    686: tbiscl(v)
                    687:        unsigned v;
                    688: {
                    689:        register caddr_t addr;          /* must be first reg var */
                    690:        register int i;
                    691: 
                    692:        asm(".set TBIS,58");
                    693:        addr = ptob(v);
                    694:        for (i = 0; i < CLSIZE; i++) {
                    695: #ifdef lint
                    696:                mtpr(TBIS, addr);
                    697: #else
                    698:                asm("mtpr r11,$TBIS");
                    699: #endif
                    700:                addr += NBPG;
                    701:        }
                    702: }
                    703:   
                    704: int    waittime = -1;
                    705: 
                    706: boot(arghowto)
                    707:        int arghowto;
                    708: {
                    709:        register int howto;             /* r11 == how to boot */
                    710:        register int devtype;           /* r10 == major of root dev */
                    711: 
                    712:        howto = arghowto;
                    713:        if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) {
                    714:                waittime = 0;
                    715:                update();
                    716:                printf("syncing disks... ");
                    717:                while (++waittime <= 5)
                    718:                        sleep((caddr_t)&lbolt, PZERO);
                    719:                printf("done\n");
                    720:        }
                    721:        splx(0x1f);                     /* extreme priority */
                    722:        devtype = major(rootdev);
                    723:        if (howto&RB_HALT) {
                    724: #ifdef MVAX
                    725:                if( cpu == M_VAX ) {
                    726:                        ((struct qb_regs *)nexus)->qb_cpmbx = RB_HALTMD;
                    727:                        for (;;)
                    728:                                asm ("halt");
                    729:                }
                    730: #endif MVAX
                    731:                printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n");
                    732:                mtpr(IPL, 0x1f);
                    733:                for (;;)
                    734:                        ;
                    735:        } else {
                    736:                if ((howto & RB_PANIC) != 0)
                    737:                        doadump();
                    738:                tocons(TXDB_BOOT);
                    739:        }
                    740: #if defined(VAX750) || defined(VAX7ZZ) || defined(MVAX)
                    741:        if (cpu != VAX_780)
                    742:                { asm("movl r11,r5"); }         /* boot flags go in r5 */
                    743: #endif
                    744: #ifdef MVAX
                    745:        if( cpu == M_VAX ) 
                    746:                ((struct qb_regs *)nexus)->qb_cpmbx = RB_REBOOT;
                    747: #endif
                    748:        for (;;)
                    749:                asm("halt");
                    750:        /*NOTREACHED*/
                    751: }
                    752: 
                    753: tocons(c)
                    754: {
                    755: 
                    756:        while ((mfpr(TXCS)&TXCS_RDY) == 0)
                    757:                continue;
                    758:        mtpr(TXDB, c);
                    759: }
                    760: 
                    761: /*
                    762:  * Doadump comes here after turning off memory management and
                    763:  * getting on the dump stack, either when called above, or by
                    764:  * the auto-restart code.
                    765:  */
                    766: dumpsys()
                    767: {
                    768:        int dstat;
                    769:        rpb.rp_flag = 1;
                    770:        if ((minor(dumpdev)&07) != 1)
                    771:                return;
                    772:        printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
                    773:        printf("dump ");
                    774:        switch (dstat = (*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
                    775: 
                    776:        case ENXIO:
                    777:                printf("device bad\n");
                    778:                break;
                    779: 
                    780:        case EFAULT:
                    781:                printf("device not ready\n");
                    782:                break;
                    783: 
                    784:        case EINVAL:
                    785:                printf("area improper\n");
                    786:                break;
                    787: 
                    788:        case EIO:
                    789:                printf("i/o error\n");
                    790:                break;
                    791: 
                    792:        default:
                    793:                printf("unexpected error %d\n", dstat);
                    794:                break;
                    795: 
                    796:        case 0:
                    797:                printf("succeeded\n");
                    798:                break;
                    799:        }
                    800: }

unix.superglobalmegacorp.com

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