Annotation of researchv9/sys.vax/sys/machdep.c, revision 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.