|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.