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