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