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

1.1     ! root        1: /*
        !             2:  * machine-specific hardware routines,
        !             3:  * these for MicroVAX II
        !             4:  */
        !             5: 
        !             6: #include "sys/param.h"
        !             7: #include "sys/pte.h"
        !             8: #include "sys/mtpr.h"
        !             9: #include "sys/vm.h"
        !            10: #include "sys/qbio.h"
        !            11: #include "sys/clock.h"
        !            12: 
        !            13: #define        IORESET 0x37            /* reset all IO connections */
        !            14: #define        PARENB  01              /* mser: enable parity error traps */
        !            15: 
        !            16: /*
        !            17:  * bits in console mailbox
        !            18:  */
        !            19: 
        !            20: #define        HALTACT 03      /* halt action */
        !            21: #define        HMRBOOT 0       /* halt: restart, then boot (if halts disabled!) */
        !            22: #define        HMRST   01      /* halt: restart regardless (but never boot) */
        !            23: #define        HMBOOT  02      /* halt: boot */
        !            24: #define        BOOTIH  04      /* boot inhibit */
        !            25: #define        RSTIH   010     /* restart inhibit */
        !            26: 
        !            27: char *iospace;
        !            28: int delayfact = 1;             /* factor for DELAY macro */
        !            29: 
        !            30: /*
        !            31:  * adjust physical top of memory to useful top of memory:
        !            32:  * preserve space for console program (1024 bytes)
        !            33:  * and memory bitmap (one bit per 512-byte page; why do we save it?)
        !            34:  */
        !            35: machmem(hi)
        !            36: int hi;
        !            37: {
        !            38:        return(hi - (hi/(NBPG*NBBY)) - 1024);
        !            39: }
        !            40: 
        !            41: /*
        !            42:  * miscellaneous machine-dependent initialization
        !            43:  * called just after mapping turned on
        !            44:  *
        !            45:  * - make instruction emulation code accessible from user space
        !            46:  * - reset and enable IO
        !            47:  */
        !            48: machinit()
        !            49: {
        !            50:        register int *p;                /* pun; really struct pte */
        !            51:        register char *e;
        !            52:        register struct iomflow *q;
        !            53:        extern char _emulbeg, _emulend;
        !            54: 
        !            55:        e = &_emulbeg;
        !            56:        p = (int *)&Sysmap[btop((int)e & ~KSTART)];
        !            57:        do {
        !            58:                *p = (*p &~ PG_PROT) | PG_URKR;
        !            59:                p++;
        !            60:                e += NBPG;
        !            61:        } while (e < &_emulend);
        !            62:        mtpr(IORESET, 0);
        !            63:        q = (struct iomflow *)iospace;
        !            64:        q->c.mser = q->c.mser | PARENB;         /* clear stale error bits */
        !            65: }
        !            66: 
        !            67: /*
        !            68:  * stray interrupt handling:
        !            69:  * just decrypt it and return
        !            70:  */
        !            71: strayintr(v)
        !            72: int v;
        !            73: {
        !            74:        if (v < 0x200)
        !            75:                printf("stray interrupt at 0x%x\n", v);
        !            76:        else
        !            77:                printf("stray Q-bus interrupt at 0%o\n", v-0x200);
        !            78: }
        !            79: 
        !            80: /*
        !            81:  * how big is io space?
        !            82:  */
        !            83: 
        !            84: mchiopsize()
        !            85: {
        !            86:        return (sizeof(struct iomflow));
        !            87: }
        !            88: 
        !            89: /*
        !            90:  * set up the page tables for iospace
        !            91:  * called while the system page table is being assembled;
        !            92:  * memory mapping is off
        !            93:  * pt is the first page table of an area
        !            94:  * mapping what mchiopsize returned
        !            95:  */
        !            96: 
        !            97: mchiopinit(pt)
        !            98: struct pte *pt;
        !            99: {
        !           100:        register long *p;       /* pun, for efficiency */
        !           101:        register long b;
        !           102:        register int i;
        !           103: 
        !           104:        p = (long *)pt;
        !           105:        *p++ = PG_V|PG_KW|btop(0x20080000);     /* cpu regs */
        !           106:        *p++ = PG_V|PG_KW|btop(0x200b8000);     /* watch chip regs */
        !           107:        b = btop(0x20088000);                   /* Q-bus map */
        !           108:        for (i = 0; i < (8192*sizeof(long))/NBPG; i++)
        !           109:                *p++ = PG_V|PG_KW|b++;
        !           110:        b = btop(0x20000000);                   /* Q-bus io regs */
        !           111:        for (i = 0; i < 8192/NBPG; i++)
        !           112:                *p++ = PG_V|PG_KW|b++;
        !           113: }
        !           114: 
        !           115: /*
        !           116:  * return the IO regs for a Q-bus adapter
        !           117:  * (there's really only one, but only this code knows that)
        !           118:  */
        !           119: 
        !           120: caddr_t
        !           121: qbaaddr(u)
        !           122: int u;
        !           123: {
        !           124:        if (u != 0)
        !           125:                return (0);
        !           126:        return ((caddr_t)&((struct iomflow *)iospace)->u[u]);
        !           127: }
        !           128: 
        !           129: /*
        !           130:  * arrange for a restart on halt
        !           131:  * -- it would be slightly preferable
        !           132:  * to fall back to a boot if the restart fails;
        !           133:  * alas, to do that on MicroVAX II,
        !           134:  * you must disable console halts
        !           135:  */
        !           136: 
        !           137: setrestart()
        !           138: {
        !           139:        register short *p;
        !           140: 
        !           141:        p = &((struct iomflow *)iospace)->w.cpmbx;
        !           142:        *p &=~ (BOOTIH|RSTIH|HALTACT);
        !           143:        *p |= HMRST;            /* always just restart */
        !           144: }
        !           145: 
        !           146: /*
        !           147:  * arrange for a boot, now or on next halt
        !           148:  * -- sometimes called with mapping disabled
        !           149:  */
        !           150: 
        !           151: setboot()
        !           152: {
        !           153:        register short *p;
        !           154: 
        !           155:        if (mfpr(MAPEN))
        !           156:                p = &((struct iomflow *)iospace)->w.cpmbx;
        !           157:        else
        !           158:                p = (short *)0x200b801c;
        !           159:        *p &=~ (BOOTIH|HALTACT);
        !           160:        *p |= HMBOOT;           /* halt mode `boot' */
        !           161: }
        !           162: 
        !           163: /*
        !           164:  * time-of-year clock:
        !           165:  * in MicroVAX, it's a watch chip
        !           166:  * just use it as a counter with funny digits
        !           167:  */
        !           168: 
        !           169: #define        BYEAR   82      /* arbitrary non-leap-year base */
        !           170: #define        TODRRES 100     /* TODR units per second */
        !           171: 
        !           172: #define        UIP     0200    /* csra - update in progress */
        !           173: #define        AMAG    040     /* csra - magic clock modes */
        !           174: #define        SET     0200    /* csrb - set clock */
        !           175: #define        DM      04      /* csrb - binary (not bcd) */
        !           176: #define        M24     02      /* csrb - 24-hour mode */
        !           177: #define        VRT     0200    /* csrd - valid clock */
        !           178: 
        !           179: #define        BOFF    (SET|DM|M24)    /* stop clock and ready for setting */
        !           180: #define        BON     (DM|M24)        /* let clock go again */
        !           181: 
        !           182: static char dmsize[] = {
        !           183:        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
        !           184:        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
        !           185: };
        !           186: 
        !           187: struct ty {    /* just for convenience */
        !           188:        char sec, min, hr, day, mon, yr;
        !           189: };
        !           190: 
        !           191: gettodr()
        !           192: {
        !           193:        register int s, i;
        !           194:        register struct watchregs *regs;
        !           195:        struct ty ty;
        !           196: 
        !           197:        regs = &((struct iomflow *)iospace)->w;
        !           198:        while(regs->csra & UIP)
        !           199:                ;
        !           200:        /*
        !           201:         * we now have 244us to read the clock
        !           202:         */
        !           203:        if ((regs->csrd & VRT) == 0) {  /* invalid time */
        !           204:                regs->csrb = BOFF;
        !           205:                regs->csra = AMAG;
        !           206:                regs->yr = 0;           /* just make it wrong */
        !           207:                regs->csrb = BON;
        !           208:                return (0);             /* and return a wrong answer */
        !           209:        }
        !           210:        s = spl7();
        !           211:        ty.sec = regs->sec;
        !           212:        ty.min = regs->min;
        !           213:        ty.hr = regs->hr;
        !           214:        ty.day = regs->day;
        !           215:        ty.mon = regs->mon;
        !           216:        ty.yr = regs->yr;
        !           217:        splx(s);
        !           218:        if (ty.sec < 0 || ty.sec > 59
        !           219:        ||  ty.min < 0 || ty.min > 59
        !           220:        ||  ty.hr < 0 || ty.hr > 23
        !           221:        ||  ty.day < 1 || ty.day > 31
        !           222:        ||  ty.mon < 1 || ty.mon > 12
        !           223:        ||  ty.yr < BYEAR || ty.yr > BYEAR+1)
        !           224:                return 0;
        !           225:        if (ty.yr > BYEAR)
        !           226:                ty.mon += 12;   /* overflow */
        !           227:        s = 0;
        !           228:        for(i = 0; i < ty.mon-1; i++)
        !           229:                s += dmsize[i];
        !           230:        s += ty.day-1;
        !           231:        s = 24*s + ty.hr;
        !           232:        s = 60*s + ty.min;
        !           233:        s = 60*s + ty.sec;
        !           234:        return (s*TODRRES+TODRZERO);
        !           235: }
        !           236: 
        !           237: /*
        !           238:  * This routine is used to set the MicroVAX-II toy register.
        !           239:  */
        !           240: settodr(tim)
        !           241: {
        !           242:        register int yd;
        !           243:        register struct watchregs *regs;
        !           244:        struct ty ty;
        !           245: 
        !           246:        regs = &((struct iomflow *)iospace)->w;
        !           247:        tim = (tim - TODRZERO)/TODRRES;         /* truncated -- too bad */
        !           248:        ty.sec = tim % 60;
        !           249:        tim /= 60;
        !           250:        ty.min = tim % 60;
        !           251:        tim /= 60;
        !           252:        ty.hr = tim % 24;
        !           253:        tim /= 24;
        !           254:        yd = tim % 365;
        !           255:        tim /= 365;
        !           256:        ty.yr = BYEAR + tim;
        !           257:        for (ty.mon = 0; yd > dmsize[ty.mon]; ty.mon++)
        !           258:                yd -= dmsize[ty.mon];
        !           259:        ty.day = yd;
        !           260:        regs->csrb = BOFF;
        !           261:        regs->csra = AMAG;
        !           262:        regs->sec = ty.sec;
        !           263:        regs->min = ty.min;
        !           264:        regs->hr = ty.hr;
        !           265:        regs->day = ty.day+1;
        !           266:        regs->mon = ty.mon+1;
        !           267:        regs->yr = ty.yr;
        !           268:        regs->csrb = BON;
        !           269: }

unix.superglobalmegacorp.com

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