|
|
1.1 ! root 1: /* ! 2: * unibus adapter routines for DWBUA ! 3: */ ! 4: ! 5: #include "sys/param.h" ! 6: #include "sys/ubaddr.h" ! 7: #include "sys/nexus.h" ! 8: #include "sys/biaddr.h" ! 9: #include "sys/biic.h" ! 10: #include "sys/map.h" ! 11: #include "sys/uba.h" ! 12: #include "sys/pte.h" ! 13: #include "sys/vmparam.h" ! 14: ! 15: extern struct uba uba[]; ! 16: extern struct biaddr ubaaddr[]; ! 17: extern int ubacnt; ! 18: ! 19: /* ! 20: * 0x2000 bytes of nexus space, followed by the address window ! 21: */ ! 22: ! 23: #define NMAP 496 ! 24: #define NBDP 5 ! 25: ! 26: struct ubadev { ! 27: struct biic bi; ! 28: long junk0[392]; ! 29: long csr; ! 30: long vor; ! 31: long fubar; ! 32: long bifar; ! 33: long junk1[8]; ! 34: long dpr[16]; /* 0 == DDP, 5 BDPs, rest unused */ ! 35: long junk2[28]; ! 36: long mreg[512]; ! 37: long junk3[0x400]; ! 38: char ubspace[NXWSIZE]; ! 39: }; ! 40: ! 41: /* ! 42: * bits in the data path register ! 43: */ ! 44: ! 45: #define PURGE 0x1 /* purge datapath */ ! 46: ! 47: /* ! 48: * bits in map register ! 49: */ ! 50: ! 51: #define BO 0x2000000 /* offset address by one */ ! 52: #define MRV 0x80000000 /* map register valid */ ! 53: #define PSHIFT 21 /* shift data path number this much */ ! 54: ! 55: /* ! 56: * bits in csr ! 57: */ ! 58: ! 59: #define BUAERR 0x80000000 /* BUA error summary */ ! 60: #define USSTO 0x8000000 /* VAXBI-to-UNIBUS SSYN timeout */ ! 61: #define BUAEIE 0x100000 /* error interrupt enable */ ! 62: #define BUAONE 0x8000 /* set when adapter is answering */ ! 63: ! 64: /* ! 65: * bits in gpr0 ! 66: */ ! 67: ! 68: #define UBPUP 0x1 /* unibus is powered up */ ! 69: ! 70: /* ! 71: * return the register address for a unibus device ! 72: */ ! 73: ! 74: caddr_t ! 75: ubaddr(up) ! 76: register struct ubaddr *up; ! 77: { ! 78: register struct uba *ub; ! 79: ! 80: if (up->ubno < 0 || up->ubno > ubacnt) { ! 81: printf("bad ubano %d\n", up->ubno); ! 82: return (0); ! 83: } ! 84: ub = &uba[up->ubno]; ! 85: if ((ub->flags & UBINIT) == 0) ! 86: if (ubstart(up->ubno) == 0) ! 87: return (0); ! 88: return ((caddr_t)&ub->addr->ubspace[up->uboff]); ! 89: } ! 90: ! 91: /* ! 92: * init the unibus adapter ! 93: */ ! 94: ! 95: ubstart(u) ! 96: int u; ! 97: { ! 98: register struct uba *ub; ! 99: ! 100: ub = &uba[u]; ! 101: if ((ub->addr = (struct ubadev *)biaddr(&ubaaddr[u])) == 0) ! 102: return (0); ! 103: if (badaddr(&ub->addr->bi.bitype, sizeof(long))) { ! 104: printf("ub%d absent\n"); ! 105: return (0); ! 106: } ! 107: rminit(ub->map, UBNMAP, NMAP-1, 1); /* NMAP-1 because can't alloc 0 */ ! 108: ub->path = ((1<<NBDP)-1)<<1; ! 109: if (ubmstart(u) == 0) ! 110: return (0); ! 111: if (ubinit(u) == 0) ! 112: return (0); ! 113: ub->flags |= UBINIT; ! 114: return (1); ! 115: } ! 116: ! 117: /* ! 118: * init the unibus adapter hardware ! 119: */ ! 120: ! 121: #define PUSTALL 200000 ! 122: ! 123: ubinit(u) ! 124: register int u; ! 125: { ! 126: register struct uba *ub; ! 127: register struct ubadev *up; ! 128: register int i; ! 129: register int s; ! 130: register long *p; ! 131: ! 132: ub = &uba[u]; ! 133: up = ub->addr; ! 134: s = spl7(); ! 135: DELAY(80000); ! 136: up->bi.bicsr |= BINRST|BISTS; ! 137: DELAY(80000); ! 138: for (i = 0; i < PUSTALL; i++) ! 139: if (up->bi.bicsr & BISTS) ! 140: break; ! 141: for (i = 0; i < PUSTALL; i++) ! 142: if (up->csr & BUAONE) ! 143: break; ! 144: for (i = 0; i < PUSTALL; i++) ! 145: if (up->bi.bigpr0 & UBPUP) ! 146: break; ! 147: splx(s); ! 148: if ((up->bi.bigpr0 & UBPUP) == 0) { ! 149: printf("ub%d not responding; csr x%x\n", u, up->csr); ! 150: return (0); ! 151: } ! 152: biinit(&ubaaddr[u], 1); ! 153: up->vor = ubaaddr[u].ovec; ! 154: up->bi.bieir = ubaaddr[u].vec|EIBR7; ! 155: up->bi.biuir = UIEXVEC; ! 156: up->bi.biber = BIBERCLR; ! 157: up->bi.bicsr |= BIHEIE|BISEIE|BIHIARB; ! 158: up->csr |= BUAEIE; /* also clears error latches */ ! 159: for (i = 0, p = ub->addr->mreg; i < NMAP; i++) ! 160: *p++ = 0; ! 161: ubminit(u); ! 162: return (1); ! 163: } ! 164: ! 165: /* ! 166: * determine whether a particular address, ! 167: * which happens to be in UNIBUS space, ! 168: * exists ! 169: */ ! 170: ubbadaddr(u, a, s) ! 171: int u, s; ! 172: caddr_t a; ! 173: { ! 174: register int p; ! 175: register struct ubadev *up; ! 176: ! 177: if (u < 0 || u >= ubacnt) ! 178: return (1); ! 179: up = uba[u].addr; ! 180: p = spl7(); ! 181: up->csr = up->csr; /* clear errors */ ! 182: s = badaddr(a, s); ! 183: if (up->csr & USSTO) /* or perhaps any error? */ ! 184: s = 1; ! 185: up->csr = up->csr; /* clear errors again */ ! 186: splx(p); ! 187: return (s); ! 188: } ! 189: ! 190: /* ! 191: * unibus adapter interrupts ! 192: */ ! 193: ! 194: uba0int(dev) ! 195: int dev; ! 196: { ! 197: register struct ubadev *up; ! 198: register long biber, bicsr, ubcsr; ! 199: ! 200: if (dev < 0 || dev >= ubacnt) { ! 201: printf("stray intr from ub%d\n", dev); ! 202: return; ! 203: } ! 204: up = uba[dev].addr; ! 205: if (up == 0) { ! 206: printf("ub%d unexpected intr\n", dev); ! 207: return; ! 208: } ! 209: biber = up->bi.biber; ! 210: bicsr = up->bi.bicsr; ! 211: ubcsr = up->csr; ! 212: up->bi.biber = biber; /* clear latches */ ! 213: up->bi.biber &=~ EIFORCE; /* needed? */ ! 214: up->csr |= BUAEIE; ! 215: if (cknofault()) ! 216: return; ! 217: if (bicsr & (BIHES|BISES)) ! 218: printf("ub%d bicsr x%x biber x%x\n", dev, bicsr, biber); ! 219: if (ubcsr & BUAERR) ! 220: printf("ub%d csr x%x fubar 0%o bifar x%x\n", dev, ! 221: ubcsr, up->fubar<<2, up->bifar); ! 222: } ! 223: ! 224: /* ! 225: * allocate a buffered data path ! 226: * return the ddp if none available ! 227: */ ! 228: int ubnopath; ! 229: ! 230: int ! 231: ubmapath(u) ! 232: int u; ! 233: { ! 234: register struct uba *ub; ! 235: register int path; ! 236: register int s; ! 237: ! 238: ub = &uba[u]; ! 239: s = spl6(); ! 240: for (path = NBDP; path > 0; path--) ! 241: if (ub->path & (1<<path)) { ! 242: ub->path &=~ (1<<path); ! 243: break; ! 244: } ! 245: splx(s); ! 246: if (path == 0) ! 247: ubnopath++; ! 248: return (path); ! 249: } ! 250: ! 251: /* ! 252: * flush (in hardware) a bdp ! 253: */ ! 254: ! 255: ubmflush(u, path) ! 256: int u; ! 257: int path; ! 258: { ! 259: ! 260: if (path == 0 || path > NBDP) ! 261: return; ! 262: uba[u].addr->dpr[path] = PURGE; ! 263: } ! 264: ! 265: /* ! 266: * fill in a piece of unibus map ! 267: * return the address of the base ! 268: */ ! 269: ! 270: uaddr_t ! 271: ubmsetmap(u, p, nreg, um) ! 272: int u; ! 273: register struct pte *p; ! 274: register int nreg; ! 275: ubm_t um; ! 276: { ! 277: register long *m; ! 278: register long x; ! 279: ! 280: m = &uba[u].addr->mreg[ubmfirst(um)]; ! 281: x = (ubmpath(um)<<PSHIFT)|MRV; ! 282: if (nreg > ubmsize(um)-1) ! 283: panic("ubmsetmap"); ! 284: while (--nreg >= 0) ! 285: *m++ = p++->pg_pfnum | x; ! 286: return (ctob(ubmfirst(um))); ! 287: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.