Annotation of researchv10dc/sys/md/machdep.c, revision 1.1.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.