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

1.1     ! root        1: /*
        !             2:  * stuff for dealing with bi nodes (io nexus) on nautilus
        !             3:  *
        !             4:  * iospace is an array of struct nexus (registers + window space),
        !             5:  * followed by three pages of special registers:
        !             6:  * NBIA0, NBIA1, and the memory controller
        !             7:  */
        !             8: 
        !             9: #include "sys/param.h"
        !            10: #include "sys/nexus.h"
        !            11: #include "sys/biaddr.h"
        !            12: #include "sys/biic.h"
        !            13: #include "sys/pte.h"
        !            14: 
        !            15: static int nexcnt;
        !            16: char *iospace;                 /* array of struct nexus, plus some stuff */
        !            17: struct nbia {
        !            18:        long    csr0;
        !            19:        long    csr1;
        !            20: };
        !            21: static struct nbia *nbia[2];
        !            22: long *mcrcsr;
        !            23: 
        !            24: static int nexreg(), nexwind(), biainit(), bibinit(), nbiavec();
        !            25: 
        !            26: /*
        !            27:  * how much address space
        !            28:  * is needed for nexus space?
        !            29:  * needed when allocating system page table
        !            30:  * the fudge factor of 3: 2 pages for NBIAs, one for the memory controller
        !            31:  */
        !            32: 
        !            33: mchiopsize()
        !            34: {
        !            35:        register int i;
        !            36: 
        !            37:        for (i = 0; nextab[i].bus >= 0; i++)
        !            38:                ;
        !            39:        nexcnt = i;
        !            40:        return (i * sizeof(struct nexus) + 3 * NBPG);
        !            41: }
        !            42: 
        !            43: /*
        !            44:  * map appropriate parts of nexus space into kernel space
        !            45:  * called early on, before memory mapping is set up
        !            46:  * argument is the first relevant spt entry
        !            47:  */
        !            48: 
        !            49: mchiopinit(pt)
        !            50: struct pte *pt;
        !            51: {
        !            52:        register long *p;
        !            53:        register int i, n;
        !            54:        register int b;
        !            55: 
        !            56:        p = (long *)pt;
        !            57:        for (i = 0; i < nexcnt; i++) {
        !            58:                b = nexreg(&nextab[i]);
        !            59:                for (n = 0; n < btoc(NXSIZE); n++)
        !            60:                        if (b)
        !            61:                                *p++ = PG_V|PG_KW|(b+n);
        !            62:                        else
        !            63:                                *p++ = 0;
        !            64:                b = nexwind(&nextab[i], 0);
        !            65:                for (n = 0; n < btoc(NXWSIZE); n++)
        !            66:                        if (b)
        !            67:                                *p++ = PG_V|PG_KW|(b+n);
        !            68:                        else
        !            69:                                *p++ = 0;
        !            70:        }
        !            71:        /*
        !            72:         * map the remainder to NMI adapters
        !            73:         */
        !            74:        *p++ = PG_KW|PG_V|(0x20080000/NBPG);    /* NBIA 0 */
        !            75:        *p++ = PG_KW|PG_V|(0x24080000/NBPG);    /* NBIA 1 */
        !            76:        *p++ = PG_KW|PG_V|(0x3e000000/NBPG);    /* memory */
        !            77:        mcrcsr = (long *)(iospace + nexcnt * sizeof(struct nexus) + 2 * NBPG);
        !            78: }
        !            79: 
        !            80: static
        !            81: nexreg(n)
        !            82: register struct nextab *n;
        !            83: {
        !            84:        if (n->bus >= 4 || n->adp >= 16)
        !            85:                return(0);
        !            86:        return (btoc(0x20000000 + (n->bus * 0x2000000) + (n->adp * NXSIZE)));
        !            87: }
        !            88: 
        !            89: /*
        !            90:  * `loc' requests local address within that BI
        !            91:  * the local address is what we put in sadr/eadr
        !            92:  * the global one is what we put in the page table
        !            93:  */
        !            94: static
        !            95: nexwind(n, loc)
        !            96: register struct nextab *n;
        !            97: {
        !            98:        register long addr;
        !            99: 
        !           100:        addr = 0x20400000 + (n->adp * NXWSIZE);
        !           101:        if (loc == 0)
        !           102:                addr += (n->bus * 0x2000000);
        !           103:        return (btoc(addr));
        !           104: }
        !           105: 
        !           106: /*
        !           107:  * generic VAXBI routines
        !           108:  */
        !           109: 
        !           110: extern int biacnt;
        !           111: extern char bianode[];
        !           112: extern struct biaddr biaaddr[];
        !           113: 
        !           114: #define        NNUM    017     /* node to receive interrupts */
        !           115: #define        NOK     0200    /* this node has been initialized */
        !           116: 
        !           117: #define        DB88    0x106   /* DB88 device type */
        !           118: #define        NBIE    0x200000        /* NBIA interrupt enable */
        !           119: #define        NBINIT  0x1     /* NBIA CSR1 init */
        !           120: 
        !           121: #define        NBIASTALL       1000000
        !           122: 
        !           123: /*
        !           124:  * return the address of a node's registers
        !           125:  * make sure the adapter has been initialized
        !           126:  */
        !           127: 
        !           128: caddr_t
        !           129: biaddr(bi)
        !           130: register struct biaddr *bi;
        !           131: {
        !           132:        register int a;
        !           133: 
        !           134:        if (bi->nexus < 0 || bi->nexus >= nexcnt)
        !           135:                return (0);
        !           136:        a = nextab[bi->nexus].bus;
        !           137:        if (a != bi->adno)
        !           138:                printf("nx%d adno%d bus%d\n", bi->nexus, bi->adno, a);
        !           139:        if ((bianode[a] & NOK) == 0 && biainit(a) == 0)
        !           140:                return (0);
        !           141:        return ((caddr_t)(iospace + bi->nexus * sizeof(struct nexus)));
        !           142: }
        !           143: /*
        !           144:  * set certain magic numbers in the BIIC:
        !           145:  * interrupt destination and map
        !           146:  * call after node reset stuff is all done,
        !           147:  * lest the numbers disappear
        !           148:  *
        !           149:  * can't NRST or look at BROKE here,
        !           150:  * as conventions vary too much among devices
        !           151:  */
        !           152: 
        !           153: int
        !           154: biinit(bi, mapwin)
        !           155: struct biaddr *bi;
        !           156: int mapwin;
        !           157: {
        !           158:        register struct biic *bp;
        !           159:        long wind;
        !           160: 
        !           161:        if ((bp = (struct biic *)biaddr(bi)) == NULL)
        !           162:                panic("biinit");
        !           163:        bp->biintr = 1<<(bianode[bi->adno] & NNUM);
        !           164:        if (mapwin == 0) {
        !           165:                bp->bieadr = 0;
        !           166:                bp->bisadr = 0;
        !           167:        } else {
        !           168:                wind = ctob(nexwind(&nextab[bi->nexus], 1));
        !           169:                bp->bieadr = wind + NXWSIZE;
        !           170:                bp->bisadr = wind;
        !           171:        }
        !           172: }
        !           173: 
        !           174: /*
        !           175:  * init an NBIA
        !           176:  * and both the DB88s on this NBIA, if need be
        !           177:  */
        !           178: 
        !           179: static int
        !           180: biainit(a)
        !           181: register int a;
        !           182: {
        !           183:        register caddr_t cp;
        !           184:        register int v;
        !           185:        register struct nbia *np;
        !           186: 
        !           187:        if (a >= biacnt)
        !           188:                return (0);
        !           189:        if (nbia[0] == 0) {
        !           190:                cp = iospace + (nexcnt * sizeof(struct nexus));
        !           191:                nbia[0] = (struct nbia *)cp;
        !           192:                nbia[1] = (struct nbia *)(cp + NBPG);
        !           193:        }
        !           194:        np = ((a & 02) == 0) ? nbia[0] : nbia[1];
        !           195:        if (badaddr(&np->csr0, sizeof(long))) {
        !           196:                printf("nbia for bi%d not responding\n", a);
        !           197:                return (0);
        !           198:        }
        !           199:        np->csr1 |= NBINIT;
        !           200:        for (v = 0; v < NBIASTALL; v++)
        !           201:                ;
        !           202:        if ((v = nbiavec(a & ~1)) == 0)
        !           203:                return (0);
        !           204:        bibinit(a & ~1);        /* the even one */
        !           205:        bibinit(a | 1);         /* the odd one */
        !           206:        v &= 0x7c00;    /* just the useful bits of vector */
        !           207:        np->csr0 = np->csr0;    /* clear error complaints */
        !           208:        np->csr1 = np->csr1;
        !           209:        np->csr0 = v|NBIE;
        !           210:        setnmi((a & 02) ? 1 : 0);
        !           211:        return ((bianode[a] & NOK) != 0);
        !           212: }
        !           213: 
        !           214: /*
        !           215:  * init one DB88
        !           216:  */
        !           217: 
        !           218: static
        !           219: bibinit(a)
        !           220: register int a;
        !           221: {
        !           222:        register struct biic *bp;
        !           223:        register struct biaddr *bi;
        !           224: 
        !           225:        if (a >= biacnt || biaaddr[a].nexus < 0)
        !           226:                return;
        !           227:        bi = &biaaddr[a];
        !           228:        if (bi->nexus < 0 || bi->nexus >= nexcnt)
        !           229:                return;
        !           230:        bp = (struct biic *)(iospace + bi->nexus * sizeof(struct nexus));
        !           231:        bp->bitype = (bp->bitype & 0xffff0000)|DB88;
        !           232:        bp->bisadr = 0;
        !           233:        bp->bieadr = 0x20000000;        /* all non-IO space */
        !           234:        bp->bieir = EIBR7|bi->vec;
        !           235:        bp->bicsr |= BIBROKE|BIHEIE|BISEIE;     /* write BROKE to clear it */
        !           236:        bp->biber = bp->biber;
        !           237:        bp->bibci |= BCINTREN|BCRTOEN;
        !           238:        bp->biintr = 1<<(bp->bicsr & BINODEID);
        !           239:        if ((bp->bitype & 0xffff) != DB88)
        !           240:                return; /* oops */
        !           241:        bianode[a] = NOK|(bp->bicsr & BINODEID);
        !           242: }
        !           243: 
        !           244: /*
        !           245:  * figure out the vector offset for the nbia
        !           246:  * annoying sanity checks on the pair of DB88s
        !           247:  */
        !           248: 
        !           249: static int
        !           250: nbiavec(a)
        !           251: register int a;
        !           252: {
        !           253:        register struct biaddr *o, *e;
        !           254:        register int err;
        !           255: 
        !           256:        e = &biaaddr[a];
        !           257:        o = &biaaddr[a+1];
        !           258:        err = 0;
        !           259:        if (a+1 < biacnt && e->nexus >= 0 && o->nexus >= 0)
        !           260:                if (o->ovec != e->ovec+0x200)
        !           261:                        err++;
        !           262:        if (e->nexus >= 0 && (e->ovec & 0x200) != 0)
        !           263:                err++;
        !           264:        if (a+1 < biacnt && o->nexus >= 0 && (o->ovec & 0x200) == 0)
        !           265:                err++;
        !           266:        if (err)
        !           267:                printf("bi%d bi%d: fix the damned vectors\n", a, a+1);
        !           268:        /*
        !           269:         * now for the vector
        !           270:         */
        !           271:        if (e->nexus >= 0)
        !           272:                return (e->ovec);
        !           273:        if (a+1 < biacnt && o->nexus >= 0)
        !           274:                return (o->ovec - 0x200);
        !           275:        return (0);
        !           276: }
        !           277: 
        !           278: /*
        !           279:  * here on nbia interrupt
        !           280:  * -- bi or nbi parity error, bi powerup
        !           281:  * figure out how to ignore the latter
        !           282:  */
        !           283: 
        !           284: nbiaintr(dev)
        !           285: int dev;
        !           286: {
        !           287:        register struct nbia *np;
        !           288:        register long csr0, csr1;
        !           289: 
        !           290:        np = nbia[dev];
        !           291:        csr0 = np->csr0;
        !           292:        csr1 = np->csr1;
        !           293:        np->csr0 = csr0;        /* clear interrupt conditions */
        !           294:        np->csr1 = csr1;
        !           295:        printf("nbi%d intr csr0 %x csr1 %x\n", dev, csr0, csr1);
        !           296: }
        !           297: 
        !           298: /*
        !           299:  * here on nbib error interrupt
        !           300:  */
        !           301: 
        !           302: bia0int(dev)
        !           303: register int dev;
        !           304: {
        !           305:        register struct biic *bp;
        !           306:        register long biber, bicsr;
        !           307: 
        !           308:        if (dev >= biacnt || biaaddr[dev].nexus < 0 || biaaddr[dev].nexus >= nexcnt)
        !           309:                return;
        !           310:        bp = (struct biic *)(iospace + biaaddr[dev].nexus * sizeof(struct nexus));
        !           311:        bicsr = bp->bicsr;
        !           312:        biber = bp->biber;
        !           313:        bp->biber = biber;      /* clear latches */
        !           314:        if ((biber & (BIHES|BISES)) == 0)
        !           315:                return;
        !           316:        if (cknofault())
        !           317:                return;
        !           318:        printf("bi%d: csr %x ber %x\n", dev, bicsr, biber);
        !           319: }

unix.superglobalmegacorp.com

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