|
|
1.1 ! root 1: /* ! 2: * Q-bus adapter routines for MicroVAX II ! 3: * The names imply `UNIBUS'; most of the system knows no difference ! 4: */ ! 5: ! 6: #include "sys/param.h" ! 7: #include "sys/ubaddr.h" ! 8: #include "sys/map.h" ! 9: #include "sys/uba.h" ! 10: #include "sys/pte.h" ! 11: #include "sys/vmparam.h" ! 12: #include "sys/qbio.h" ! 13: ! 14: extern struct uba uba[]; ! 15: extern struct nxaddr ubaaddr[]; ! 16: extern int ubacnt; ! 17: ! 18: /* ! 19: * bits in map register ! 20: */ ! 21: ! 22: #define MPAGE 0x3fff /* physical page number -- small on comet */ ! 23: #define MRV 0x80000000 /* map register valid */ ! 24: ! 25: #define QIOBASE 0760000 /* base address in Q-bus io space */ ! 26: ! 27: #define ICR 0777500 /* interprocessor control register */ ! 28: #define LMEAE 040 /* local memory external access enable */ ! 29: ! 30: /* ! 31: * return the register address for a unibus device ! 32: */ ! 33: ! 34: caddr_t ! 35: ubaddr(up) ! 36: register struct ubaddr *up; ! 37: { ! 38: register struct uba *ub; ! 39: ! 40: if (up->ubno < 0 || up->ubno > ubacnt) { ! 41: printf("bad qbus no %d\n", up->ubno); ! 42: return (0); ! 43: } ! 44: ub = &uba[up->ubno]; ! 45: if ((ub->flags & UBINIT) == 0) ! 46: if (ubstart(up->ubno) == 0) ! 47: return (0); ! 48: return ((caddr_t)&ub->addr->ioreg[up->uboff-QIOBASE]); ! 49: } ! 50: ! 51: /* ! 52: * init the unibus adapter ! 53: */ ! 54: ! 55: ubstart(u) ! 56: int u; ! 57: { ! 58: register struct uba *ub; ! 59: extern caddr_t qbaaddr(); ! 60: ! 61: ub = &uba[u]; ! 62: if ((ub->addr = (struct ubadev *)qbaaddr(u)) == 0) ! 63: return (0); ! 64: rminit(ub->map, UBNMAP, NQMREG-1, 1); /* NQMREG-1 because can't alloc 0 */ ! 65: if (ubmstart(u) == 0) ! 66: return (0); ! 67: ubinit(u); ! 68: ub->flags |= UBINIT|UBQBUS; ! 69: return (1); ! 70: } ! 71: ! 72: /* ! 73: * init the unibus adapter hardware ! 74: */ ! 75: ! 76: ubinit(u) ! 77: int u; ! 78: { ! 79: register struct uba *ub; ! 80: register int i; ! 81: register long *p; ! 82: ! 83: ub = &uba[u]; ! 84: *(short *)&ub->addr->ioreg[ICR-QIOBASE] |= LMEAE; ! 85: for (i = 0, p = ub->addr->mreg; i < NQMREG; i++) ! 86: *p++ = 0; ! 87: ubminit(u); ! 88: } ! 89: ! 90: /* ! 91: * determine whether a particular address, ! 92: * which happens to be in UNIBUS space, ! 93: * exists ! 94: * -- on MicroVAX, you just get a machine check on error ! 95: */ ! 96: ubbadaddr(u, a, s) ! 97: int u, s; ! 98: caddr_t a; ! 99: { ! 100: ! 101: return (badaddr(a, s)); ! 102: } ! 103: ! 104: /* ! 105: * get/put a single byte to a particular unibus address ! 106: * intended for use by ECC code ! 107: * work it out from first principles, ! 108: * because UNIBUS adapter may loop and hang otherwise ! 109: */ ! 110: ! 111: static long ! 112: ubphys(ubno, addr) ! 113: unsigned int ubno; ! 114: uaddr_t addr; ! 115: { ! 116: register struct uba *ub; ! 117: register int pg; ! 118: register long m; ! 119: ! 120: if (ubno >= ubacnt) ! 121: panic("ubphys"); ! 122: ub = &uba[ubno]; ! 123: if (ub->addr == NULL) ! 124: panic("ubphys"); ! 125: pg = addr / NBPG; ! 126: if (pg >= NQMREG) ! 127: return (-1); /* addr too big */ ! 128: m = ub->addr->mreg[pg]; ! 129: if ((m & MRV) == 0) ! 130: return (-1); /* invalid */ ! 131: return ((m & MPAGE) * NBPG + addr % NBPG); ! 132: } ! 133: ! 134: int ! 135: ubgetc(ubno, addr) ! 136: unsigned int ubno; ! 137: uaddr_t addr; ! 138: { ! 139: register long phys; ! 140: ! 141: phys = ubphys(ubno, addr); ! 142: if (phys < 0) ! 143: return (-1); ! 144: return (phgetc(phys)); ! 145: } ! 146: ! 147: int ! 148: ubputc(ubno, addr, c) ! 149: unsigned int ubno; ! 150: uaddr_t addr; ! 151: char c; ! 152: { ! 153: register long phys; ! 154: ! 155: phys = ubphys(ubno, addr); ! 156: if (phys < 0) ! 157: return (-1); ! 158: return (phputc(phys, c)); ! 159: } ! 160: ! 161: /* ! 162: * allocate a BDP: MicroVAXes have none ! 163: */ ! 164: ! 165: int ! 166: ubmapath(u) ! 167: int u; ! 168: { ! 169: return (0); ! 170: } ! 171: ! 172: ubmflush(u, path) ! 173: int u; ! 174: int path; ! 175: { ! 176: } ! 177: ! 178: /* ! 179: * fill in a piece of unibus map ! 180: * return the address of the base ! 181: * ! 182: * hardware bug: successive writes to map registers ! 183: * can block Q-bus DMA ! 184: * workaround: CPU write to memory after each map reg write, ! 185: * to slow it down enough ! 186: */ ! 187: ! 188: uaddr_t ! 189: ubmsetmap(u, p, nreg, um) ! 190: int u; ! 191: register struct pte *p; ! 192: register int nreg; ! 193: ubm_t um; ! 194: { ! 195: register long *m; ! 196: int junk; ! 197: ! 198: m = &uba[u].addr->mreg[ubmfirst(um)]; ! 199: if (nreg > ubmsize(um)-1) ! 200: panic("ubmsetmap"); ! 201: while (--nreg >= 0) { ! 202: *m++ = p++->pg_pfnum | MRV; ! 203: junk = 0; ! 204: } ! 205: return (ctob(ubmfirst(um))); ! 206: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.