Annotation of researchv10dc/sys/md/machdep.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * machine-dependent init stuff;
        !             3:  * specific to VAX but general to all models
        !             4:  */
        !             5: 
        !             6: #include "sys/param.h"
        !             7: #include "sys/systm.h"
        !             8: #include "sys/user.h"
        !             9: #include "sys/proc.h"
        !            10: #include "sys/map.h"
        !            11: #include "sys/reg.h"
        !            12: #include "sys/mtpr.h"
        !            13: #include "sys/clock.h"
        !            14: #include "sys/pte.h"
        !            15: #include "sys/vm.h"
        !            16: #include "sys/psl.h"
        !            17: #include "sys/buf.h"
        !            18: #include "sys/reboot.h"
        !            19: #include "sys/conf.h"
        !            20: #include "sys/text.h"
        !            21: #include "sys/cmap.h"
        !            22: #include "sys/msgbuf.h"
        !            23: 
        !            24: /*
        !            25:  * table of little bits of page table needed
        !            26:  * by various bits of code
        !            27:  * the right way to do this would be
        !            28:  * to have a pool, and hand space out dynamically
        !            29:  */
        !            30: 
        !            31: extern char *CADDR1, *CADDR2, *CADDR3;
        !            32: extern struct pte *CMAP1, *CMAP2, *CMAP3, *mmap;
        !            33: extern char *vmmap;
        !            34: extern char *priobuf;
        !            35: extern struct pte *Prbufmap;
        !            36: 
        !            37: struct {
        !            38:        int npages;
        !            39:        struct pte **pmap;
        !            40:        caddr_t *pmem;
        !            41: } mmlist[] = {
        !            42:        UPAGES, &Swapmap, (caddr_t *)&swaputl,
        !            43:        UPAGES, &Forkmap, (caddr_t *)&forkutl,
        !            44:        UPAGES, &Xswapmap, (caddr_t *)&xswaputl,
        !            45:        UPAGES, &Xswap2map, (caddr_t *)&xswap2utl,
        !            46:        UPAGES, &Pushmap, (caddr_t *)&pushutl,
        !            47:        UPAGES, &Prusrmap, (caddr_t *)&prusrutl,
        !            48:        CLSIZE, &Prbufmap, (caddr_t *)&priobuf,
        !            49:        CLSIZE, &msgbufmap, (caddr_t *)&msgbuf,
        !            50:        USRPTSIZE, &Usrptmap, (caddr_t *)&usrpt,
        !            51:        1,      &CMAP1, (caddr_t *)&CADDR1,
        !            52:        1,      &CMAP2, (caddr_t *)&CADDR2,
        !            53:        1,      &CMAP3, (caddr_t *)&CADDR3,
        !            54:        1,      &mmap, (caddr_t *)&vmmap,
        !            55:        -1
        !            56: };
        !            57: 
        !            58: struct pte *physspt;
        !            59: struct pte *Sysmap;
        !            60: struct pte *Usrptmap;
        !            61: struct pte *usrpt;
        !            62: 
        !            63: /*
        !            64:  * init the memory map
        !            65:  * called early on, well before main
        !            66:  * memory management is off
        !            67:  *
        !            68:  * the system page table is allocated here, out of free memory
        !            69:  * the theory is:
        !            70:  *     map the static kernel first
        !            71:  *     then any pseudo-dynamic data structures
        !            72:  *     then the buffers
        !            73:  *     then lay down the system page table
        !            74:  *     then map io space
        !            75:  *
        !            76:  * subtlety: we generally want end and etext to be physical addresses.
        !            77:  * (long)&end & ~KSTART seems to be the only expression that is constant
        !            78:  * with and without the c optimizer.
        !            79:  */
        !            80: 
        !            81: mmapinit(hiaddr)
        !            82: long hiaddr;
        !            83: {
        !            84:        extern int end, etext;
        !            85:        extern char *iospace;
        !            86:        register int i;
        !            87:        register long *p;       /* pun; really struct pte * */
        !            88:        register long mtop;     /* highest real memory address used */
        !            89:        register long ptop;     /* highest virtual address used */
        !            90:        register long v;
        !            91: 
        !            92:        maxmem = physmem = btoc(hiaddr);
        !            93:        mtop = (long)&end & ~KSTART;
        !            94:        /*
        !            95:         * dynamic things: add to memtop, set addrs along the way
        !            96:         */
        !            97:        if (nbuf == 0) {
        !            98:                nbuf = 32 * physmem / btoc(1024*1024);
        !            99:                if (nbuf < 32)
        !           100:                        nbuf = 32;
        !           101:        }
        !           102:        buf = (struct buf *)(KSTART+mtop);
        !           103:        mtop += nbuf * sizeof(struct buf);
        !           104:        mtop = (mtop + NBPG - 1) & ~PGOFSET;
        !           105:        buffers = (char *)(KSTART+mtop);
        !           106:        mtop += nbuf * BUFSIZE;
        !           107:        /*
        !           108:         * cmaps; we'll slightly overestimate; too bad
        !           109:         */
        !           110:        cmap = (struct cmap *)(KSTART+mtop);
        !           111:        ncmap = (physmem * NBPG - mtop)/(CLSIZE*NBPG + sizeof(struct cmap));
        !           112:        mtop += ncmap * sizeof(struct cmap);
        !           113:        ecmap = (struct cmap *)(KSTART+mtop);
        !           114:        /*
        !           115:         * clear all the memory we just handed out
        !           116:         */
        !           117:        p = (long *)((long)&end & ~KSTART);
        !           118:        while (p < (long *)mtop)
        !           119:                *p++ = 0;
        !           120:        /*
        !           121:         * now the things that aren't memory
        !           122:         * maps are relative to beginning of spt
        !           123:         */
        !           124:        mtop = (mtop + NBPG - 1) & ~PGOFSET;
        !           125:        ptop = mtop;
        !           126:        for (i = 0; mmlist[i].npages >= 0; i++) {
        !           127:                *mmlist[i].pmem = (caddr_t)(ptop + KSTART);
        !           128:                *mmlist[i].pmap = (struct pte *)(btoc(ptop) * sizeof(struct pte));
        !           129:                ptop += ctob(mmlist[i].npages);
        !           130:        }
        !           131:        iospace = (char *)(ptop + KSTART);
        !           132:        ptop += mchiopsize();
        !           133:        Sysmap = (struct pte *)(ptop + KSTART);
        !           134:        physspt = (struct pte *)mtop;
        !           135:        p = (long *)mtop;
        !           136:        i = (int)&etext & ~KSTART;      /* not - KSTART; optimizer gets it wrong */
        !           137:        for (v = 0; v < mtop; v += NBPG)        /* kernel text + data */
        !           138:                if (v < i)
        !           139:                        *p++ = PG_V|PG_KR|btoc(v);
        !           140:                else
        !           141:                        *p++ = PG_V|PG_KW|btoc(v);
        !           142:        for (; v < ptop; v += NBPG)             /* mystery maps */
        !           143:                *p++ = 0;
        !           144:        ptop += (btoc(ptop) + btoc(btoc(ptop)*sizeof(struct pte)))*sizeof(struct pte);
        !           145:        for (i = btoc(mtop); v < ptop; v += NBPG, i++)          /* spt */
        !           146:                *p++ = PG_V|PG_KW|i;
        !           147:        firstfree = i + 1;
        !           148:        /*
        !           149:         * fix the random maps
        !           150:         */
        !           151:        for (i = 0; mmlist[i].npages >= 0; i++)
        !           152:                *(long *)mmlist[i].pmap += (long)Sysmap;
        !           153:        mchiopinit(physspt + btoc(iospace - KSTART));
        !           154:        p = (long *)(physspt + (msgbufmap - Sysmap));
        !           155:        for (i = 0; i < btoc(sizeof(struct msgbuf)); i++)
        !           156:                *p++ = PG_V|PG_KW|(physmem - btoc(sizeof(struct msgbuf)) + i);
        !           157:        maxmem -= CLSIZE;
        !           158:        mtpr(SBR, mtop);
        !           159:        mtpr(SLR, btoc(ptop));
        !           160: }
        !           161: 
        !           162: /*
        !           163:  * set up context for process 0:
        !           164:  * first page of free memory becomes page table
        !           165:  * next UPAGES become user block
        !           166:  * init the process control block slightly
        !           167:  * called before memory mapping is turned on
        !           168:  */
        !           169: 
        !           170: uctinit(kpc)
        !           171: long kpc;
        !           172: {
        !           173:        register long *p;       /* pun: struct pte * */
        !           174:        register int i;
        !           175:        register struct pcb *pp;
        !           176: 
        !           177:        p = (long *)ctob(firstfree);
        !           178:        for (i = 0; i < (UPAGES+1)*NBPG; i += sizeof(long))
        !           179:                *p++ = 0;
        !           180:        p = (long *)(physspt + ((long)usrpt-KSTART)/NBPG);
        !           181:        *p = PG_V|PG_KW|firstfree;      /* one page for first p0 page table */
        !           182:        p = (long *)ctob(firstfree+1);
        !           183:        for (i = UPAGES; i > 0; --i)
        !           184:                *--p = PG_V|PG_URKW|firstfree+i;
        !           185:        pp = (struct pcb *)ctob(firstfree+1);
        !           186:        pp->pcb_p0br = usrpt;
        !           187:        pp->pcb_p0lr = 0 + AST_NONE;    /* no p0 space mapped */
        !           188:        pp->pcb_p1br = usrpt + NPTEPG - P1TOP;
        !           189:        pp->pcb_p1lr = P1TOP - UPAGES;
        !           190:        pp->pcb_ksp = KSTART;
        !           191:        pp->pcb_esp = pp->pcb_ssp = -1;         /* something invalid */
        !           192:        pp->pcb_usp = USRSTACK;
        !           193:        pp->pcb_psl = 0;                /* mode (kernel,kernel), ipl 0 */
        !           194:        pp->pcb_pc = kpc;
        !           195:        firstfree += UPAGES + 1;
        !           196:        mtpr(PCBB, pp);
        !           197: }
        !           198: 
        !           199: /*
        !           200:  * Machine-dependent startup code
        !           201:  * some of this is excessively specific to the paging code
        !           202:  */
        !           203: 
        !           204: int dmmin, dmmax, dmtext;
        !           205: 
        !           206: startup()
        !           207: {
        !           208:        register long maxsz;
        !           209:        register unsigned i;
        !           210:        register struct proc *p;
        !           211:        extern struct map kernelmap[];
        !           212:        extern int kernelcnt;
        !           213:        extern char version[];
        !           214: 
        !           215:        setrestart();
        !           216:        printf("%s\n", version);
        !           217:        meminit(firstfree, maxmem);
        !           218:        maxmem = freemem;
        !           219:        printf("mem = %d\n", ctob(maxmem));
        !           220:        rminit(kernelmap, kernelcnt, USRPTSIZE-1, 1);
        !           221:        /*
        !           222:         * dmmin fixed for now
        !           223:         * dmmax == first power of 2 larger than max?size/(NDMAP-1)
        !           224:         */
        !           225:        dmmin = DMMIN;
        !           226:        maxsz = maxtsize / NXDAD;
        !           227:        for (i = 0x80000000; i; i >>= 1)
        !           228:                if (maxsz & i)
        !           229:                        break;
        !           230:        i *= 2;
        !           231:        if (i < dmmin)
        !           232:                i = dmmin;
        !           233:        dmtext = i;
        !           234:        maxsz = maxdsize > maxssize ? maxdsize : maxssize;
        !           235:        maxsz /= NDMAP-1;
        !           236:        if (maxsz < dmtext)
        !           237:                maxsz = dmtext;
        !           238:        for (i = 0x80000000; i; i >>= 1)
        !           239:                if (maxsz & i)
        !           240:                        break;
        !           241:        i *= 2;
        !           242:        if (i < dmmin)
        !           243:                i = dmmin;
        !           244:        dmmax = i;
        !           245:        maxpgio *= nswdevt;
        !           246:        /*
        !           247:         * set up vm aspects of first process
        !           248:         */
        !           249:        p = &proc[0];
        !           250:        p->p_p0br = (struct pte *)mfpr(P0BR);
        !           251:        p->p_szpt = 1;
        !           252:        p->p_addr = uaddr(p);
        !           253:        setredzone(p->p_addr, (caddr_t)&u);
        !           254:        u.u_pcb.pcb_szpt = CLSIZE;
        !           255: }
        !           256: 
        !           257: /*
        !           258:  * init unix time
        !           259:  * base is some nearly correct number, e.g. from a filesystem.
        !           260:  * try to get something better from the VAX time-of-year clock,
        !           261:  * which contains the number of .01-second clicks in the current year
        !           262:  */
        !           263: clkinit(base)
        !           264:        time_t base;
        !           265: {
        !           266:        register unsigned long todr;
        !           267:        int year = YRREF;
        !           268: 
        !           269:        todr = gettodr();
        !           270:        if (todr < TODRZERO) {  /* too small; TODR was restarted */
        !           271:                time = base;
        !           272:                clkset();       /* so fix it */
        !           273:        }
        !           274:        else {
        !           275:                for (time = (todr-TODRZERO)/100; time < base-SECYR/2; time += SECYR) {
        !           276:                        if (LEAPYEAR(year))
        !           277:                                time += SECDAY;
        !           278:                        year++;
        !           279:                }
        !           280:        }
        !           281: }
        !           282: 
        !           283: /*
        !           284:  * once a day or so, set TOY clock to match system clock
        !           285:  */
        !           286: 
        !           287: static time_t clknext;
        !           288: 
        !           289: clkcheck()
        !           290: {
        !           291: 
        !           292:        if (clknext == 0)
        !           293:                clknext = time + SECDAY;
        !           294:        if (clknext > time)
        !           295:                return;
        !           296:        clknext = time + SECDAY;
        !           297:        clkset();
        !           298: }
        !           299: 
        !           300: /*
        !           301:  * reset the TOY clock to match current unix time
        !           302:  */
        !           303: 
        !           304: clkset()
        !           305: {
        !           306:        int year = YRREF;
        !           307:        unsigned secyr;
        !           308:        unsigned yrtime = time;
        !           309: 
        !           310:        for (;;) {
        !           311:                secyr = SECYR;
        !           312:                if (LEAPYEAR(year))
        !           313:                        secyr += SECDAY;
        !           314:                if (yrtime < secyr)
        !           315:                        break;
        !           316:                yrtime -= secyr;
        !           317:                year++;
        !           318:        }
        !           319:        settodr(TODRZERO + yrtime*100);
        !           320: }
        !           321: 
        !           322: /*
        !           323:  * bias the clock to correct an error of `wrong' milliseconds
        !           324:  * -- just tick slightly slowly or quickly for a while
        !           325:  * MicroVAX has no NICR, but writing it is a no-op;
        !           326:  * let the clock interrupt code do the work
        !           327:  */
        !           328: 
        !           329: int clockbias;         /* number of ticks */
        !           330: char clocksign;                /* direction to correct */
        !           331: 
        !           332: biasclock()
        !           333: {
        !           334:        register struct a {
        !           335:                int wrong;
        !           336:        } *uap;
        !           337:        register long nticks;
        !           338: 
        !           339:        uap = (struct a *)u.u_ap;
        !           340:        if (!suser())
        !           341:                return;
        !           342:        nticks = (long)uap->wrong * 1000;       /* microseconds */
        !           343:        nticks /= CLKBIAS;                      /* number of ticks to bias */
        !           344:        spl7();
        !           345:        if (nticks < 0) {
        !           346:                mtpr(NICR, CLK60HZ-CLKBIAS);
        !           347:                clockbias = -nticks;
        !           348:                clocksign = -1;         /* -1 => clock must run slower */
        !           349:        }
        !           350:        else {
        !           351:                mtpr(NICR, CLK60HZ+CLKBIAS);
        !           352:                clockbias = nticks;
        !           353:                clocksign = 1;
        !           354:        }
        !           355:        spl0();
        !           356: }
        !           357: 
        !           358: /*
        !           359:  * Return the difference (in microseconds)
        !           360:  * between the  current time and a previous
        !           361:  * time as represented  by the arguments.
        !           362:  * If there is a pending clock interrupt
        !           363:  * which has not been serviced due to high
        !           364:  * ipl, return error code.
        !           365:  */
        !           366: vmtime(otime, olbolt, oicr)
        !           367:        register int otime, olbolt, oicr;
        !           368: {
        !           369: 
        !           370:        if (mfpr(ICCS)&ICCS_INT)
        !           371:                return(-1);
        !           372:        else
        !           373:                return(((time-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr);
        !           374: }
        !           375: 
        !           376: /*
        !           377:  * Send an interrupt to process
        !           378:  *
        !           379:  * SHOULD CHANGE THIS TO PASS ONE MORE WORK SO THAT ALL INFORMATION
        !           380:  * PROVIDED BY HARDWARE IS AVAILABLE TO THE USER PROCESS.
        !           381:  */
        !           382: sendsig(p, n)
        !           383:        int (*p)();
        !           384: {
        !           385:        register int *usp, *regs;
        !           386: 
        !           387:        regs = u.u_ar0;
        !           388:        usp = (int *)regs[SP];
        !           389:        usp -= 5;
        !           390:        if ((int)usp <= USRSTACK - ctob(u.u_ssize))
        !           391:                (void) grow((unsigned)usp);
        !           392:        if (useracc((caddr_t)usp, 5*sizeof(int), B_WRITE) == 0)
        !           393:                goto bad;
        !           394:        *usp++ = n;
        !           395:        if (n == SIGILL || n == SIGFPE) {
        !           396:                *usp++ = u.u_code;
        !           397:                u.u_code = 0;
        !           398:        } else
        !           399:                *usp++ = 0;
        !           400:        *usp++ = (int)p;
        !           401:        *usp++ = regs[PC];
        !           402:        *usp++ = regs[PS];
        !           403:        regs[SP] = (int)(usp - 5);
        !           404:        regs[PS] &= ~(PSL_CM|PSL_FPD);
        !           405:        regs[PC] = (int)u.u_pcb.pcb_sigc;
        !           406:        return;
        !           407: 
        !           408: bad:
        !           409:        /*
        !           410:         * Process has trashed its stack; give it an illegal
        !           411:         * instruction to halt it in its tracks.
        !           412:         */
        !           413:        u.u_signal[SIGILL] = SIG_DFL;
        !           414:        P_SETDFL(u.u_procp, SIGMASK(SIGILL));
        !           415:        psignal(u.u_procp, SIGILL);
        !           416: }
        !           417: 
        !           418: /*
        !           419:  * Invalidate single all pte's in a cluster
        !           420:  */
        !           421: tbiscl(v)
        !           422:        unsigned v;
        !           423: {
        !           424:        register caddr_t addr;
        !           425:        register int i;
        !           426: 
        !           427:        addr = ptob(v);
        !           428:        for (i = 0; i < CLSIZE; i++) {
        !           429:                mtpr(TBIS, addr);
        !           430:                addr += NBPG;
        !           431:        }
        !           432: }
        !           433: 
        !           434: /*
        !           435:  * sys reboot
        !           436:  * can this please go away?
        !           437:  */
        !           438: 
        !           439: boot(howto)
        !           440:        int howto;
        !           441: {
        !           442: 
        !           443:        if (howto&RB_HALT)
        !           444:                death();
        !           445:        reboot(1);
        !           446: }
        !           447: 
        !           448: /*
        !           449:  * freeze.  can't just halt because
        !           450:  * on some machines that would cause a boot
        !           451:  */
        !           452: 
        !           453: death()
        !           454: {
        !           455:        splx(0x1f);
        !           456:        printf("death\n");
        !           457:        for (;;)
        !           458:                ;
        !           459: }

unix.superglobalmegacorp.com

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