fixups just pre lint
[unix-history] / usr / src / sys / vax / vax / autoconf.c
CommitLineData
d565635a 1/* autoconf.c 4.24 81/03/08 */
327f6ec8 2
327f6ec8 3/*
d565635a
BJ
4 * Setup the system to run on the current machine.
5 *
6 * Configure() is called at boot time and initializes the uba and mba
7 * device tables and the memory controller monitoring. Available
8 * devices are determined (from possibilities mentioned in ioconf.c),
9 * and the drivers are initialized.
10 *
11 * N.B.: A lot of the conditionals based on processor type say
12 * #if VAX780
13 * and
14 * #if VAX750
15 * which may be incorrect after more processors are introduced if they
16 * are like either of these machines. Thus the exact form of these
17 * lines may change. Will future machines have configuration registers
18 * in the adapters and probable nexus space (like the 780), or wired
19 * addresses (like the 750)? It remains to be seen.
327f6ec8
BJ
20 */
21
47fa50b1
BJ
22#include "mba.h"
23
327f6ec8 24#include "../h/param.h"
3f3a34c3 25#include "../h/systm.h"
327f6ec8
BJ
26#include "../h/map.h"
27#include "../h/nexus.h"
28#include "../h/pte.h"
29#include "../h/buf.h"
b721b0ed
BJ
30#include "../h/mbareg.h"
31#include "../h/mbavar.h"
8d2ea14f
BJ
32#include "../h/dk.h"
33#include "../h/vm.h"
b721b0ed
BJ
34#include "../h/ubareg.h"
35#include "../h/ubavar.h"
327f6ec8
BJ
36#include "../h/mtpr.h"
37#include "../h/cpu.h"
38#include "../h/scb.h"
3f3a34c3 39#include "../h/mem.h"
327f6ec8 40
d565635a
BJ
41/*
42 * The following several variables are related to
43 * the configuration process, and are used in initializing
44 * the machine.
45 */
46int cold; /* if 1, still working on cold-start */
327f6ec8 47int nexnum; /* current nexus number */
d565635a 48int dkn; /* number of iostat dk numbers assigned so far */
327f6ec8 49
d565635a
BJ
50/*
51 * Addresses of the (locore) routines which bootstrap us from
52 * hardware traps to C code. Filled into the system control block
53 * as necessary.
54 */
47fa50b1 55#if NMBA > 0
8d2ea14f 56int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
47fa50b1 57#endif
5aa9d5ea 58#if VAX780
8d2ea14f 59int (*ubaintv[4])() = { Xua0int, Xua1int, Xua2int, Xua3int };
d565635a
BJ
60/*
61 * These are the (fixed) addresses of the (last 8k bytes of) unibus memory for
62 * each of the 4 possible unibus adapters. Note that the unibus memory
63 * addresses are actually indexed by the unibus adapter type code,
64 * and are unrelated to tr (nexus) number.
65 */
5aa9d5ea 66caddr_t umaddr780[4] = {
30d13fef
BJ
67 (caddr_t) 0x2013e000, (caddr_t) 0x2017e000,
68 (caddr_t) 0x201be000, (caddr_t) 0x201fe000
3f3a34c3 69};
5aa9d5ea 70#endif
d565635a
BJ
71
72/*
73 * This allocates the space for the per-uba information,
74 * such as buffered data path usage.
75 */
b721b0ed 76struct uba_hd uba_hd[MAXNUBA];
327f6ec8 77
d565635a
BJ
78/*
79 * The bits which decode the fault bits in the configuration register
80 * of nexus's are reusable per nexus-type, so we declare them once here
81 * to avoid replication.
82 */
295446f8
BJ
83#if VAX780
84char nexflt_bits[] = NEXFLT_BITS;
85#endif
86
d565635a
BJ
87/*
88 * Per-processor type initialization routines and data.
89 * It would be nice to parameterize initialization more,
90 * but the 780 and 750 are really quite different at this
91 * level. We await future machines before attempting
92 * any significant parameterization.
93 */
47fa50b1
BJ
94#if VAX780
95int c780();
96#endif
97#if VAX750
98int c750();
99#endif
3f3a34c3
BJ
100
101struct percpu percpu[] = {
102#if VAX780
30d13fef 103 c780, VAX_780,
3f3a34c3
BJ
104#endif
105#if VAX750
30d13fef 106 c750, VAX_750,
3f3a34c3
BJ
107#endif
108};
109#define NCPU (sizeof(percpu)/sizeof(struct percpu))
110
327f6ec8
BJ
111/*
112 * Determine mass storage and memory configuration for a machine.
113 * Get cpu type, and then switch out to machine specific procedures
114 * which will probe adaptors to see what is out there.
115 */
116configure()
117{
118 union cpusid cpusid;
3f3a34c3 119 register struct percpu *ocp;
3e7ee2db
BJ
120 register int i, *ip;
121 extern char Sysbase[];
327f6ec8
BJ
122
123 cpusid.cpusid = mfpr(SID);
3f3a34c3
BJ
124 for (ocp = percpu; ocp < &percpu[NCPU]; ocp++)
125 if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
3f3a34c3 126 (*ocp->pc_config)(ocp);
d565635a
BJ
127 /*
128 * Write protect the scb. It is strange
129 * that this code is here, but this is as soon
130 * as we are done mucking with it, and the
131 * write-enable was done in assembly language
132 * to which we will never return.
133 */
3e7ee2db
BJ
134 ip = (int *)Sysmap; *ip &= ~PG_PROT; *ip |= PG_KR;
135 mtpr(TBIS, Sysbase);
d565635a
BJ
136#if GENERIC
137 setconf();
138#endif
8d2ea14f 139 cold = 0;
c9e9b65b 140 memenable();
3f3a34c3
BJ
141 return;
142 }
d565635a 143 printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
327f6ec8
BJ
144 asm("halt");
145}
146
3f3a34c3 147#if VAX780
327f6ec8
BJ
148/*
149 * Build configuration table for a 780, by looking
150 * at the things (mbas and ubas) in the nexus slots
151 * and initialzing each appropriately.
152 */
3f3a34c3
BJ
153c780(pcpu)
154 register struct percpu *pcpu;
327f6ec8
BJ
155{
156 register struct nexus *nxv;
5aa9d5ea 157 register struct uba_hd *uhp;
30d13fef 158 struct nexus *nxp = NEX780;
327f6ec8 159 union nexcsr nexcsr;
3cda891a 160 int i, ubawatch();
327f6ec8 161
30d13fef 162 for (nexnum = 0,nxv = nexus; nexnum < NNEX780; nexnum++,nxp++,nxv++) {
327f6ec8
BJ
163 nxaccess((caddr_t)nxp, Nexmap[nexnum]);
164 if (badaddr((caddr_t)nxv, 4))
165 continue;
166 nexcsr = nxv->nexcsr;
167 if (nexcsr.nex_csr&NEX_APD)
168 continue;
327f6ec8
BJ
169 switch (nexcsr.nex_type) {
170
171 case NEX_MBA:
8d2ea14f 172 printf("mba%d at tr%d\n", nummba, nexnum);
a7e7fa7e 173 if (nummba >= NMBA) {
d565635a
BJ
174 printf("%d mba's", nummba);
175 goto notconfig;
a7e7fa7e 176 }
d565635a 177#if NMBA > 0
3f3a34c3 178 mbafind(nxv, nxp);
5aa9d5ea 179 nummba++;
47fa50b1 180#endif
d565635a 181 break;
327f6ec8
BJ
182
183 case NEX_UBA0:
184 case NEX_UBA1:
185 case NEX_UBA2:
186 case NEX_UBA3:
d565635a 187 printf("uba%d at tr%d\n", numuba, nexnum);
30d13fef
BJ
188 if (numuba >= 4) {
189 printf("5 uba's");
3f3a34c3
BJ
190 goto unsupp;
191 }
8d2ea14f 192 setscbnex(nexnum, ubaintv[numuba]);
3f3a34c3 193 i = nexcsr.nex_type - NEX_UBA0;
30d13fef
BJ
194 unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
195 umem[i], umaddr780[i]);
30d13fef 196 ((struct uba_regs *)nxv)->uba_cr =
b721b0ed 197 UBACR_IFS|UBACR_BRIE|UBACR_USEFIE|UBACR_SUEFIE;
3f3a34c3 198 numuba++;
327f6ec8
BJ
199 break;
200
201 case NEX_DR32:
5aa9d5ea 202 /* there can be more than one... are there other codes??? */
327f6ec8
BJ
203 printf("dr32");
204 goto unsupp;
205
206 case NEX_MEM4:
207 case NEX_MEM4I:
208 case NEX_MEM16:
209 case NEX_MEM16I:
d565635a 210 printf("mcr%d at tr%d\n", nmcr, nexnum);
30d13fef 211 if (nmcr >= 4) {
d565635a 212 printf("5 mcr's");
3f3a34c3
BJ
213 goto unsupp;
214 }
215 mcraddr[nmcr++] = (struct mcr *)nxv;
327f6ec8
BJ
216 break;
217
218 case NEX_MPM0:
219 case NEX_MPM1:
220 case NEX_MPM2:
221 case NEX_MPM3:
222 printf("mpm");
223 goto unsupp;
224
225 default:
226 printf("nexus type %x", nexcsr.nex_type);
30d13fef 227unsupp:
3f3a34c3 228 printf(" unsupported (at tr %d)\n", nexnum);
327f6ec8 229 continue;
d565635a
BJ
230unconfig:
231 printf(" not configured\n");
232 continue;
327f6ec8
BJ
233 }
234 }
ef52fe82 235 timeout(ubawatch, 0, hz);
327f6ec8
BJ
236}
237#endif
238
30d13fef
BJ
239#if VAX750
240/*
241 * Configure a 750. There are four possible mba's,
242 * one standard UNIBUS, and a memory controller.
243 */
244c750(pcpu)
245 struct percpu *pcpu;
246{
247 register struct nexus *nxv = nexus;
248 struct nexus *nxp = NEX750;
249
3e7ee2db
BJ
250 printf("mcr at %x\n", MCR_750);
251 nxaccess((caddr_t)MCR_750, Nexmap[nexnum]);
47fa50b1 252 mcraddr[nmcr++] = (struct mcr *)nxv;
30d13fef
BJ
253 for (nexnum = 0; nexnum < NNEX750; nexnum++, nxp++, nxv++) {
254 nxaccess((caddr_t)nxp, Nexmap[nexnum]);
255 if (badaddr((caddr_t)nxv, 4))
256 continue;
3e7ee2db 257 printf("mba%d at %x\n", nummba, nxp);
d565635a
BJ
258 if (nummba >= NMBA) {
259 printf("%d mba(s) not configured\n", nummba+1);
260 continue;
a7e7fa7e 261 }
d565635a
BJ
262#if NMBA > 0
263 mbafind(nxv, nxp);
264 nummba++;
47fa50b1 265#endif
d565635a 266 }
3e7ee2db 267 printf("uba at %x\n", nxp);
30d13fef 268 nxaccess((caddr_t)nxp, Nexmap[nexnum++]);
d565635a 269 unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
8d2ea14f 270 umem[0], UMEM750);
30d13fef 271 numuba = 1;
30d13fef
BJ
272}
273#endif
274
47fa50b1 275#if NMBA > 0
b721b0ed 276struct mba_device *mbaconfig();
327f6ec8
BJ
277/*
278 * Find devices attached to a particular mba
279 * and look for each device found in the massbus
280 * initialization tables.
281 */
3f3a34c3 282mbafind(nxv, nxp)
30d13fef 283 struct nexus *nxv, *nxp;
327f6ec8
BJ
284{
285 register struct mba_regs *mdp;
286 register struct mba_drv *mbd;
b721b0ed
BJ
287 register struct mba_device *mi;
288 register struct mba_slave *ms;
327f6ec8 289 int dn, dt, sn, ds;
b721b0ed 290 struct mba_device fnd;
327f6ec8 291
3f3a34c3 292 mdp = (struct mba_regs *)nxv;
5aa9d5ea
RE
293 mba_hd[nummba].mh_mba = mdp;
294 mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
295 setscbnex(nexnum, mbaintv[nummba]);
327f6ec8 296 fnd.mi_mba = mdp;
5aa9d5ea 297 fnd.mi_mbanum = nummba;
327f6ec8
BJ
298 for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
299 dt = mbd->mbd_dt & 0xffff;
300 if (dt == 0)
301 continue;
327f6ec8
BJ
302 if ((dt&MBDT_TYPE) == MBDT_TU78) {
303 printf("tm04/tu78 unsupported\n");
304 continue;
305 }
306 if (dt == MBDT_MOH)
307 continue;
308 fnd.mi_drive = dn;
b721b0ed
BJ
309 if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) {
310 for (ms = mbsinit; ms->ms_driver; ms++)
311 if (ms->ms_driver == mi->mi_driver && ms->ms_alive == 0 &&
312 (ms->ms_ctlr == mi->mi_unit || ms->ms_ctlr=='?')) {
313 mbd->mbd_tc = ms->ms_slave;
327f6ec8 314 dt = mbd->mbd_dt;
b721b0ed
BJ
315 if (dt & MBDT_SPR) {
316 printf("%s%d at %s%d slave %d\n",
317 ms->ms_driver->md_sname,
318 ms->ms_unit,
319 mi->mi_driver->md_dname,
320 mi->mi_unit,
321 ms->ms_slave);
d565635a
BJ
322 ms->ms_alive = 1;
323 ms->ms_ctlr = mi->mi_unit;
b721b0ed
BJ
324 (*ms->ms_driver->md_slave)
325 (mi, ms);
326 }
327f6ec8 327 }
327f6ec8
BJ
328 }
329 }
3f3a34c3
BJ
330 mdp->mba_cr = MBAINIT;
331 mdp->mba_cr = MBAIE;
327f6ec8
BJ
332}
333
334/*
335 * Have found a massbus device;
336 * see if it is in the configuration table.
337 * If so, fill in its data.
338 */
b721b0ed 339struct mba_device *
327f6ec8 340mbaconfig(ni, type)
b721b0ed 341 register struct mba_device *ni;
327f6ec8
BJ
342 register int type;
343{
b721b0ed 344 register struct mba_device *mi;
327f6ec8 345 register short *tp;
71236e46 346 register struct mba_hd *mh;
327f6ec8 347
b721b0ed 348 for (mi = mbdinit; mi->mi_driver; mi++) {
327f6ec8
BJ
349 if (mi->mi_alive)
350 continue;
351 tp = mi->mi_driver->md_type;
352 for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
295446f8 353 if (*tp == (type&MBDT_TYPE))
327f6ec8
BJ
354 goto found;
355 continue;
356found:
357#define match(fld) (ni->fld == mi->fld || mi->fld == '?')
b721b0ed 358 if (!match(mi_drive) || !match(mi_mbanum))
327f6ec8 359 continue;
b721b0ed
BJ
360 printf("%s%d at mba%d drive %d",
361 mi->mi_driver->md_dname, mi->mi_unit,
362 ni->mi_mbanum, ni->mi_drive);
295446f8 363 printf("\n");
327f6ec8 364 mi->mi_alive = 1;
71236e46
BJ
365 mh = &mba_hd[ni->mi_mbanum];
366 mi->mi_hd = mh;
367 mh->mh_mbip[ni->mi_drive] = mi;
368 mh->mh_ndrive++;
327f6ec8
BJ
369 mi->mi_mba = ni->mi_mba;
370 mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
371 mi->mi_driver->md_info[mi->mi_unit] = mi;
372 mi->mi_mbanum = ni->mi_mbanum;
373 mi->mi_drive = ni->mi_drive;
8d2ea14f
BJ
374 if (mi->mi_dk && dkn < DK_NDRIVE)
375 mi->mi_dk = dkn++;
376 else
377 mi->mi_dk = -1;
b721b0ed
BJ
378 (*mi->mi_driver->md_attach)(mi);
379 return (mi);
327f6ec8 380 }
b721b0ed 381 return (0);
327f6ec8 382}
47fa50b1 383#endif
327f6ec8 384
3f3a34c3 385/*
30d13fef
BJ
386 * Fixctlrmask fixes the masks of the driver ctlr routines
387 * which otherwise save r10 and r11 where the interrupt and br
388 * level are passed through.
389 */
390fixctlrmask()
391{
b721b0ed
BJ
392 register struct uba_ctlr *um;
393 register struct uba_device *ui;
30d13fef
BJ
394 register struct uba_driver *ud;
395#define phys(a,b) ((b)(((int)(a))&0x7fffffff))
396
397 for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
71236e46 398 *phys(ud->ud_probe, short *) &= ~0xc00;
30d13fef 399 for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
71236e46 400 *phys(ud->ud_probe, short *) &= ~0xc00;
30d13fef
BJ
401}
402
403/*
404 * Find devices on a UNIBUS.
405 * Uses per-driver routine to set <br,cvec> into <r11,r10>,
406 * and then fills in the tables, with help from a per-driver
407 * slave initialization routine.
3f3a34c3 408 */
30d13fef
BJ
409unifind(vubp, pubp, vumem, pumem)
410 struct uba_regs *vubp, *pubp;
411 caddr_t vumem, pumem;
327f6ec8 412{
30d13fef 413 register int br, cvec; /* MUST BE r11, r10 */
b721b0ed
BJ
414 register struct uba_device *ui;
415 register struct uba_ctlr *um;
30d13fef
BJ
416 u_short *umem = (u_short *)vumem, *sp, *reg, addr;
417 struct uba_hd *uhp;
327f6ec8 418 struct uba_driver *udp;
8d2ea14f 419 int i, (**ivec)(), haveubasr = 0;
30d13fef
BJ
420
421 /*
422 * Initialize the UNIBUS, by freeing the map
423 * registers and the buffered data path registers
424 */
425 uhp = &uba_hd[numuba];
426 uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map));
c84ff1f9 427 rminit(uhp->uh_map, NUBMREG, 1, "uba", UAMSIZ);
30d13fef
BJ
428 switch (cpu) {
429#if VAX780
430 case VAX_780:
8d2ea14f
BJ
431 uhp->uh_bdpfree = (1<<NBDP780) - 1;
432 haveubasr = 1;
30d13fef
BJ
433 break;
434#endif
435#if VAX750
436 case VAX_750:
8d2ea14f 437 uhp->uh_bdpfree = (1<<NBDP750) - 1;
30d13fef
BJ
438 break;
439#endif
440 }
327f6ec8 441
30d13fef
BJ
442 /*
443 * Save virtual and physical addresses
444 * of adaptor, and allocate and initialize
445 * the UNIBUS interrupt vector.
446 */
447 uhp->uh_uba = vubp;
448 uhp->uh_physuba = pubp;
449 if (numuba == 0)
450 uhp->uh_vec = UNIvec;
451 else
452 uhp->uh_vec = (int(**)())calloc(512);
453 for (i = 0; i < 128; i++)
454 uhp->uh_vec[i] =
455 scbentry(&catcher[i*2], SCB_ISTACK);
456 nxaccess((struct nexus *)pumem, UMEMmap[numuba]);
3f3a34c3 457#if VAX780
8d2ea14f 458 if (haveubasr) {
30d13fef 459 vubp->uba_sr = vubp->uba_sr;
b721b0ed 460 vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
327f6ec8 461 }
327f6ec8 462#endif
30d13fef
BJ
463 /*
464 * Map the first page of UNIBUS i/o
465 * space to the first page of memory
466 * for devices which will need to dma
467 * output to produce an interrupt.
468 */
b721b0ed 469 *(int *)(&vubp->uba_map[0]) = UBAMR_MRV;
30d13fef
BJ
470
471#define ubaddr(off) (u_short *)((int)vumem + ((off)&0x1fff))
472 /*
473 * Check each unibus mass storage controller.
474 * For each one which is potentially on this uba,
475 * see if it is really there, and if it is record it and
476 * then go looking for slaves.
477 */
478 for (um = ubminit; udp = um->um_driver; um++) {
479 if (um->um_ubanum != numuba && um->um_ubanum != '?')
480 continue;
481 addr = (u_short)um->um_addr;
482 reg = ubaddr(addr);
483 if (badaddr((caddr_t)reg, 2))
327f6ec8 484 continue;
3f3a34c3 485#if VAX780
8d2ea14f
BJ
486 if (haveubasr && vubp->uba_sr) {
487 vubp->uba_sr = vubp->uba_sr;
488 continue;
30d13fef 489 }
327f6ec8 490#endif
30d13fef 491 cvec = 0x200;
71236e46 492 i = (*udp->ud_probe)(reg);
3f3a34c3 493#if VAX780
8d2ea14f
BJ
494 if (haveubasr && vubp->uba_sr) {
495 vubp->uba_sr = vubp->uba_sr;
496 continue;
30d13fef 497 }
327f6ec8 498#endif
30d13fef
BJ
499 if (i == 0)
500 continue;
8d2ea14f
BJ
501 printf("%s%d at uba%d csr %o ",
502 udp->ud_mname, um->um_ctlr, numuba, addr);
30d13fef
BJ
503 if (cvec == 0) {
504 printf("zero vector\n");
505 continue;
506 }
507 if (cvec == 0x200) {
508 printf("didn't interrupt\n");
509 continue;
510 }
8d2ea14f 511 printf("vec %o, ipl %x\n", cvec, br);
30d13fef
BJ
512 um->um_alive = 1;
513 um->um_ubanum = numuba;
514 um->um_hd = &uba_hd[numuba];
515 um->um_addr = (caddr_t)reg;
516 udp->ud_minfo[um->um_ctlr] = um;
517 for (ivec = um->um_intr; *ivec; ivec++) {
518 um->um_hd->uh_vec[cvec/4] =
519 scbentry(*ivec, SCB_ISTACK);
520 cvec += 4;
521 }
522 for (ui = ubdinit; ui->ui_driver; ui++) {
523 if (ui->ui_driver != udp || ui->ui_alive ||
524 ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
525 ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
327f6ec8 526 continue;
8d2ea14f 527 if ((*udp->ud_slave)(ui, reg)) {
30d13fef
BJ
528 ui->ui_alive = 1;
529 ui->ui_ctlr = um->um_ctlr;
530 ui->ui_ubanum = numuba;
531 ui->ui_hd = &uba_hd[numuba];
532 ui->ui_addr = (caddr_t)reg;
533 ui->ui_physaddr = pumem + (addr&0x1fff);
8d2ea14f 534 if (ui->ui_dk && dkn < DK_NDRIVE)
0801d37f 535 ui->ui_dk = dkn++;
8d2ea14f
BJ
536 else
537 ui->ui_dk = -1;
30d13fef
BJ
538 ui->ui_mi = um;
539 /* ui_type comes from driver */
540 udp->ud_dinfo[ui->ui_unit] = ui;
8d2ea14f
BJ
541 printf("%s%d at %s%d slave %d\n",
542 udp->ud_dname, ui->ui_unit,
543 udp->ud_mname, um->um_ctlr, ui->ui_slave);
71236e46 544 (*udp->ud_attach)(ui);
327f6ec8 545 }
30d13fef
BJ
546 }
547 }
548 /*
549 * Now look for non-mass storage peripherals.
550 */
551 for (ui = ubdinit; udp = ui->ui_driver; ui++) {
552 if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
553 ui->ui_alive || ui->ui_slave != -1)
554 continue;
555 addr = (u_short)ui->ui_addr;
556 reg = ubaddr(addr);
557 if (badaddr((caddr_t)reg, 2))
558 continue;
559#if VAX780
8d2ea14f
BJ
560 if (haveubasr && vubp->uba_sr) {
561 vubp->uba_sr = vubp->uba_sr;
562 continue;
30d13fef
BJ
563 }
564#endif
565 cvec = 0x200;
71236e46 566 i = (*udp->ud_probe)(reg);
30d13fef 567#if VAX780
8d2ea14f
BJ
568 if (haveubasr && vubp->uba_sr) {
569 vubp->uba_sr = vubp->uba_sr;
570 continue;
327f6ec8 571 }
30d13fef
BJ
572#endif
573 if (i == 0)
574 continue;
8d2ea14f
BJ
575 printf("%s%d at uba%d csr %o ",
576 ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
30d13fef
BJ
577 if (cvec == 0) {
578 printf("zero vector\n");
579 continue;
580 }
581 if (cvec == 0x200) {
582 printf("didn't interrupt\n");
583 continue;
584 }
8d2ea14f 585 printf("vec %o, ipl %x\n", cvec, br);
30d13fef
BJ
586 ui->ui_hd = &uba_hd[numuba];
587 for (ivec = ui->ui_intr; *ivec; ivec++) {
588 ui->ui_hd->uh_vec[cvec/4] =
589 scbentry(*ivec, SCB_ISTACK);
590 cvec += 4;
591 }
592 ui->ui_alive = 1;
593 ui->ui_ubanum = numuba;
594 ui->ui_addr = (caddr_t)reg;
595 ui->ui_physaddr = pumem + (addr&0x1fff);
8d2ea14f 596 ui->ui_dk = -1;
30d13fef
BJ
597 /* ui_type comes from driver */
598 udp->ud_dinfo[ui->ui_unit] = ui;
71236e46 599 (*udp->ud_attach)(ui);
327f6ec8
BJ
600 }
601}
602
327f6ec8 603setscbnex(nexnum, fn)
8d2ea14f 604 int nexnum, (*fn)();
327f6ec8 605{
71236e46 606 register struct scb *scbp = &scb;
327f6ec8 607
71236e46
BJ
608 scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
609 scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
327f6ec8
BJ
610 scbentry(fn, SCB_ISTACK);
611}
612
613/*
614 * Make a nexus accessible at physical address phys
615 * by mapping kernel ptes starting at pte.
616 *
617 * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE
618 * SINCE MISSING NEXI DONT RESPOND. BUT THEN AGAIN
619 * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE.
620 */
30d13fef
BJ
621nxaccess(physa, pte)
622 caddr_t physa;
327f6ec8
BJ
623 register struct pte *pte;
624{
625 register int cnt = btop(sizeof (struct nexus));
30d13fef 626 register unsigned v = btop(physa);
327f6ec8
BJ
627
628 do
629 *(int *)pte++ = PG_V|PG_KW|v++;
630 while (--cnt > 0);
631 mtpr(TBIA, 0);
632}