xref: /original-bsd/sys/vax/vax/autoconf.c (revision 4b2c5e10)
1 /*	autoconf.c	6.3	83/08/11	*/
2 
3 /*
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.
17  *
18  * TODO:
19  *	use pcpu info about whether a ubasr exists
20  */
21 
22 #include "mba.h"
23 #include "uba.h"
24 
25 #include "../machine/pte.h"
26 
27 #include "../h/param.h"
28 #include "../h/systm.h"
29 #include "../h/map.h"
30 #include "../h/buf.h"
31 #include "../h/dk.h"
32 #include "../h/vm.h"
33 #include "../h/conf.h"
34 #include "../h/dmap.h"
35 
36 #include "../vax/cpu.h"
37 #include "../vax/mem.h"
38 #include "../vax/mtpr.h"
39 #include "../vax/nexus.h"
40 #include "../vax/scb.h"
41 #include "../vaxmba/mbareg.h"
42 #include "../vaxmba/mbavar.h"
43 #include "../vaxuba/ubareg.h"
44 #include "../vaxuba/ubavar.h"
45 
46 /*
47  * The following several variables are related to
48  * the configuration process, and are used in initializing
49  * the machine.
50  */
51 int	cold;		/* if 1, still working on cold-start */
52 int	nexnum;		/* current nexus number */
53 int	dkn;		/* number of iostat dk numbers assigned so far */
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 #endif
63 #if VAX780
64 int	(*ubaintv[4])() =	{ Xua0int, Xua1int, Xua2int, Xua3int };
65 #endif
66 
67 /*
68  * This allocates the space for the per-uba information,
69  * such as buffered data path usage.
70  */
71 struct	uba_hd uba_hd[MAXNUBA];
72 
73 /*
74  * Determine mass storage and memory configuration for a machine.
75  * Get cpu type, and then switch out to machine specific procedures
76  * which will probe adaptors to see what is out there.
77  */
78 configure()
79 {
80 	union cpusid cpusid;
81 	register struct percpu *ocp;
82 	register int *ip;
83 	extern char Sysbase[];
84 
85 	cpusid.cpusid = mfpr(SID);
86 	for (ocp = percpu; ocp->pc_cputype; ocp++)
87 		if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
88 			probenexus(ocp);
89 			/*
90 			 * Write protect the scb and UNIBUS interrupt vectors.
91 			 * It is strange that this code is here, but this is
92 			 * as soon as we are done mucking with it, and the
93 			 * write-enable was done in assembly language
94 			 * to which we will never return.
95 			 */
96 			ip = (int *)Sysmap + 1; *ip &= ~PG_PROT; *ip |= PG_KR;
97 			ip++; *ip &= ~PG_PROT; *ip |= PG_KR;
98 #if NUBA > 1
99 			ip++; *ip &= ~PG_PROT; *ip |= PG_KR;
100 #endif
101 			mtpr(TBIS, Sysbase);
102 #if GENERIC
103 			setconf();
104 #endif
105 			/*
106 			 * Configure swap area and related system
107 			 * parameter based on device(s) used.
108 			 */
109 			swapconf();
110 			cold = 0;
111 			memenable();
112 			return;
113 		}
114 	printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
115 	asm("halt");
116 }
117 
118 /*
119  * Probe nexus space, finding the interconnects
120  * and setting up and probing mba's and uba's for devices.
121  */
122 /*ARGSUSED*/
123 probenexus(pcpu)
124 	register struct percpu *pcpu;
125 {
126 	register struct nexus *nxv;
127 	struct nexus *nxp = pcpu->pc_nexbase;
128 	union nexcsr nexcsr;
129 	int i;
130 
131 	nexnum = 0, nxv = nexus;
132 	for (; nexnum < pcpu->pc_nnexus; nexnum++, nxp++, nxv++) {
133 		nxaccess(nxp, Nexmap[nexnum]);
134 		if (badaddr((caddr_t)nxv, 4))
135 			continue;
136 		if (pcpu->pc_nextype && pcpu->pc_nextype[nexnum] != NEX_ANY)
137 			nexcsr.nex_csr = pcpu->pc_nextype[nexnum];
138 		else
139 			nexcsr = nxv->nexcsr;
140 		if (nexcsr.nex_csr&NEX_APD)
141 			continue;
142 		switch (nexcsr.nex_type) {
143 
144 		case NEX_MBA:
145 			printf("mba%d at tr%d\n", nummba, nexnum);
146 			if (nummba >= NMBA) {
147 				printf("%d mba's", nummba);
148 				goto unconfig;
149 			}
150 #if NMBA > 0
151 			mbafind(nxv, nxp);
152 			nummba++;
153 #endif
154 			break;
155 
156 		case NEX_UBA0:
157 		case NEX_UBA1:
158 		case NEX_UBA2:
159 		case NEX_UBA3:
160 			printf("uba%d at tr%d\n", numuba, nexnum);
161 			if (numuba >= 4) {
162 				printf("5 uba's");
163 				goto unsupp;
164 			}
165 #if VAX780
166 			if (cpu == VAX_780)
167 				setscbnex(ubaintv[numuba]);
168 #endif
169 			i = nexcsr.nex_type - NEX_UBA0;
170 			unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
171 			    umem[i], pcpu->pc_umaddr[i], UMEMmap[i]);
172 #if VAX780
173 			if (cpu == VAX_780)
174 				((struct uba_regs *)nxv)->uba_cr =
175 				    UBACR_IFS|UBACR_BRIE|
176 				    UBACR_USEFIE|UBACR_SUEFIE|
177 				    (((struct uba_regs *)nxv)->uba_cr&0x7c000000);
178 #endif
179 			numuba++;
180 			break;
181 
182 		case NEX_DR32:
183 		/* there can be more than one... are there other codes??? */
184 			printf("dr32");
185 			goto unsupp;
186 
187 		case NEX_MEM4:
188 		case NEX_MEM4I:
189 		case NEX_MEM16:
190 		case NEX_MEM16I:
191 		case NEX_MEM64L:
192 		case NEX_MEM64LI:
193 		case NEX_MEM64U:
194 		case NEX_MEM64UI:
195 		case NEX_MEM64I:
196 			printf("mcr%d at tr%d\n", nmcr, nexnum);
197 			if (nmcr >= 4) {
198 				printf("5 mcr's");
199 				goto unsupp;
200 			}
201 			mcraddr[nmcr++] = (struct mcr *)nxv;
202 			break;
203 
204 		case NEX_MPM0:
205 		case NEX_MPM1:
206 		case NEX_MPM2:
207 		case NEX_MPM3:
208 			printf("mpm");
209 			goto unsupp;
210 
211 		case NEX_CI:
212 			printf("ci");
213 			goto unsupp;
214 
215 		default:
216 			printf("nexus type %x", nexcsr.nex_type);
217 unsupp:
218 			printf(" unsupported (at tr %d)\n", nexnum);
219 			continue;
220 unconfig:
221 			printf(" not configured\n");
222 			continue;
223 		}
224 	}
225 }
226 
227 #if NMBA > 0
228 struct	mba_device *mbaconfig();
229 /*
230  * Find devices attached to a particular mba
231  * and look for each device found in the massbus
232  * initialization tables.
233  */
234 mbafind(nxv, nxp)
235 	struct nexus *nxv, *nxp;
236 {
237 	register struct mba_regs *mdp;
238 	register struct mba_drv *mbd;
239 	register struct mba_device *mi;
240 	register struct mba_slave *ms;
241 	int dn, dt, sn;
242 	struct mba_device fnd;
243 
244 	mdp = (struct mba_regs *)nxv;
245 	mba_hd[nummba].mh_mba = mdp;
246 	mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
247 	setscbnex(mbaintv[nummba]);
248 	fnd.mi_mba = mdp;
249 	fnd.mi_mbanum = nummba;
250 	for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
251 		if ((mbd->mbd_ds&MBDS_DPR) == 0)
252 			continue;
253 		mdp->mba_sr |= MBSR_NED;		/* si kludge */
254 		dt = mbd->mbd_dt & 0xffff;
255 		if (dt == 0)
256 			continue;
257 		if (mdp->mba_sr&MBSR_NED)
258 			continue;			/* si kludge */
259 		if (dt == MBDT_MOH)
260 			continue;
261 		fnd.mi_drive = dn;
262 #define	qeq(a, b)	( a == b || a == '?' )
263 		if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP))
264 		    for (sn = 0; sn < 8; sn++) {
265 			mbd->mbd_tc = sn;
266 		        for (ms = mbsinit; ms->ms_driver; ms++)
267 			    if (ms->ms_driver == mi->mi_driver &&
268 				ms->ms_alive == 0 &&
269 				qeq(ms->ms_ctlr, mi->mi_unit) &&
270 				qeq(ms->ms_slave, sn) &&
271 				(*ms->ms_driver->md_slave)(mi, ms, sn)) {
272 					printf("%s%d at %s%d slave %d\n"
273 					    , ms->ms_driver->md_sname
274 					    , ms->ms_unit
275 					    , mi->mi_driver->md_dname
276 					    , mi->mi_unit
277 					    , sn
278 					);
279 					ms->ms_alive = 1;
280 					ms->ms_ctlr = mi->mi_unit;
281 					ms->ms_slave = sn;
282 				}
283 		    }
284 	}
285 	mdp->mba_cr = MBCR_INIT;
286 	mdp->mba_cr = MBCR_IE;
287 }
288 
289 /*
290  * Have found a massbus device;
291  * see if it is in the configuration table.
292  * If so, fill in its data.
293  */
294 struct mba_device *
295 mbaconfig(ni, type)
296 	register struct mba_device *ni;
297 	register int type;
298 {
299 	register struct mba_device *mi;
300 	register short *tp;
301 	register struct mba_hd *mh;
302 
303 	for (mi = mbdinit; mi->mi_driver; mi++) {
304 		if (mi->mi_alive)
305 			continue;
306 		tp = mi->mi_driver->md_type;
307 		for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
308 			if (*tp == (type&MBDT_TYPE))
309 				goto found;
310 		continue;
311 found:
312 #define	match(fld)	(ni->fld == mi->fld || mi->fld == '?')
313 		if (!match(mi_drive) || !match(mi_mbanum))
314 			continue;
315 		printf("%s%d at mba%d drive %d\n",
316 		    mi->mi_driver->md_dname, mi->mi_unit,
317 		    ni->mi_mbanum, ni->mi_drive);
318 		mi->mi_alive = 1;
319 		mh = &mba_hd[ni->mi_mbanum];
320 		mi->mi_hd = mh;
321 		mh->mh_mbip[ni->mi_drive] = mi;
322 		mh->mh_ndrive++;
323 		mi->mi_mba = ni->mi_mba;
324 		mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
325 		mi->mi_mbanum = ni->mi_mbanum;
326 		mi->mi_drive = ni->mi_drive;
327 		/*
328 		 * If drive has never been seen before,
329 		 * give it a dkn for statistics.
330 		 */
331 		if (mi->mi_driver->md_info[mi->mi_unit] == 0) {
332 			mi->mi_driver->md_info[mi->mi_unit] = mi;
333 			if (mi->mi_dk && dkn < DK_NDRIVE)
334 				mi->mi_dk = dkn++;
335 			else
336 				mi->mi_dk = -1;
337 		}
338 		(*mi->mi_driver->md_attach)(mi);
339 		return (mi);
340 	}
341 	return (0);
342 }
343 #endif
344 
345 /*
346  * Fixctlrmask fixes the masks of the driver ctlr routines
347  * which otherwise save r10 and r11 where the interrupt and br
348  * level are passed through.
349  */
350 fixctlrmask()
351 {
352 	register struct uba_ctlr *um;
353 	register struct uba_device *ui;
354 	register struct uba_driver *ud;
355 #define	phys(a,b) ((b)(((int)(a))&0x7fffffff))
356 
357 	for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
358 		*phys(ud->ud_probe, short *) &= ~0xc00;
359 	for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
360 		*phys(ud->ud_probe, short *) &= ~0xc00;
361 }
362 
363 /*
364  * Find devices on a UNIBUS.
365  * Uses per-driver routine to set <br,cvec> into <r11,r10>,
366  * and then fills in the tables, with help from a per-driver
367  * slave initialization routine.
368  */
369 unifind(vubp, pubp, vumem, pumem, memmap)
370 	struct uba_regs *vubp, *pubp;
371 	caddr_t vumem, pumem;
372 	struct pte *memmap;
373 {
374 #ifndef lint
375 	register int br, cvec;			/* MUST BE r11, r10 */
376 #else
377 	/*
378 	 * Lint doesn't realize that these
379 	 * can be initialized asynchronously
380 	 * when devices interrupt.
381 	 */
382 	register int br = 0, cvec = 0;
383 #endif
384 	register struct uba_device *ui;
385 	register struct uba_ctlr *um;
386 	u_short *reg, *ap, addr;
387 	struct uba_hd *uhp;
388 	struct uba_driver *udp;
389 	int i, (**ivec)(), haveubasr;
390 	caddr_t ualloc, zmemall();
391 	extern int catcher[256];
392 
393 	/*
394 	 * Initialize the UNIBUS, by freeing the map
395 	 * registers and the buffered data path registers
396 	 */
397 	uhp = &uba_hd[numuba];
398 	uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map));
399 	ubainitmaps(uhp);
400 	haveubasr = cpu == VAX_780;
401 
402 	/*
403 	 * Save virtual and physical addresses
404 	 * of adaptor, and allocate and initialize
405 	 * the UNIBUS interrupt vector.
406 	 */
407 	uhp->uh_uba = vubp;
408 	uhp->uh_physuba = pubp;
409 	if (numuba == 0)
410 		uhp->uh_vec = UNIvec;
411 #if NUBA > 1
412 	else if (numuba == 1)
413 		uhp->uh_vec = UNI1vec;
414 	else {
415 #if defined(VAX_750)
416 		if (cpu == VAX_750)
417 			printf("More than 2 UBA's not supported\n");
418 		else
419 #endif
420 			uhp->uh_vec = (int(**)())calloc(512);
421 	}
422 #endif
423 	for (i = 0; i < 128; i++)
424 		uhp->uh_vec[i] =
425 		    scbentry(&catcher[i*2], SCB_ISTACK);
426 	/*
427 	 * Set last free interrupt vector for devices with
428 	 * programmable interrupt vectors.  Use is to decrement
429 	 * this number and use result as interrupt vector.
430 	 */
431 	uhp->uh_lastiv = 0x200;
432 
433 	ubaaccess(pumem, memmap);
434 #if VAX780
435 	if (haveubasr) {
436 		vubp->uba_sr = vubp->uba_sr;
437 		vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
438 	}
439 #endif
440 	/*
441 	 * Grab some memory to record the umem address space we allocate,
442 	 * so we can be sure not to place two devices at the same address.
443 	 *
444 	 * We could use just 1/8 of this (we only want a 1 bit flag) but
445 	 * we are going to give it back anyway, and that would make the
446 	 * code here bigger (which we can't give back), so ...
447 	 *
448 	 * One day, someone will make a unibus with something other than
449 	 * an 8K i/o address space, & screw this totally.
450 	 */
451 	ualloc = zmemall(memall, 8*1024);
452 	if (ualloc == (caddr_t)0)
453 		panic("no mem for unifind");
454 
455 	/*
456 	 * Map the first page of UNIBUS i/o
457 	 * space to the first page of memory
458 	 * for devices which will need to dma
459 	 * output to produce an interrupt.
460 	 */
461 	*(int *)(&vubp->uba_map[0]) = UBAMR_MRV;
462 
463 #define	ubaoff(off)	((off)&0x1fff)
464 #define	ubaddr(off)	(u_short *)((int)vumem + (ubaoff(off)|0x3e000))
465 	/*
466 	 * Check each unibus mass storage controller.
467 	 * For each one which is potentially on this uba,
468 	 * see if it is really there, and if it is record it and
469 	 * then go looking for slaves.
470 	 */
471 	for (um = ubminit; udp = um->um_driver; um++) {
472 		if (um->um_ubanum != numuba && um->um_ubanum != '?')
473 			continue;
474 		addr = (u_short)um->um_addr;
475 		/*
476 		 * use the particular address specified first,
477 		 * or if it is given as "0", of there is no device
478 		 * at that address, try all the standard addresses
479 		 * in the driver til we find it
480 		 */
481 	    for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
482 
483 		if (ualloc[ubaoff(addr)])
484 			continue;
485 		reg = ubaddr(addr);
486 		if (badaddr((caddr_t)reg, 2))
487 			continue;
488 #if VAX780
489 		if (haveubasr && vubp->uba_sr) {
490 			vubp->uba_sr = vubp->uba_sr;
491 			continue;
492 		}
493 #endif
494 		cvec = 0x200;
495 		i = (*udp->ud_probe)(reg, um->um_ctlr);
496 #if VAX780
497 		if (haveubasr && vubp->uba_sr) {
498 			vubp->uba_sr = vubp->uba_sr;
499 			continue;
500 		}
501 #endif
502 		if (i == 0)
503 			continue;
504 		printf("%s%d at uba%d csr %o ",
505 		    udp->ud_mname, um->um_ctlr, numuba, addr);
506 		if (cvec == 0) {
507 			printf("zero vector\n");
508 			continue;
509 		}
510 		if (cvec == 0x200) {
511 			printf("didn't interrupt\n");
512 			continue;
513 		}
514 		printf("vec %o, ipl %x\n", cvec, br);
515 		um->um_alive = 1;
516 		um->um_ubanum = numuba;
517 		um->um_hd = &uba_hd[numuba];
518 		um->um_addr = (caddr_t)reg;
519 		udp->ud_minfo[um->um_ctlr] = um;
520 		for (ivec = um->um_intr; *ivec; ivec++) {
521 			um->um_hd->uh_vec[cvec/4] =
522 			    scbentry(*ivec, SCB_ISTACK);
523 			cvec += 4;
524 		}
525 		for (ui = ubdinit; ui->ui_driver; ui++) {
526 			if (ui->ui_driver != udp || ui->ui_alive ||
527 			    ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
528 			    ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
529 				continue;
530 			if ((*udp->ud_slave)(ui, reg)) {
531 				ui->ui_alive = 1;
532 				ui->ui_ctlr = um->um_ctlr;
533 				ui->ui_ubanum = numuba;
534 				ui->ui_hd = &uba_hd[numuba];
535 				ui->ui_addr = (caddr_t)reg;
536 				ui->ui_physaddr = pumem + ubdevreg(addr);
537 				if (ui->ui_dk && dkn < DK_NDRIVE)
538 					ui->ui_dk = dkn++;
539 				else
540 					ui->ui_dk = -1;
541 				ui->ui_mi = um;
542 				/* ui_type comes from driver */
543 				udp->ud_dinfo[ui->ui_unit] = ui;
544 				printf("%s%d at %s%d slave %d\n",
545 				    udp->ud_dname, ui->ui_unit,
546 				    udp->ud_mname, um->um_ctlr, ui->ui_slave);
547 				(*udp->ud_attach)(ui);
548 			}
549 		}
550 		break;
551 	    }
552 	}
553 	/*
554 	 * Now look for non-mass storage peripherals.
555 	 */
556 	for (ui = ubdinit; udp = ui->ui_driver; ui++) {
557 		if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
558 		    ui->ui_alive || ui->ui_slave != -1)
559 			continue;
560 		addr = (u_short)ui->ui_addr;
561 
562 	    for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
563 
564 		if (ualloc[ubaoff(addr)])
565 			continue;
566 		reg = ubaddr(addr);
567 		if (badaddr((caddr_t)reg, 2))
568 			continue;
569 #if VAX780
570 		if (haveubasr && vubp->uba_sr) {
571 			vubp->uba_sr = vubp->uba_sr;
572 			continue;
573 		}
574 #endif
575 		cvec = 0x200;
576 		i = (*udp->ud_probe)(reg);
577 #if VAX780
578 		if (haveubasr && vubp->uba_sr) {
579 			vubp->uba_sr = vubp->uba_sr;
580 			continue;
581 		}
582 #endif
583 		if (i == 0)
584 			continue;
585 		printf("%s%d at uba%d csr %o ",
586 		    ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
587 		if (cvec == 0) {
588 			printf("zero vector\n");
589 			continue;
590 		}
591 		if (cvec == 0x200) {
592 			printf("didn't interrupt\n");
593 			continue;
594 		}
595 		printf("vec %o, ipl %x\n", cvec, br);
596 		while (--i >= 0)
597 			ualloc[ubaoff(addr+i)] = 1;
598 		ui->ui_hd = &uba_hd[numuba];
599 		for (ivec = ui->ui_intr; *ivec; ivec++) {
600 			ui->ui_hd->uh_vec[cvec/4] =
601 			    scbentry(*ivec, SCB_ISTACK);
602 			cvec += 4;
603 		}
604 		ui->ui_alive = 1;
605 		ui->ui_ubanum = numuba;
606 		ui->ui_addr = (caddr_t)reg;
607 		ui->ui_physaddr = pumem + ubdevreg(addr);
608 		ui->ui_dk = -1;
609 		/* ui_type comes from driver */
610 		udp->ud_dinfo[ui->ui_unit] = ui;
611 		(*udp->ud_attach)(ui);
612 		break;
613 	    }
614 	}
615 
616 #ifdef	AUTO_DEBUG
617 	printf("Unibus allocation map");
618 	for (i = 0; i < 8*1024; ) {
619 		register n, m;
620 
621 		if ((i % 128) == 0) {
622 			printf("\n%6o:", i);
623 			for (n = 0; n < 128; n++)
624 				if (ualloc[i+n])
625 					break;
626 			if (n == 128) {
627 				i += 128;
628 				continue;
629 			}
630 		}
631 
632 		for (n = m = 0; n < 16; n++) {
633 			m <<= 1;
634 			m |= ualloc[i++];
635 		}
636 
637 		printf(" %4x", m);
638 	}
639 	printf("\n");
640 #endif
641 
642 	wmemfree(ualloc, 8*1024);
643 }
644 
645 setscbnex(fn)
646 	int (*fn)();
647 {
648 	register struct scb *scbp = &scb;
649 
650 	scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
651 	    scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
652 		scbentry(fn, SCB_ISTACK);
653 }
654 
655 /*
656  * Make a nexus accessible at physical address phys
657  * by mapping kernel ptes starting at pte.
658  *
659  * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE
660  * SINCE MISSING NEXI DONT RESPOND.  BUT THEN AGAIN
661  * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE.
662  */
663 nxaccess(physa, pte)
664 	struct nexus *physa;
665 	register struct pte *pte;
666 {
667 	register int i = btop(sizeof (struct nexus));
668 	register unsigned v = btop(physa);
669 
670 	do
671 		*(int *)pte++ = PG_V|PG_KW|v++;
672 	while (--i > 0);
673 	mtpr(TBIA, 0);
674 }
675 
676 ubaaccess(pumem, pte)
677 	caddr_t pumem;
678 	register struct pte *pte;
679 {
680 	register int i = 512;
681 	register unsigned v = btop(pumem);
682 
683 	do
684 		*(int *)pte++ = PG_V|PG_KW|v++;
685 	while (--i > 0);
686 	mtpr(TBIA, 0);
687 }
688 
689 #define	DMMIN	32
690 #define	DMMAX	1024
691 #define	DMTEXT	1024
692 #define	MAXDUMP	(10*2048)
693 /*
694  * Configure swap space and related parameters.
695  */
696 swapconf()
697 {
698 	register struct swdevt *swp;
699 	register int nblks;
700 
701 	for (swp = swdevt; swp->sw_dev; swp++) {
702 		if (bdevsw[major(swp->sw_dev)].d_psize)
703 			nblks =
704 			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
705 		if (swp->sw_nblks == 0 || swp->sw_nblks > nblks)
706 			swp->sw_nblks = nblks;
707 	}
708 	if (!cold)			/* in case called for mba device */
709 		return;
710 	if (dumplo == 0)
711 		dumplo = swdevt[0].sw_nblks - MAXDUMP;
712 	if (dumplo < 0)
713 		dumplo = 0;
714 	if (dmmin == 0)
715 		dmmin = DMMIN;
716 	if (dmmax == 0)
717 		dmmax = DMMAX;
718 	if (dmtext == 0)
719 		dmtext = DMTEXT;
720 	if (dmtext > dmmax)
721 		dmtext = dmmax;
722 }
723