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