|
|
1.1 ! root 1: /* ! 2: * unibus adapter routines for VAX-11/750 ! 3: */ ! 4: ! 5: #include "sys/param.h" ! 6: #include "sys/ubaddr.h" ! 7: #include "sys/nexus.h" ! 8: #include "sys/nxaddr.h" ! 9: #include "sys/map.h" ! 10: #include "sys/uba.h" ! 11: #include "sys/pte.h" ! 12: #include "sys/vmparam.h" ! 13: ! 14: extern struct uba uba[]; ! 15: extern struct nxaddr ubaaddr[]; ! 16: extern int ubacnt; ! 17: ! 18: /* ! 19: * `registers', such as they are, ! 20: * for the comet unibus ! 21: * 0x2000 bytes of nexus space, followed by the address window ! 22: */ ! 23: ! 24: #define NMAP 496 ! 25: #define NBDP 3 ! 26: ! 27: struct ubadev { ! 28: long junk0[0x10]; ! 29: long dpr[16]; /* data path registers */ ! 30: long junk1[0x1e0]; ! 31: long mreg[512]; /* unibus map registers; last 16 unused */ ! 32: long junk2[0x400]; ! 33: char ubspace[NXWSIZE]; ! 34: }; ! 35: ! 36: /* ! 37: * bits in the data path register ! 38: */ ! 39: ! 40: #define PURGE 0x1 /* purge datapath */ ! 41: #define DPERR 0x80000000 /* any datapath error */ ! 42: ! 43: /* ! 44: * bits in map register ! 45: */ ! 46: ! 47: #define MPAGE 0x3fff /* physical page number -- small on comet */ ! 48: #define BO 0x2000000 /* offset address by one */ ! 49: #define MRV 0x80000000 /* map register valid */ ! 50: #define PSHIFT 21 /* shift data path number this much */ ! 51: ! 52: /* ! 53: * return the register address for a unibus device ! 54: */ ! 55: ! 56: caddr_t ! 57: ubaddr(up) ! 58: register struct ubaddr *up; ! 59: { ! 60: register struct uba *ub; ! 61: ! 62: if (up->ubno < 0 || up->ubno > ubacnt) { ! 63: printf("bad ubano %d\n", up->ubno); ! 64: return (0); ! 65: } ! 66: ub = &uba[up->ubno]; ! 67: if ((ub->flags & UBINIT) == 0) ! 68: if (ubstart(up->ubno) == 0) ! 69: return (0); ! 70: return ((caddr_t)&ub->addr->ubspace[up->uboff]); ! 71: } ! 72: ! 73: /* ! 74: * init the unibus adapter ! 75: */ ! 76: ! 77: ubstart(u) ! 78: int u; ! 79: { ! 80: register struct uba *ub; ! 81: ! 82: ub = &uba[u]; ! 83: if ((ub->addr = (struct ubadev *)nxaddr(&ubaaddr[u])) == 0) ! 84: return (0); ! 85: if (badaddr(&ub->addr->dpr[1], sizeof(long))) { ! 86: printf("ub%d not responding\n", u); ! 87: return (0); ! 88: } ! 89: rminit(ub->map, UBNMAP, NMAP-1, 1); /* NMAP-1 because can't alloc 0 */ ! 90: ub->path = ((1<<NBDP)-1)<<1; ! 91: if (ubmstart(u) == 0) ! 92: return (0); ! 93: ubinit(u); ! 94: ub->flags |= UBINIT; ! 95: return (1); ! 96: } ! 97: ! 98: /* ! 99: * init the unibus adapter hardware ! 100: */ ! 101: ! 102: ubinit(u) ! 103: int u; ! 104: { ! 105: register struct uba *ub; ! 106: register int i; ! 107: register long *p; ! 108: ! 109: ub = &uba[u]; ! 110: for (i = 0, p = ub->addr->mreg; i < NMAP; i++) ! 111: *p++ = 0; ! 112: ubminit(u); ! 113: } ! 114: ! 115: /* ! 116: * determine whether a particular address, ! 117: * which happens to be in UNIBUS space, ! 118: * exists ! 119: * -- on comet, you just get a machine check on error ! 120: */ ! 121: ubbadaddr(u, a, s) ! 122: int u, s; ! 123: caddr_t a; ! 124: { ! 125: ! 126: return (badaddr(a, s)); ! 127: } ! 128: ! 129: /* ! 130: * get/put a single byte to a particular unibus address ! 131: * intended for use by ECC code ! 132: * work it out from first principles, ! 133: * because UNIBUS adapter may loop and hang otherwise ! 134: */ ! 135: ! 136: static long ! 137: ubphys(ubno, addr) ! 138: unsigned int ubno; ! 139: uaddr_t addr; ! 140: { ! 141: register struct uba *ub; ! 142: register int pg; ! 143: register long m; ! 144: ! 145: if (ubno >= ubacnt) ! 146: panic("ubphys"); ! 147: ub = &uba[ubno]; ! 148: if (ub->addr == NULL) ! 149: panic("ubphys"); ! 150: pg = addr / NBPG; ! 151: if (pg >= NMAP) ! 152: return (-1); /* addr too big */ ! 153: m = ub->addr->mreg[pg]; ! 154: if ((m & MRV) == 0) ! 155: return (-1); /* invalid */ ! 156: return ((m & MPAGE) * NBPG + addr % NBPG); ! 157: } ! 158: ! 159: int ! 160: ubgetc(ubno, addr) ! 161: unsigned int ubno; ! 162: uaddr_t addr; ! 163: { ! 164: register long phys; ! 165: ! 166: phys = ubphys(ubno, addr); ! 167: if (phys < 0) ! 168: return (-1); ! 169: return (phgetc(phys)); ! 170: } ! 171: ! 172: int ! 173: ubputc(ubno, addr, c) ! 174: unsigned int ubno; ! 175: uaddr_t addr; ! 176: char c; ! 177: { ! 178: register long phys; ! 179: ! 180: phys = ubphys(ubno, addr); ! 181: if (phys < 0) ! 182: return (-1); ! 183: return (phputc(phys, c)); ! 184: } ! 185: ! 186: /* ! 187: * unibus adapter interrupts; ! 188: * on the comet, these are always wrong ! 189: */ ! 190: ! 191: uba0int(dev) ! 192: int dev; ! 193: { ! 194: printf("uba%d stray intr\n", dev); ! 195: } ! 196: ! 197: /* ! 198: * allocate a buffered data path ! 199: * return the ddp if none available ! 200: */ ! 201: int ubnopath; ! 202: ! 203: int ! 204: ubmapath(u) ! 205: int u; ! 206: { ! 207: register struct uba *ub; ! 208: register int path; ! 209: register int s; ! 210: ! 211: ub = &uba[u]; ! 212: s = spl6(); ! 213: for (path = NBDP; path > 0; path--) ! 214: if (ub->path & (1<<path)) { ! 215: ub->path &=~ (1<<path); ! 216: break; ! 217: } ! 218: splx(s); ! 219: if (path == 0) ! 220: ubnopath++; ! 221: return (path); ! 222: } ! 223: ! 224: /* ! 225: * flush (in hardware) a bdp ! 226: */ ! 227: #define PRGTIM 10 ! 228: ! 229: ubmflush(u, path) ! 230: int u; ! 231: int path; ! 232: { ! 233: register long *reg; ! 234: register int i; ! 235: ! 236: if (path == 0) ! 237: return; ! 238: reg = &uba[u].addr->dpr[path]; ! 239: *reg = PURGE; ! 240: for (i = PRGTIM; i > 0; --i) ! 241: if ((*reg & PURGE) == 0) ! 242: break; ! 243: if (i <= 0) ! 244: printf("uba%d bdp%d stuck %x\n", u, path, *reg); ! 245: if (*reg & DPERR) { ! 246: printf("uba%d bdp%d err %x\n", u, path, *reg); ! 247: *reg = *reg; ! 248: } ! 249: } ! 250: ! 251: /* ! 252: * fill in a piece of unibus map ! 253: * return the address of the base ! 254: */ ! 255: ! 256: uaddr_t ! 257: ubmsetmap(u, p, nreg, um) ! 258: int u; ! 259: register struct pte *p; ! 260: register int nreg; ! 261: ubm_t um; ! 262: { ! 263: register long *m; ! 264: register long x; ! 265: ! 266: m = &uba[u].addr->mreg[ubmfirst(um)]; ! 267: x = (ubmpath(um)<<PSHIFT)|MRV; ! 268: if (nreg > ubmsize(um)-1) ! 269: panic("ubmsetmap"); ! 270: while (--nreg >= 0) ! 271: *m++ = p++->pg_pfnum | x; ! 272: return (ctob(ubmfirst(um))); ! 273: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.