xref: /original-bsd/sys/vax/vax/autoconf.c (revision 64af1d24)
1 /*
2  * Copyright (c) 1982,1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)autoconf.c	6.26 (Berkeley) 05/27/86
7  */
8 
9 /*
10  * Setup the system to run on the current machine.
11  *
12  * Configure() is called at boot time and initializes the uba and mba
13  * device tables and the memory controller monitoring.  Available
14  * devices are determined (from possibilities mentioned in ioconf.c),
15  * and the drivers are initialized.
16  */
17 
18 #include "mba.h"
19 #include "uba.h"
20 
21 #include "pte.h"
22 
23 #include "param.h"
24 #include "systm.h"
25 #include "map.h"
26 #include "buf.h"
27 #include "dk.h"
28 #include "vm.h"
29 #include "conf.h"
30 #include "dmap.h"
31 #include "reboot.h"
32 
33 #include "cpu.h"
34 #include "mem.h"
35 #include "mtpr.h"
36 #include "nexus.h"
37 #include "scb.h"
38 #include "ioa.h"
39 #include "../vaxmba/mbareg.h"
40 #include "../vaxmba/mbavar.h"
41 #include "../vaxuba/ubareg.h"
42 #include "../vaxuba/ubavar.h"
43 
44 /*
45  * The following several variables are related to
46  * the configuration process, and are used in initializing
47  * the machine.
48  */
49 int	cold;		/* if 1, still working on cold-start */
50 int	nexnum;		/* current nexus number */
51 int	nsbi;		/* current sbi number */
52 int	dkn;		/* number of iostat dk numbers assigned so far */
53 int	cpuspeed = 1;	/* relative cpu speed */
54 
55 /*
56  * Addresses of the (locore) routines which bootstrap us from
57  * hardware traps to C code.  Filled into the system control block
58  * as necessary.
59  */
60 #if NMBA > 0
61 int	(*mbaintv[4])() =	{ Xmba0int, Xmba1int, Xmba2int, Xmba3int };
62 #if NMBA > 4
63 	Need to expand the table for more than 4 massbus adaptors
64 #endif
65 #endif
66 #if defined(VAX780) || defined(VAX8600)
67 int	(*ubaintv[])() =
68 {
69 	Xua0int, Xua1int, Xua2int, Xua3int,
70 #if NUBA > 4
71 	Xua4int, Xua5int, Xua6int, Xua7int,
72 #endif
73 #if NUBA > 8
74 	Need to expand the table for more than 8 unibus adaptors
75 #endif
76 };
77 #endif
78 
79 /*
80  * This allocates the space for the per-uba information,
81  * such as buffered data path usage.
82  */
83 struct	uba_hd uba_hd[NUBA];
84 
85 /*
86  * Determine mass storage and memory configuration for a machine.
87  * Get cpu type, and then switch out to machine specific procedures
88  * which will probe adaptors to see what is out there.
89  */
90 configure()
91 {
92 	union cpusid cpusid;
93 	register struct percpu *ocp;
94 	register int *ip;
95 	extern char Sysbase[];
96 
97 	cpusid.cpusid = mfpr(SID);
98 	for (ocp = percpu; ocp->pc_cputype; ocp++)
99 		if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
100 			cpuspeed = ocp->pc_cpuspeed;
101 			probeio(ocp);
102 			/*
103 			 * Write protect the scb and UNIBUS interrupt vectors.
104 			 * It is strange that this code is here, but this is
105 			 * as soon as we are done mucking with it, and the
106 			 * write-enable was done in assembly language
107 			 * to which we will never return.
108 			 */
109 			ip = (int *)Sysmap + 1; *ip &= ~PG_PROT; *ip |= PG_KR;
110 			ip++; *ip &= ~PG_PROT; *ip |= PG_KR;
111 #if NUBA > 1
112 			ip++; *ip &= ~PG_PROT; *ip |= PG_KR;
113 #endif
114 			mtpr(TBIS, Sysbase);
115 #if GENERIC
116 			if ((boothowto & RB_ASKNAME) || setroot() == 0)
117 				setconf();
118 #else
119 			(void) setroot();
120 #endif
121 			/*
122 			 * Configure swap area and related system
123 			 * parameter based on device(s) used.
124 			 */
125 			swapconf();
126 			cold = 0;
127 			memenable();
128 			return;
129 		}
130 	printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
131 	asm("halt");
132 }
133 
134 /*
135  * Probe the main IO bus(es).
136  * The percpu structure gives us a handle on the addresses and/or types.
137  */
138 probeio(pcpu)
139 	register struct percpu *pcpu;
140 {
141 	register struct iobus *iob;
142 	int ioanum;
143 
144 	ioanum = 0;
145 	for (iob = pcpu->pc_io; ioanum < pcpu->pc_nioa; ioanum++, iob++) {
146 
147 		switch (iob->io_type) {
148 
149 #if VAX780 || VAX750 || VAX730 || VAX630
150 		case IO_SBI780:
151 		case IO_CMI750:
152 		case IO_XXX730:
153 		case IO_QBUS:
154 			probenexi((struct nexusconnect *)iob->io_details);
155 			break;
156 #endif
157 
158 #if VAX8600
159 		case IO_ABUS:
160 			probe_Abus(ioanum, iob);
161 			break;
162 #endif
163 		default:
164 			if (iob->io_addr) {
165 			    printf(
166 		"IO adaptor %d, type %d, at address 0x%x is unsupported\n",
167 				ioanum, iob->io_type, iob->io_addr);
168 			} else
169 			    printf("IO adaptor %d, type %d, is unsupported\n",
170 				ioanum, iob->io_type);
171 			break;
172 		}
173 	}
174 }
175 
176 #if VAX8600
177 probe_Abus(ioanum, iob)
178 	register struct iobus *iob;
179 {
180 	register struct ioa *ioap;
181 	union ioacsr ioacsr;
182 	int type;
183 	struct sbia_regs *sbiaregs;
184 
185 	ioap = &ioa[ioanum];
186 	ioaccess(iob->io_addr, Ioamap[ioanum], iob->io_size);
187 	if (badaddr((caddr_t)ioap, 4))
188 		return;
189 	ioacsr.ioa_csr = ioap->ioacsr.ioa_csr;
190 	type = ioacsr.ioa_type & IOA_TYPMSK;
191 
192 	switch (type) {
193 
194 	case IOA_SBIA:
195 		printf("SBIA%d at IO adaptor %d address 0x%x\n",
196 		    nsbi, ioanum, iob->io_addr);
197 		probenexi((struct nexusconnect *)iob->io_details);
198 		nsbi++;
199 		sbiaregs = (struct sbia_regs *)ioap;
200 		sbiaregs->sbi_errsum = -1;
201 		sbiaregs->sbi_error = 0x1000;
202 		sbiaregs->sbi_fltsts = 0xc0000;
203 		break;
204 
205 	default:
206 		printf("IOA%d at address 0x%x is unsupported (type = 0x%x)\n",
207 		    ioanum, iob->io_addr, ioacsr.ioa_type);
208 		break;
209 	}
210 }
211 #endif
212 
213 /*
214  * Probe nexus space, finding the interconnects
215  * and setting up and probing mba's and uba's for devices.
216  */
217 /*ARGSUSED*/
218 probenexi(pnc)
219 	register struct nexusconnect *pnc;
220 {
221 	register struct nexus *nxv;
222 	struct nexus *nxp = pnc->psb_nexbase;
223 	union nexcsr nexcsr;
224 	int i;
225 
226 	nexnum = 0, nxv = &nexus[nsbi * NNEXSBI];
227 	for (; nexnum < pnc->psb_nnexus; nexnum++, nxp++, nxv++) {
228 		ioaccess((caddr_t)nxp, Nexmap[nsbi * NNEXSBI + nexnum],
229 		     sizeof(struct nexus));
230 		if (badaddr((caddr_t)nxv, 4))
231 			continue;
232 		if (pnc->psb_nextype && pnc->psb_nextype[nexnum] != NEX_ANY)
233 			nexcsr.nex_csr = pnc->psb_nextype[nexnum];
234 		else
235 			nexcsr = nxv->nexcsr;
236 		if (nexcsr.nex_csr&NEX_APD)
237 			continue;
238 		switch (nexcsr.nex_type) {
239 
240 		case NEX_MBA:
241 			printf("mba%d at tr%d\n", nummba, nexnum);
242 			if (nummba >= NMBA) {
243 				printf("%d mba's", nummba++);
244 				goto unconfig;
245 			}
246 #if NMBA > 0
247 			mbafind(nxv, nxp);
248 			nummba++;
249 #endif
250 			break;
251 
252 		case NEX_UBA0:
253 		case NEX_UBA1:
254 		case NEX_UBA2:
255 		case NEX_UBA3:
256 			printf("uba%d at tr%d\n", numuba, nexnum);
257 #if VAX750
258 			if (numuba >= 2 && cpu == VAX_750) {
259 				printf("More than 2 UBA's");
260 				goto unsupp;
261 			}
262 #endif
263 			if (numuba >= NUBA) {
264 				printf("%d uba's", ++numuba);
265 				goto unconfig;
266 			}
267 #if defined(VAX780) || defined(VAX8600)
268 			if ((cpu == VAX_780) || (cpu == VAX_8600))
269 				setscbnex(ubaintv[numuba]);
270 #endif
271 			i = nexcsr.nex_type - NEX_UBA0;
272 			unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
273 			    umem[numuba], pnc->psb_umaddr[i], UMEMmap[numuba],
274 			    pnc->psb_haveubasr);
275 #if defined(VAX780) || defined(VAX8600)
276 			if ((cpu == VAX_780) || (cpu == VAX_8600))
277 				((struct uba_regs *)nxv)->uba_cr =
278 				    UBACR_IFS|UBACR_BRIE|
279 				    UBACR_USEFIE|UBACR_SUEFIE|
280 				    (((struct uba_regs *)nxv)->uba_cr&0x7c000000);
281 #endif
282 			numuba++;
283 			break;
284 
285 		case NEX_DR32:
286 		/* there can be more than one... are there other codes??? */
287 			printf("dr32");
288 			goto unsupp;
289 
290 		case NEX_MEM4:
291 		case NEX_MEM4I:
292 		case NEX_MEM16:
293 		case NEX_MEM16I:
294 			printf("mcr%d at tr%d\n", nmcr, nexnum);
295 			if (nmcr >= 4) {
296 				printf("5 mcr's");
297 				goto unsupp;
298 			}
299 			switch (cpu) {
300 			case VAX_780:
301 				mcrtype[nmcr] = M780C;
302 				break;
303 			case VAX_750:
304 				mcrtype[nmcr] = M750;
305 				break;
306 			case VAX_730:
307 				mcrtype[nmcr] = M730;
308 				break;
309 			}
310 			mcraddr[nmcr++] = (struct mcr *)nxv;
311 			break;
312 
313 		case NEX_MEM64I:
314 		case NEX_MEM64L:
315 		case NEX_MEM64LI:
316 		case NEX_MEM256I:
317 		case NEX_MEM256L:
318 		case NEX_MEM256LI:
319 			printf("mcr%d (el) at tr%d\n", nmcr, nexnum);
320 			if (nmcr >= 4) {
321 				printf("5 mcr's");
322 				goto unsupp;
323 			}
324 			if (cpu == VAX_780)
325 				mcrtype[nmcr] = M780EL;
326 			mcraddr[nmcr++] = (struct mcr *)nxv;
327 			if (nexcsr.nex_type != NEX_MEM64I &&
328 			  nexcsr.nex_type != NEX_MEM256I)
329 				break;
330 			/* fall into ... */
331 
332 		case NEX_MEM64U:
333 		case NEX_MEM64UI:
334 		case NEX_MEM256U:
335 		case NEX_MEM256UI:
336 			printf("mcr%d (eu) at tr%d\n", nmcr, nexnum);
337 			if (nmcr >= 4) {
338 				printf("5 mcr's");
339 				goto unsupp;
340 			}
341 			if (cpu == VAX_780)
342 				mcrtype[nmcr] = M780EU;
343 			mcraddr[nmcr++] = (struct mcr *)nxv;
344 			break;
345 
346 		case NEX_MPM0:
347 		case NEX_MPM1:
348 		case NEX_MPM2:
349 		case NEX_MPM3:
350 			printf("mpm");
351 			goto unsupp;
352 
353 		case NEX_CI:
354 			printf("ci");
355 			goto unsupp;
356 
357 		default:
358 			printf("nexus type %x", nexcsr.nex_type);
359 unsupp:
360 			printf(" unsupported (at tr %d)\n", nexnum);
361 			continue;
362 unconfig:
363 			printf(" not configured\n");
364 			continue;
365 		}
366 	}
367 	if (nummba > NMBA)
368 		nummba = NMBA;
369 	if (numuba > NUBA)
370 		numuba = NUBA;
371 }
372 
373 #if NMBA > 0
374 struct	mba_device *mbaconfig();
375 /*
376  * Find devices attached to a particular mba
377  * and look for each device found in the massbus
378  * initialization tables.
379  */
380 mbafind(nxv, nxp)
381 	struct nexus *nxv, *nxp;
382 {
383 	register struct mba_regs *mdp;
384 	register struct mba_drv *mbd;
385 	register struct mba_device *mi;
386 	register struct mba_slave *ms;
387 	int dn, dt, sn;
388 	struct mba_device fnd;
389 
390 	mdp = (struct mba_regs *)nxv;
391 	mba_hd[nummba].mh_mba = mdp;
392 	mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
393 	setscbnex(mbaintv[nummba]);
394 	fnd.mi_mba = mdp;
395 	fnd.mi_mbanum = nummba;
396 	for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
397 		if ((mbd->mbd_ds&MBDS_DPR) == 0)
398 			continue;
399 		mdp->mba_sr |= MBSR_NED;		/* si kludge */
400 		dt = mbd->mbd_dt & 0xffff;
401 		if (dt == 0)
402 			continue;
403 		if (mdp->mba_sr&MBSR_NED)
404 			continue;			/* si kludge */
405 		if (dt == MBDT_MOH)
406 			continue;
407 		fnd.mi_drive = dn;
408 #define	qeq(a, b)	( a == b || a == '?' )
409 		if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP))
410 		    for (sn = 0; sn < 8; sn++) {
411 			mbd->mbd_tc = sn;
412 		        for (ms = mbsinit; ms->ms_driver; ms++)
413 			    if (ms->ms_driver == mi->mi_driver &&
414 				ms->ms_alive == 0 &&
415 				qeq(ms->ms_ctlr, mi->mi_unit) &&
416 				qeq(ms->ms_slave, sn) &&
417 				(*ms->ms_driver->md_slave)(mi, ms, sn)) {
418 					printf("%s%d at %s%d slave %d\n"
419 					    , ms->ms_driver->md_sname
420 					    , ms->ms_unit
421 					    , mi->mi_driver->md_dname
422 					    , mi->mi_unit
423 					    , sn
424 					);
425 					ms->ms_alive = 1;
426 					ms->ms_ctlr = mi->mi_unit;
427 					ms->ms_slave = sn;
428 				}
429 		    }
430 	}
431 	mdp->mba_cr = MBCR_INIT;
432 	mdp->mba_cr = MBCR_IE;
433 }
434 
435 /*
436  * Have found a massbus device;
437  * see if it is in the configuration table.
438  * If so, fill in its data.
439  */
440 struct mba_device *
441 mbaconfig(ni, type)
442 	register struct mba_device *ni;
443 	register int type;
444 {
445 	register struct mba_device *mi;
446 	register short *tp;
447 	register struct mba_hd *mh;
448 
449 	for (mi = mbdinit; mi->mi_driver; mi++) {
450 		if (mi->mi_alive)
451 			continue;
452 		tp = mi->mi_driver->md_type;
453 		for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
454 			if (*tp == (type&MBDT_TYPE))
455 				goto found;
456 		continue;
457 found:
458 #define	match(fld)	(ni->fld == mi->fld || mi->fld == '?')
459 		if (!match(mi_drive) || !match(mi_mbanum))
460 			continue;
461 		printf("%s%d at mba%d drive %d\n",
462 		    mi->mi_driver->md_dname, mi->mi_unit,
463 		    ni->mi_mbanum, ni->mi_drive);
464 		mi->mi_alive = 1;
465 		mh = &mba_hd[ni->mi_mbanum];
466 		mi->mi_hd = mh;
467 		mh->mh_mbip[ni->mi_drive] = mi;
468 		mh->mh_ndrive++;
469 		mi->mi_mba = ni->mi_mba;
470 		mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
471 		mi->mi_mbanum = ni->mi_mbanum;
472 		mi->mi_drive = ni->mi_drive;
473 		/*
474 		 * If drive has never been seen before,
475 		 * give it a dkn for statistics.
476 		 */
477 		if (mi->mi_driver->md_info[mi->mi_unit] == 0) {
478 			mi->mi_driver->md_info[mi->mi_unit] = mi;
479 			if (mi->mi_dk && dkn < DK_NDRIVE)
480 				mi->mi_dk = dkn++;
481 			else
482 				mi->mi_dk = -1;
483 		}
484 		(*mi->mi_driver->md_attach)(mi);
485 		return (mi);
486 	}
487 	return (0);
488 }
489 #endif
490 
491 /*
492  * Fixctlrmask fixes the masks of the driver ctlr routines
493  * which otherwise save r10 and r11 where the interrupt and br
494  * level are passed through.
495  */
496 fixctlrmask()
497 {
498 	register struct uba_ctlr *um;
499 	register struct uba_device *ui;
500 	register struct uba_driver *ud;
501 #define	phys(a,b) ((b)(((int)(a))&0x7fffffff))
502 
503 	for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
504 		*phys(ud->ud_probe, short *) &= ~0xc00;
505 	for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
506 		*phys(ud->ud_probe, short *) &= ~0xc00;
507 }
508 
509 /*
510  * Find devices on a UNIBUS.
511  * Uses per-driver routine to set <br,cvec> into <r11,r10>,
512  * and then fills in the tables, with help from a per-driver
513  * slave initialization routine.
514  */
515 unifind(vubp, pubp, vumem, pumem, memmap, haveubasr)
516 	struct uba_regs *vubp, *pubp;
517 	caddr_t vumem, pumem;
518 	struct pte *memmap;
519 	int haveubasr;
520 {
521 #ifndef lint
522 	register int br, cvec;			/* MUST BE r11, r10 */
523 #else
524 	/*
525 	 * Lint doesn't realize that these
526 	 * can be initialized asynchronously
527 	 * when devices interrupt.
528 	 */
529 	register int br = 0, cvec = 0;
530 #endif
531 	register struct uba_device *ui;
532 	register struct uba_ctlr *um;
533 	u_short *reg, *ap, addr;
534 	struct uba_hd *uhp;
535 	struct uba_driver *udp;
536 	int i, (**ivec)();
537 	caddr_t ualloc, zmemall();
538 	extern int catcher[256];
539 
540 #if VAX630
541 	/*
542 	 * The map registers start right at 20088000 on the
543 	 * ka630, so we have to subtract out the 2k offset to make the
544 	 * pointers work..
545 	 */
546 	if (cpu == VAX_630) {
547 		vubp = (struct uba_regs *)(((u_long)vubp)-0x800);
548 		pubp = (struct uba_regs *)(((u_long)pubp)-0x800);
549 	}
550 #endif
551 	/*
552 	 * Initialize the UNIBUS, by freeing the map
553 	 * registers and the buffered data path registers
554 	 */
555 	uhp = &uba_hd[numuba];
556 	uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map));
557 	ubainitmaps(uhp);
558 
559 	/*
560 	 * Save virtual and physical addresses
561 	 * of adaptor, and allocate and initialize
562 	 * the UNIBUS interrupt vector.
563 	 */
564 	uhp->uh_uba = vubp;
565 	uhp->uh_physuba = pubp;
566 	/*
567 	 * On the 8600, can't use UNIvec;
568 	 * the vectors for the second SBI overlap it.
569 	 */
570 	if (cpu == VAX_8600)
571 		uhp->uh_vec = (int(**)())calloc(512);
572 	else if (numuba == 0)
573 		uhp->uh_vec = UNIvec;
574 #if NUBA > 1
575 	else if (numuba == 1)
576 		uhp->uh_vec = UNI1vec;
577 	else
578 		uhp->uh_vec = (int(**)())calloc(512);
579 #endif
580 	for (i = 0; i < 128; i++)
581 		uhp->uh_vec[i] =
582 		    scbentry(&catcher[i*2], SCB_ISTACK);
583 	/*
584 	 * Set last free interrupt vector for devices with
585 	 * programmable interrupt vectors.  Use is to decrement
586 	 * this number and use result as interrupt vector.
587 	 */
588 	uhp->uh_lastiv = 0x200;
589 
590 #if VAX630
591 	/*
592 	 * Kludge time again. The q22 memory and device reg. address spaces
593 	 * are not physically contiguous, so we need 2 loops to map them
594 	 * into contiguous virtual space.
595 	 */
596 	if (cpu == VAX_630) {
597 		ioaccess(pumem, memmap, (UBAPAGES-16)*NBPG);
598 		ioaccess(0x20000000, memmap+(UBAPAGES-16), 16*NBPG);
599 	} else
600 #endif
601 		ioaccess(pumem, memmap, UBAPAGES * NBPG);
602 #if defined(VAX780) || defined(VAX8600)
603 	if (haveubasr) {
604 		vubp->uba_sr = vubp->uba_sr;
605 		vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
606 	}
607 #endif
608 	/*
609 	 * First configure devices that have unibus memory,
610 	 * allowing them to allocate the correct map registers.
611 	 */
612 	ubameminit(numuba);
613 	/*
614 	 * Grab some memory to record the umem address space we allocate,
615 	 * so we can be sure not to place two devices at the same address.
616 	 *
617 	 * We could use just 1/8 of this (we only want a 1 bit flag) but
618 	 * we are going to give it back anyway, and that would make the
619 	 * code here bigger (which we can't give back), so ...
620 	 *
621 	 * One day, someone will make a unibus with something other than
622 	 * an 8K i/o address space, & screw this totally.
623 	 */
624 	ualloc = zmemall(memall, 8*1024);
625 	if (ualloc == (caddr_t)0)
626 		panic("no mem for unifind");
627 
628 	/*
629 	 * Map the first page of UNIBUS i/o
630 	 * space to the first page of memory
631 	 * for devices which will need to dma
632 	 * output to produce an interrupt.
633 	 */
634 	*(int *)(&vubp->uba_map[0]) = UBAMR_MRV;
635 
636 #define	ubaoff(off)	((off)&0x1fff)
637 #define	ubaddr(off)	(u_short *)((int)vumem + (ubaoff(off)|0x3e000))
638 	/*
639 	 * Check each unibus mass storage controller.
640 	 * For each one which is potentially on this uba,
641 	 * see if it is really there, and if it is record it and
642 	 * then go looking for slaves.
643 	 */
644 	for (um = ubminit; udp = um->um_driver; um++) {
645 		if (um->um_ubanum != numuba && um->um_ubanum != '?')
646 			continue;
647 		addr = (u_short)um->um_addr;
648 		/*
649 		 * use the particular address specified first,
650 		 * or if it is given as "0", of there is no device
651 		 * at that address, try all the standard addresses
652 		 * in the driver til we find it
653 		 */
654 	    for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
655 
656 		if (ualloc[ubaoff(addr)])
657 			continue;
658 		reg = ubaddr(addr);
659 		if (badaddr((caddr_t)reg, 2))
660 			continue;
661 #if defined(VAX780) || defined(VAX8600)
662 		if (haveubasr && vubp->uba_sr) {
663 			vubp->uba_sr = vubp->uba_sr;
664 			continue;
665 		}
666 #endif
667 		cvec = 0x200;
668 		i = (*udp->ud_probe)(reg, um->um_ctlr, um);
669 #if defined(VAX780) || defined(VAX8600)
670 		if (haveubasr && vubp->uba_sr) {
671 			vubp->uba_sr = vubp->uba_sr;
672 			continue;
673 		}
674 #endif
675 		if (i == 0)
676 			continue;
677 		printf("%s%d at uba%d csr %o ",
678 		    udp->ud_mname, um->um_ctlr, numuba, addr);
679 		if (cvec == 0) {
680 			printf("zero vector\n");
681 			continue;
682 		}
683 		if (cvec == 0x200) {
684 			printf("didn't interrupt\n");
685 			continue;
686 		}
687 		printf("vec %o, ipl %x\n", cvec, br);
688 		um->um_alive = 1;
689 		um->um_ubanum = numuba;
690 		um->um_hd = &uba_hd[numuba];
691 		um->um_addr = (caddr_t)reg;
692 		udp->ud_minfo[um->um_ctlr] = um;
693 		for (ivec = um->um_intr; *ivec; ivec++) {
694 			um->um_hd->uh_vec[cvec/4] =
695 			    scbentry(*ivec, SCB_ISTACK);
696 			cvec += 4;
697 		}
698 		for (ui = ubdinit; ui->ui_driver; ui++) {
699 			if (ui->ui_driver != udp || ui->ui_alive ||
700 			    ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
701 			    ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
702 				continue;
703 			if ((*udp->ud_slave)(ui, reg)) {
704 				ui->ui_alive = 1;
705 				ui->ui_ctlr = um->um_ctlr;
706 				ui->ui_ubanum = numuba;
707 				ui->ui_hd = &uba_hd[numuba];
708 				ui->ui_addr = (caddr_t)reg;
709 				ui->ui_physaddr = pumem + ubdevreg(addr);
710 				if (ui->ui_dk && dkn < DK_NDRIVE)
711 					ui->ui_dk = dkn++;
712 				else
713 					ui->ui_dk = -1;
714 				ui->ui_mi = um;
715 				/* ui_type comes from driver */
716 				udp->ud_dinfo[ui->ui_unit] = ui;
717 				printf("%s%d at %s%d slave %d\n",
718 				    udp->ud_dname, ui->ui_unit,
719 				    udp->ud_mname, um->um_ctlr, ui->ui_slave);
720 				(*udp->ud_attach)(ui);
721 			}
722 		}
723 		break;
724 	    }
725 	}
726 	/*
727 	 * Now look for non-mass storage peripherals.
728 	 */
729 	for (ui = ubdinit; udp = ui->ui_driver; ui++) {
730 		if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
731 		    ui->ui_alive || ui->ui_slave != -1)
732 			continue;
733 		addr = (u_short)ui->ui_addr;
734 
735 	    for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
736 
737 		if (ualloc[ubaoff(addr)])
738 			continue;
739 		reg = ubaddr(addr);
740 		if (badaddr((caddr_t)reg, 2))
741 			continue;
742 #if defined(VAX780) || defined(VAX8600)
743 		if (haveubasr && vubp->uba_sr) {
744 			vubp->uba_sr = vubp->uba_sr;
745 			continue;
746 		}
747 #endif
748 		cvec = 0x200;
749 		i = (*udp->ud_probe)(reg, ui);
750 #if defined(VAX780) || defined(VAX8600)
751 		if (haveubasr && vubp->uba_sr) {
752 			vubp->uba_sr = vubp->uba_sr;
753 			continue;
754 		}
755 #endif
756 		if (i == 0)
757 			continue;
758 		printf("%s%d at uba%d csr %o ",
759 		    ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
760 		if (cvec == 0) {
761 			printf("zero vector\n");
762 			continue;
763 		}
764 		if (cvec == 0x200) {
765 			printf("didn't interrupt\n");
766 			continue;
767 		}
768 		printf("vec %o, ipl %x\n", cvec, br);
769 		while (--i >= 0)
770 			ualloc[ubaoff(addr+i)] = 1;
771 		ui->ui_hd = &uba_hd[numuba];
772 		for (ivec = ui->ui_intr; *ivec; ivec++) {
773 			ui->ui_hd->uh_vec[cvec/4] =
774 			    scbentry(*ivec, SCB_ISTACK);
775 			cvec += 4;
776 		}
777 		ui->ui_alive = 1;
778 		ui->ui_ubanum = numuba;
779 		ui->ui_addr = (caddr_t)reg;
780 		ui->ui_physaddr = pumem + ubdevreg(addr);
781 		ui->ui_dk = -1;
782 		/* ui_type comes from driver */
783 		udp->ud_dinfo[ui->ui_unit] = ui;
784 		(*udp->ud_attach)(ui);
785 		break;
786 	    }
787 	}
788 
789 #ifdef	AUTO_DEBUG
790 	printf("Unibus allocation map");
791 	for (i = 0; i < 8*1024; ) {
792 		register n, m;
793 
794 		if ((i % 128) == 0) {
795 			printf("\n%6o:", i);
796 			for (n = 0; n < 128; n++)
797 				if (ualloc[i+n])
798 					break;
799 			if (n == 128) {
800 				i += 128;
801 				continue;
802 			}
803 		}
804 
805 		for (n = m = 0; n < 16; n++) {
806 			m <<= 1;
807 			m |= ualloc[i++];
808 		}
809 
810 		printf(" %4x", m);
811 	}
812 	printf("\n");
813 #endif
814 
815 	wmemfree(ualloc, 8*1024);
816 }
817 
818 setscbnex(fn)
819 	int (*fn)();
820 {
821 	register struct scb *scbp = &scb;
822 
823 	scbp = (struct scb *)((caddr_t)scbp + nsbi * 512);
824 	scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
825 	    scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
826 		scbentry(fn, SCB_ISTACK);
827 }
828 
829 /*
830  * Make an IO register area accessible at physical address physa
831  * by mapping kernel ptes starting at pte.
832  */
833 ioaccess(physa, pte, size)
834 	caddr_t physa;
835 	register struct pte *pte;
836 	int size;
837 {
838 	register int i = btop(size);
839 	register unsigned v = btop(physa);
840 
841 	do
842 		*(int *)pte++ = PG_V|PG_KW|v++;
843 	while (--i > 0);
844 	mtpr(TBIA, 0);
845 }
846 
847 /*
848  * Configure swap space and related parameters.
849  */
850 swapconf()
851 {
852 	register struct swdevt *swp;
853 	register int nblks;
854 
855 	for (swp = swdevt; swp->sw_dev; swp++) {
856 		if (bdevsw[major(swp->sw_dev)].d_psize) {
857 			nblks =
858 			    (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
859 			if (swp->sw_nblks == 0 || swp->sw_nblks > nblks)
860 				swp->sw_nblks = nblks;
861 		}
862 	}
863 	if (!cold)			/* in case called for mba device */
864 		return;
865 	if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
866 		dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem;
867 	if (dumplo < 0)
868 		dumplo = 0;
869 }
870 
871 #define	DOSWAP			/* Change swdevt, argdev, and dumpdev too */
872 u_long	bootdev;		/* should be dev_t, but not until 32 bits */
873 
874 static	char devname[][2] = {
875 	'h','p',	/* 0 = hp */
876 	0,0,		/* 1 = ht */
877 	'u','p',	/* 2 = up */
878 	'r','k',	/* 3 = hk */
879 	0,0,		/* 4 = sw */
880 	0,0,		/* 5 = tm */
881 	0,0,		/* 6 = ts */
882 	0,0,		/* 7 = mt */
883 	0,0,		/* 8 = tu */
884 	'r','a',	/* 9 = ra */
885 	0,0,		/* 10 = ut */
886 	'r','b',	/* 11 = rb */
887 	0,0,		/* 12 = uu */
888 	0,0,		/* 13 = rx */
889 	'r','l',	/* 14 = rl */
890 };
891 
892 #define	PARTITIONMASK	0x7
893 #define	PARTITIONSHIFT	3
894 
895 /*
896  * Attempt to find the device from which we were booted.
897  * If we can do so, and not instructed not to do so,
898  * change rootdev to correspond to the load device.
899  */
900 setroot()
901 {
902 	int  majdev, mindev, unit, part, adaptor;
903 	dev_t temp, orootdev;
904 	struct swdevt *swp;
905 
906 	if (boothowto & RB_DFLTROOT ||
907 	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
908 		return (0);
909 	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
910 	if (majdev > sizeof(devname) / sizeof(devname[0]))
911 		return (0);
912 	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
913 	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
914 	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
915 	if (majdev == 0) {	/* MBA device */
916 #if NMBA > 0
917 		register struct mba_device *mbap;
918 		int mask;
919 
920 /*
921  * The MBA number used at boot time is not necessarily the same as the
922  * MBA number used by the kernel.  In order to change the rootdev we need to
923  * convert the boot MBA number to the kernel MBA number.  The address space
924  * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number
925  * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750.
926  * Therefore we can search the mba_hd table for the MBA that has the physical
927  * address corresponding to the boot MBA number.
928  */
929 #define	PHYSADRSHFT	13
930 #define	PHYSMBAMASK780	0x7
931 #define	PHYSMBAMASK750	0x3
932 
933 		switch (cpu) {
934 
935 		case VAX_780:
936 		case VAX_8600:
937 		default:
938 			mask = PHYSMBAMASK780;
939 			break;
940 
941 		case VAX_750:
942 			mask = PHYSMBAMASK750;
943 			break;
944 		}
945 		for (mbap = mbdinit; mbap->mi_driver; mbap++)
946 			if (mbap->mi_alive && mbap->mi_drive == unit &&
947 			    (((long)mbap->mi_hd->mh_physmba >> PHYSADRSHFT)
948 			      & mask) == adaptor)
949 			    	break;
950 		if (mbap->mi_driver == 0)
951 			return (0);
952 		mindev = mbap->mi_unit;
953 #else
954 		return (0);
955 #endif
956 	} else {
957 		register struct uba_device *ubap;
958 
959 		for (ubap = ubdinit; ubap->ui_driver; ubap++)
960 			if (ubap->ui_alive && ubap->ui_slave == unit &&
961 			   ubap->ui_ubanum == adaptor &&
962 			   ubap->ui_driver->ud_dname[0] == devname[majdev][0] &&
963 			   ubap->ui_driver->ud_dname[1] == devname[majdev][1])
964 			    	break;
965 
966 		if (ubap->ui_driver == 0)
967 			return (0);
968 		mindev = ubap->ui_unit;
969 	}
970 	mindev = (mindev << PARTITIONSHIFT) + part;
971 	orootdev = rootdev;
972 	rootdev = makedev(majdev, mindev);
973 	/*
974 	 * If the original rootdev is the same as the one
975 	 * just calculated, don't need to adjust the swap configuration.
976 	 */
977 	if (rootdev == orootdev)
978 		return (1);
979 
980 	printf("Changing root device to %c%c%d%c\n",
981 		devname[majdev][0], devname[majdev][1],
982 		mindev >> PARTITIONSHIFT, part + 'a');
983 
984 #ifdef DOSWAP
985 	mindev &= ~PARTITIONMASK;
986 	for (swp = swdevt; swp->sw_dev; swp++) {
987 		if (majdev == major(swp->sw_dev) &&
988 		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
989 			temp = swdevt[0].sw_dev;
990 			swdevt[0].sw_dev = swp->sw_dev;
991 			swp->sw_dev = temp;
992 			break;
993 		}
994 	}
995 	if (swp->sw_dev == 0)
996 		return (1);
997 
998 	/*
999 	 * If argdev and dumpdev were the same as the old primary swap
1000 	 * device, move them to the new primary swap device.
1001 	 */
1002 	if (temp == dumpdev)
1003 		dumpdev = swdevt[0].sw_dev;
1004 	if (temp == argdev)
1005 		argdev = swdevt[0].sw_dev;
1006 #endif
1007 	return (1);
1008 }
1009