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