Commit | Line | Data |
---|---|---|
a7e7fa7e | 1 | /* autoconf.c 4.16 81/02/27 */ |
327f6ec8 | 2 | |
327f6ec8 | 3 | /* |
5aa9d5ea | 4 | * Configure the system for the current machine. |
327f6ec8 BJ |
5 | */ |
6 | ||
47fa50b1 BJ |
7 | #include "mba.h" |
8 | ||
327f6ec8 | 9 | #include "../h/param.h" |
3f3a34c3 | 10 | #include "../h/systm.h" |
327f6ec8 BJ |
11 | #include "../h/map.h" |
12 | #include "../h/nexus.h" | |
13 | #include "../h/pte.h" | |
14 | #include "../h/buf.h" | |
15 | #include "../h/mba.h" | |
8d2ea14f BJ |
16 | #include "../h/dk.h" |
17 | #include "../h/vm.h" | |
3f3a34c3 | 18 | #include "../h/uba.h" |
327f6ec8 BJ |
19 | #include "../h/mtpr.h" |
20 | #include "../h/cpu.h" | |
21 | #include "../h/scb.h" | |
3f3a34c3 | 22 | #include "../h/mem.h" |
327f6ec8 | 23 | |
8d2ea14f | 24 | int cold; |
327f6ec8 | 25 | int nexnum; /* current nexus number */ |
8d2ea14f | 26 | int dkn; /* number of dk numbers assigned so far */ |
327f6ec8 | 27 | |
47fa50b1 | 28 | #if NMBA > 0 |
8d2ea14f | 29 | int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int }; |
47fa50b1 | 30 | #endif |
5aa9d5ea | 31 | #if VAX780 |
8d2ea14f | 32 | int (*ubaintv[4])() = { Xua0int, Xua1int, Xua2int, Xua3int }; |
5aa9d5ea | 33 | caddr_t umaddr780[4] = { |
30d13fef BJ |
34 | (caddr_t) 0x2013e000, (caddr_t) 0x2017e000, |
35 | (caddr_t) 0x201be000, (caddr_t) 0x201fe000 | |
3f3a34c3 | 36 | }; |
5aa9d5ea | 37 | #endif |
327f6ec8 | 38 | |
47fa50b1 BJ |
39 | #if VAX780 |
40 | int c780(); | |
41 | #endif | |
42 | #if VAX750 | |
43 | int c750(); | |
44 | #endif | |
3f3a34c3 BJ |
45 | |
46 | struct percpu percpu[] = { | |
47 | #if VAX780 | |
30d13fef | 48 | c780, VAX_780, |
3f3a34c3 BJ |
49 | #endif |
50 | #if VAX750 | |
30d13fef | 51 | c750, VAX_750, |
3f3a34c3 BJ |
52 | #endif |
53 | }; | |
54 | #define NCPU (sizeof(percpu)/sizeof(struct percpu)) | |
55 | ||
327f6ec8 BJ |
56 | /* |
57 | * Determine mass storage and memory configuration for a machine. | |
58 | * Get cpu type, and then switch out to machine specific procedures | |
59 | * which will probe adaptors to see what is out there. | |
60 | */ | |
61 | configure() | |
62 | { | |
63 | union cpusid cpusid; | |
3f3a34c3 | 64 | register struct percpu *ocp; |
3e7ee2db BJ |
65 | register int i, *ip; |
66 | extern char Sysbase[]; | |
327f6ec8 BJ |
67 | |
68 | cpusid.cpusid = mfpr(SID); | |
3f3a34c3 BJ |
69 | for (ocp = percpu; ocp < &percpu[NCPU]; ocp++) |
70 | if (ocp->pc_cputype == cpusid.cpuany.cp_type) { | |
3f3a34c3 | 71 | (*ocp->pc_config)(ocp); |
16acfbd5 | 72 | #if VAXANY |
30d13fef | 73 | setconf(); |
5aa9d5ea | 74 | #endif |
3e7ee2db BJ |
75 | ip = (int *)Sysmap; *ip &= ~PG_PROT; *ip |= PG_KR; |
76 | mtpr(TBIS, Sysbase); | |
8d2ea14f | 77 | cold = 0; |
3f3a34c3 BJ |
78 | return; |
79 | } | |
80 | printf("cpu type %d unsupported\n", cpusid.cpuany.cp_type); | |
327f6ec8 BJ |
81 | asm("halt"); |
82 | } | |
83 | ||
3f3a34c3 | 84 | #if VAX780 |
327f6ec8 BJ |
85 | /* |
86 | * Build configuration table for a 780, by looking | |
87 | * at the things (mbas and ubas) in the nexus slots | |
88 | * and initialzing each appropriately. | |
89 | */ | |
3f3a34c3 BJ |
90 | c780(pcpu) |
91 | register struct percpu *pcpu; | |
327f6ec8 BJ |
92 | { |
93 | register struct nexus *nxv; | |
5aa9d5ea | 94 | register struct uba_hd *uhp; |
30d13fef | 95 | struct nexus *nxp = NEX780; |
327f6ec8 | 96 | union nexcsr nexcsr; |
3cda891a | 97 | int i, ubawatch(); |
327f6ec8 | 98 | |
30d13fef | 99 | for (nexnum = 0,nxv = nexus; nexnum < NNEX780; nexnum++,nxp++,nxv++) { |
327f6ec8 BJ |
100 | nxaccess((caddr_t)nxp, Nexmap[nexnum]); |
101 | if (badaddr((caddr_t)nxv, 4)) | |
102 | continue; | |
103 | nexcsr = nxv->nexcsr; | |
104 | if (nexcsr.nex_csr&NEX_APD) | |
105 | continue; | |
327f6ec8 BJ |
106 | switch (nexcsr.nex_type) { |
107 | ||
108 | case NEX_MBA: | |
47fa50b1 | 109 | #if NMBA > 0 |
8d2ea14f | 110 | printf("mba%d at tr%d\n", nummba, nexnum); |
a7e7fa7e BJ |
111 | if (nummba >= NMBA) { |
112 | printf("%d mba's not configured\n", nummba+1); | |
113 | continue; | |
114 | } | |
3f3a34c3 | 115 | mbafind(nxv, nxp); |
5aa9d5ea | 116 | nummba++; |
47fa50b1 BJ |
117 | #else |
118 | printf("mba's"); | |
119 | goto unsupp; | |
120 | #endif | |
327f6ec8 BJ |
121 | |
122 | case NEX_UBA0: | |
123 | case NEX_UBA1: | |
124 | case NEX_UBA2: | |
125 | case NEX_UBA3: | |
30d13fef BJ |
126 | if (numuba >= 4) { |
127 | printf("5 uba's"); | |
3f3a34c3 BJ |
128 | goto unsupp; |
129 | } | |
8d2ea14f BJ |
130 | printf("uba%d at tr%d\n", numuba, nexnum); |
131 | setscbnex(nexnum, ubaintv[numuba]); | |
3f3a34c3 | 132 | i = nexcsr.nex_type - NEX_UBA0; |
30d13fef BJ |
133 | unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp, |
134 | umem[i], umaddr780[i]); | |
30d13fef BJ |
135 | ((struct uba_regs *)nxv)->uba_cr = |
136 | UBA_IFS|UBA_BRIE|UBA_USEFIE|UBA_SUEFIE; | |
3f3a34c3 | 137 | numuba++; |
327f6ec8 BJ |
138 | break; |
139 | ||
140 | case NEX_DR32: | |
5aa9d5ea | 141 | /* there can be more than one... are there other codes??? */ |
327f6ec8 BJ |
142 | printf("dr32"); |
143 | goto unsupp; | |
144 | ||
145 | case NEX_MEM4: | |
146 | case NEX_MEM4I: | |
147 | case NEX_MEM16: | |
148 | case NEX_MEM16I: | |
30d13fef BJ |
149 | if (nmcr >= 4) { |
150 | printf("%d mcr's", 4); | |
3f3a34c3 BJ |
151 | goto unsupp; |
152 | } | |
3e7ee2db | 153 | printf("mcr%d at tr%d\n", nmcr, nexnum); |
3f3a34c3 | 154 | mcraddr[nmcr++] = (struct mcr *)nxv; |
327f6ec8 BJ |
155 | break; |
156 | ||
157 | case NEX_MPM0: | |
158 | case NEX_MPM1: | |
159 | case NEX_MPM2: | |
160 | case NEX_MPM3: | |
161 | printf("mpm"); | |
162 | goto unsupp; | |
163 | ||
164 | default: | |
165 | printf("nexus type %x", nexcsr.nex_type); | |
30d13fef | 166 | unsupp: |
3f3a34c3 | 167 | printf(" unsupported (at tr %d)\n", nexnum); |
327f6ec8 BJ |
168 | continue; |
169 | } | |
170 | } | |
3cda891a | 171 | timeout(ubawatch, 0, HZ); |
327f6ec8 BJ |
172 | } |
173 | #endif | |
174 | ||
30d13fef BJ |
175 | #if VAX750 |
176 | /* | |
177 | * Configure a 750. There are four possible mba's, | |
178 | * one standard UNIBUS, and a memory controller. | |
179 | */ | |
180 | c750(pcpu) | |
181 | struct percpu *pcpu; | |
182 | { | |
183 | register struct nexus *nxv = nexus; | |
184 | struct nexus *nxp = NEX750; | |
185 | ||
3e7ee2db BJ |
186 | printf("mcr at %x\n", MCR_750); |
187 | nxaccess((caddr_t)MCR_750, Nexmap[nexnum]); | |
47fa50b1 BJ |
188 | mcraddr[nmcr++] = (struct mcr *)nxv; |
189 | #if NMBA > 0 | |
30d13fef BJ |
190 | for (nexnum = 0; nexnum < NNEX750; nexnum++, nxp++, nxv++) { |
191 | nxaccess((caddr_t)nxp, Nexmap[nexnum]); | |
192 | if (badaddr((caddr_t)nxv, 4)) | |
193 | continue; | |
3e7ee2db | 194 | printf("mba%d at %x\n", nummba, nxp); |
a7e7fa7e BJ |
195 | if (nummba >= NMBA) |
196 | printf("%d mba's not configured\n", nummba+1); | |
197 | else { | |
198 | mbafind(nxv, nxp); | |
199 | nummba++; | |
200 | } | |
30d13fef | 201 | } |
47fa50b1 | 202 | #endif |
3e7ee2db | 203 | printf("uba at %x\n", nxp); |
30d13fef BJ |
204 | nxaccess((caddr_t)nxp, Nexmap[nexnum++]); |
205 | unifind((struct uba_regs *)nxv++, (struct uba_regs *)nxp, | |
8d2ea14f | 206 | umem[0], UMEM750); |
30d13fef | 207 | numuba = 1; |
30d13fef BJ |
208 | } |
209 | #endif | |
210 | ||
47fa50b1 | 211 | #if NMBA > 0 |
327f6ec8 BJ |
212 | /* |
213 | * Find devices attached to a particular mba | |
214 | * and look for each device found in the massbus | |
215 | * initialization tables. | |
216 | */ | |
3f3a34c3 | 217 | mbafind(nxv, nxp) |
30d13fef | 218 | struct nexus *nxv, *nxp; |
327f6ec8 BJ |
219 | { |
220 | register struct mba_regs *mdp; | |
221 | register struct mba_drv *mbd; | |
222 | int dn, dt, sn, ds; | |
223 | struct mba_info fnd; | |
224 | ||
3f3a34c3 | 225 | mdp = (struct mba_regs *)nxv; |
5aa9d5ea RE |
226 | mba_hd[nummba].mh_mba = mdp; |
227 | mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp; | |
228 | setscbnex(nexnum, mbaintv[nummba]); | |
327f6ec8 | 229 | fnd.mi_mba = mdp; |
5aa9d5ea | 230 | fnd.mi_mbanum = nummba; |
327f6ec8 BJ |
231 | for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) { |
232 | dt = mbd->mbd_dt & 0xffff; | |
233 | if (dt == 0) | |
234 | continue; | |
327f6ec8 BJ |
235 | if ((dt&MBDT_TYPE) == MBDT_TU78) { |
236 | printf("tm04/tu78 unsupported\n"); | |
237 | continue; | |
238 | } | |
239 | if (dt == MBDT_MOH) | |
240 | continue; | |
241 | fnd.mi_drive = dn; | |
242 | if (dt & MBDT_TAP) { | |
243 | for (sn = 0; sn < 8; sn++) { | |
244 | mbd->mbd_tc = sn; | |
245 | dt = mbd->mbd_dt; | |
246 | if ((dt & MBDT_SPR) == 0) | |
247 | continue; | |
248 | dt &= MBDT_TYPE; | |
249 | fnd.mi_slave = sn; | |
250 | mbaconfig(&fnd, dt); | |
251 | } | |
252 | } else { | |
253 | fnd.mi_slave = -1; | |
254 | mbaconfig(&fnd, dt&MBDT_TYPE); | |
255 | } | |
256 | } | |
3f3a34c3 BJ |
257 | mdp->mba_cr = MBAINIT; |
258 | mdp->mba_cr = MBAIE; | |
327f6ec8 BJ |
259 | } |
260 | ||
261 | /* | |
262 | * Have found a massbus device; | |
263 | * see if it is in the configuration table. | |
264 | * If so, fill in its data. | |
265 | */ | |
266 | mbaconfig(ni, type) | |
267 | register struct mba_info *ni; | |
268 | register int type; | |
269 | { | |
270 | register struct mba_info *mi; | |
271 | register short *tp; | |
71236e46 | 272 | register struct mba_hd *mh; |
327f6ec8 | 273 | |
327f6ec8 BJ |
274 | for (mi = mbinit; mi->mi_driver; mi++) { |
275 | if (mi->mi_alive) | |
276 | continue; | |
277 | tp = mi->mi_driver->md_type; | |
278 | for (mi->mi_type = 0; *tp; tp++, mi->mi_type++) | |
279 | if (*tp == type) | |
280 | goto found; | |
281 | continue; | |
282 | found: | |
283 | #define match(fld) (ni->fld == mi->fld || mi->fld == '?') | |
284 | if (!match(mi_slave) || !match(mi_drive) || !match(mi_mbanum)) | |
285 | continue; | |
8d2ea14f BJ |
286 | printf("%c%d at mba%d drive %d\n", |
287 | mi->mi_name, mi->mi_unit, ni->mi_mbanum, ni->mi_drive); | |
327f6ec8 | 288 | mi->mi_alive = 1; |
71236e46 BJ |
289 | mh = &mba_hd[ni->mi_mbanum]; |
290 | mi->mi_hd = mh; | |
291 | mh->mh_mbip[ni->mi_drive] = mi; | |
292 | mh->mh_ndrive++; | |
327f6ec8 BJ |
293 | mi->mi_mba = ni->mi_mba; |
294 | mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive]; | |
295 | mi->mi_driver->md_info[mi->mi_unit] = mi; | |
296 | mi->mi_mbanum = ni->mi_mbanum; | |
297 | mi->mi_drive = ni->mi_drive; | |
298 | mi->mi_slave = ni->mi_slave; | |
8d2ea14f BJ |
299 | if (mi->mi_dk && dkn < DK_NDRIVE) |
300 | mi->mi_dk = dkn++; | |
301 | else | |
302 | mi->mi_dk = -1; | |
71236e46 | 303 | (*mi->mi_driver->md_dkinit)(mi); |
327f6ec8 BJ |
304 | } |
305 | } | |
47fa50b1 | 306 | #endif |
327f6ec8 | 307 | |
3f3a34c3 | 308 | /* |
30d13fef BJ |
309 | * Fixctlrmask fixes the masks of the driver ctlr routines |
310 | * which otherwise save r10 and r11 where the interrupt and br | |
311 | * level are passed through. | |
312 | */ | |
313 | fixctlrmask() | |
314 | { | |
315 | register struct uba_minfo *um; | |
316 | register struct uba_dinfo *ui; | |
317 | register struct uba_driver *ud; | |
318 | #define phys(a,b) ((b)(((int)(a))&0x7fffffff)) | |
319 | ||
320 | for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++) | |
71236e46 | 321 | *phys(ud->ud_probe, short *) &= ~0xc00; |
30d13fef | 322 | for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++) |
71236e46 | 323 | *phys(ud->ud_probe, short *) &= ~0xc00; |
30d13fef BJ |
324 | } |
325 | ||
326 | /* | |
327 | * Find devices on a UNIBUS. | |
328 | * Uses per-driver routine to set <br,cvec> into <r11,r10>, | |
329 | * and then fills in the tables, with help from a per-driver | |
330 | * slave initialization routine. | |
3f3a34c3 | 331 | */ |
30d13fef BJ |
332 | unifind(vubp, pubp, vumem, pumem) |
333 | struct uba_regs *vubp, *pubp; | |
334 | caddr_t vumem, pumem; | |
327f6ec8 | 335 | { |
30d13fef | 336 | register int br, cvec; /* MUST BE r11, r10 */ |
3f3a34c3 | 337 | register struct uba_dinfo *ui; |
30d13fef BJ |
338 | register struct uba_minfo *um; |
339 | u_short *umem = (u_short *)vumem, *sp, *reg, addr; | |
340 | struct uba_hd *uhp; | |
327f6ec8 | 341 | struct uba_driver *udp; |
8d2ea14f | 342 | int i, (**ivec)(), haveubasr = 0; |
30d13fef BJ |
343 | |
344 | /* | |
345 | * Initialize the UNIBUS, by freeing the map | |
346 | * registers and the buffered data path registers | |
347 | */ | |
348 | uhp = &uba_hd[numuba]; | |
349 | uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map)); | |
350 | mfree(uhp->uh_map, NUBMREG, 1); | |
351 | switch (cpu) { | |
352 | #if VAX780 | |
353 | case VAX_780: | |
8d2ea14f BJ |
354 | uhp->uh_bdpfree = (1<<NBDP780) - 1; |
355 | haveubasr = 1; | |
30d13fef BJ |
356 | break; |
357 | #endif | |
358 | #if VAX750 | |
359 | case VAX_750: | |
8d2ea14f | 360 | uhp->uh_bdpfree = (1<<NBDP750) - 1; |
30d13fef BJ |
361 | break; |
362 | #endif | |
363 | } | |
327f6ec8 | 364 | |
30d13fef BJ |
365 | /* |
366 | * Save virtual and physical addresses | |
367 | * of adaptor, and allocate and initialize | |
368 | * the UNIBUS interrupt vector. | |
369 | */ | |
370 | uhp->uh_uba = vubp; | |
371 | uhp->uh_physuba = pubp; | |
372 | if (numuba == 0) | |
373 | uhp->uh_vec = UNIvec; | |
374 | else | |
375 | uhp->uh_vec = (int(**)())calloc(512); | |
376 | for (i = 0; i < 128; i++) | |
377 | uhp->uh_vec[i] = | |
378 | scbentry(&catcher[i*2], SCB_ISTACK); | |
379 | nxaccess((struct nexus *)pumem, UMEMmap[numuba]); | |
3f3a34c3 | 380 | #if VAX780 |
8d2ea14f | 381 | if (haveubasr) { |
30d13fef | 382 | vubp->uba_sr = vubp->uba_sr; |
8d2ea14f | 383 | vubp->uba_cr = UBA_IFS|UBA_BRIE; |
327f6ec8 | 384 | } |
327f6ec8 | 385 | #endif |
30d13fef BJ |
386 | /* |
387 | * Map the first page of UNIBUS i/o | |
388 | * space to the first page of memory | |
389 | * for devices which will need to dma | |
390 | * output to produce an interrupt. | |
391 | */ | |
392 | *(int *)(&vubp->uba_map[0]) = UBA_MRV; | |
393 | ||
394 | #define ubaddr(off) (u_short *)((int)vumem + ((off)&0x1fff)) | |
395 | /* | |
396 | * Check each unibus mass storage controller. | |
397 | * For each one which is potentially on this uba, | |
398 | * see if it is really there, and if it is record it and | |
399 | * then go looking for slaves. | |
400 | */ | |
401 | for (um = ubminit; udp = um->um_driver; um++) { | |
402 | if (um->um_ubanum != numuba && um->um_ubanum != '?') | |
403 | continue; | |
404 | addr = (u_short)um->um_addr; | |
405 | reg = ubaddr(addr); | |
406 | if (badaddr((caddr_t)reg, 2)) | |
327f6ec8 | 407 | continue; |
3f3a34c3 | 408 | #if VAX780 |
8d2ea14f BJ |
409 | if (haveubasr && vubp->uba_sr) { |
410 | vubp->uba_sr = vubp->uba_sr; | |
411 | continue; | |
30d13fef | 412 | } |
327f6ec8 | 413 | #endif |
30d13fef | 414 | cvec = 0x200; |
71236e46 | 415 | i = (*udp->ud_probe)(reg); |
3f3a34c3 | 416 | #if VAX780 |
8d2ea14f BJ |
417 | if (haveubasr && vubp->uba_sr) { |
418 | vubp->uba_sr = vubp->uba_sr; | |
419 | continue; | |
30d13fef | 420 | } |
327f6ec8 | 421 | #endif |
30d13fef BJ |
422 | if (i == 0) |
423 | continue; | |
8d2ea14f BJ |
424 | printf("%s%d at uba%d csr %o ", |
425 | udp->ud_mname, um->um_ctlr, numuba, addr); | |
30d13fef BJ |
426 | if (cvec == 0) { |
427 | printf("zero vector\n"); | |
428 | continue; | |
429 | } | |
430 | if (cvec == 0x200) { | |
431 | printf("didn't interrupt\n"); | |
432 | continue; | |
433 | } | |
8d2ea14f | 434 | printf("vec %o, ipl %x\n", cvec, br); |
30d13fef BJ |
435 | um->um_alive = 1; |
436 | um->um_ubanum = numuba; | |
437 | um->um_hd = &uba_hd[numuba]; | |
438 | um->um_addr = (caddr_t)reg; | |
439 | udp->ud_minfo[um->um_ctlr] = um; | |
440 | for (ivec = um->um_intr; *ivec; ivec++) { | |
441 | um->um_hd->uh_vec[cvec/4] = | |
442 | scbentry(*ivec, SCB_ISTACK); | |
443 | cvec += 4; | |
444 | } | |
445 | for (ui = ubdinit; ui->ui_driver; ui++) { | |
446 | if (ui->ui_driver != udp || ui->ui_alive || | |
447 | ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' || | |
448 | ui->ui_ubanum != numuba && ui->ui_ubanum != '?') | |
327f6ec8 | 449 | continue; |
8d2ea14f | 450 | if ((*udp->ud_slave)(ui, reg)) { |
30d13fef BJ |
451 | ui->ui_alive = 1; |
452 | ui->ui_ctlr = um->um_ctlr; | |
453 | ui->ui_ubanum = numuba; | |
454 | ui->ui_hd = &uba_hd[numuba]; | |
455 | ui->ui_addr = (caddr_t)reg; | |
456 | ui->ui_physaddr = pumem + (addr&0x1fff); | |
8d2ea14f | 457 | if (ui->ui_dk && dkn < DK_NDRIVE) |
0801d37f | 458 | ui->ui_dk = dkn++; |
8d2ea14f BJ |
459 | else |
460 | ui->ui_dk = -1; | |
30d13fef BJ |
461 | ui->ui_mi = um; |
462 | /* ui_type comes from driver */ | |
463 | udp->ud_dinfo[ui->ui_unit] = ui; | |
8d2ea14f BJ |
464 | printf("%s%d at %s%d slave %d\n", |
465 | udp->ud_dname, ui->ui_unit, | |
466 | udp->ud_mname, um->um_ctlr, ui->ui_slave); | |
71236e46 | 467 | (*udp->ud_attach)(ui); |
327f6ec8 | 468 | } |
30d13fef BJ |
469 | } |
470 | } | |
471 | /* | |
472 | * Now look for non-mass storage peripherals. | |
473 | */ | |
474 | for (ui = ubdinit; udp = ui->ui_driver; ui++) { | |
475 | if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' || | |
476 | ui->ui_alive || ui->ui_slave != -1) | |
477 | continue; | |
478 | addr = (u_short)ui->ui_addr; | |
479 | reg = ubaddr(addr); | |
480 | if (badaddr((caddr_t)reg, 2)) | |
481 | continue; | |
482 | #if VAX780 | |
8d2ea14f BJ |
483 | if (haveubasr && vubp->uba_sr) { |
484 | vubp->uba_sr = vubp->uba_sr; | |
485 | continue; | |
30d13fef BJ |
486 | } |
487 | #endif | |
488 | cvec = 0x200; | |
71236e46 | 489 | i = (*udp->ud_probe)(reg); |
30d13fef | 490 | #if VAX780 |
8d2ea14f BJ |
491 | if (haveubasr && vubp->uba_sr) { |
492 | vubp->uba_sr = vubp->uba_sr; | |
493 | continue; | |
327f6ec8 | 494 | } |
30d13fef BJ |
495 | #endif |
496 | if (i == 0) | |
497 | continue; | |
8d2ea14f BJ |
498 | printf("%s%d at uba%d csr %o ", |
499 | ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr); | |
30d13fef BJ |
500 | if (cvec == 0) { |
501 | printf("zero vector\n"); | |
502 | continue; | |
503 | } | |
504 | if (cvec == 0x200) { | |
505 | printf("didn't interrupt\n"); | |
506 | continue; | |
507 | } | |
8d2ea14f | 508 | printf("vec %o, ipl %x\n", cvec, br); |
30d13fef BJ |
509 | ui->ui_hd = &uba_hd[numuba]; |
510 | for (ivec = ui->ui_intr; *ivec; ivec++) { | |
511 | ui->ui_hd->uh_vec[cvec/4] = | |
512 | scbentry(*ivec, SCB_ISTACK); | |
513 | cvec += 4; | |
514 | } | |
515 | ui->ui_alive = 1; | |
516 | ui->ui_ubanum = numuba; | |
517 | ui->ui_addr = (caddr_t)reg; | |
518 | ui->ui_physaddr = pumem + (addr&0x1fff); | |
8d2ea14f | 519 | ui->ui_dk = -1; |
30d13fef BJ |
520 | /* ui_type comes from driver */ |
521 | udp->ud_dinfo[ui->ui_unit] = ui; | |
71236e46 | 522 | (*udp->ud_attach)(ui); |
327f6ec8 BJ |
523 | } |
524 | } | |
525 | ||
327f6ec8 | 526 | setscbnex(nexnum, fn) |
8d2ea14f | 527 | int nexnum, (*fn)(); |
327f6ec8 | 528 | { |
71236e46 | 529 | register struct scb *scbp = &scb; |
327f6ec8 | 530 | |
71236e46 BJ |
531 | scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] = |
532 | scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] = | |
327f6ec8 BJ |
533 | scbentry(fn, SCB_ISTACK); |
534 | } | |
535 | ||
536 | /* | |
537 | * Make a nexus accessible at physical address phys | |
538 | * by mapping kernel ptes starting at pte. | |
539 | * | |
540 | * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE | |
541 | * SINCE MISSING NEXI DONT RESPOND. BUT THEN AGAIN | |
542 | * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE. | |
543 | */ | |
30d13fef BJ |
544 | nxaccess(physa, pte) |
545 | caddr_t physa; | |
327f6ec8 BJ |
546 | register struct pte *pte; |
547 | { | |
548 | register int cnt = btop(sizeof (struct nexus)); | |
30d13fef | 549 | register unsigned v = btop(physa); |
327f6ec8 BJ |
550 | |
551 | do | |
552 | *(int *)pte++ = PG_V|PG_KW|v++; | |
553 | while (--cnt > 0); | |
554 | mtpr(TBIA, 0); | |
555 | } |