|
|
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.