Add support for microvax 3000.
[unix-history] / usr / src / sys / vax / vax / autoconf.c
CommitLineData
da7c5cc6 1/*
42b84df5 2 * Copyright (c) 1982,1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
802ae52e 6 * @(#)autoconf.c 7.16 (Berkeley) %G%
da7c5cc6 7 */
327f6ec8 8
327f6ec8 9/*
d565635a
BJ
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.
327f6ec8
BJ
16 */
17
47fa50b1 18#include "mba.h"
976a5707 19#include "uba.h"
9a0de372 20#include "kra.h" /* XXX wrong file */
47fa50b1 21
1884f3f6
JB
22#include "param.h"
23#include "systm.h"
24#include "map.h"
25#include "buf.h"
3761a96c 26#include "dkstat.h"
1884f3f6 27#include "vm.h"
fcba03fb 28#include "malloc.h"
1884f3f6
JB
29#include "conf.h"
30#include "dmap.h"
42b84df5 31#include "reboot.h"
dd94cc44
MK
32#ifdef SECSIZE
33#include "file.h"
34#include "ioctl.h"
35#include "disklabel.h"
36#endif SECSIZE
cd3da95f 37
58b14b46 38#include "pte.h"
dd94cc44 39#include "pte.h"
1884f3f6
JB
40#include "cpu.h"
41#include "mem.h"
42#include "mtpr.h"
43#include "nexus.h"
44#include "scb.h"
cb4a08d0 45#include "ioa.h"
9a0de372 46#include "../vaxbi/bireg.h"
cd3da95f
BJ
47#include "../vaxmba/mbareg.h"
48#include "../vaxmba/mbavar.h"
49#include "../vaxuba/ubareg.h"
50#include "../vaxuba/ubavar.h"
327f6ec8 51
d565635a
BJ
52/*
53 * The following several variables are related to
54 * the configuration process, and are used in initializing
55 * the machine.
56 */
57int cold; /* if 1, still working on cold-start */
d565635a 58int dkn; /* number of iostat dk numbers assigned so far */
3327052b 59int cpuspeed = 1; /* relative cpu speed */
327f6ec8 60
d565635a
BJ
61/*
62 * Addresses of the (locore) routines which bootstrap us from
63 * hardware traps to C code. Filled into the system control block
64 * as necessary.
9a0de372
MK
65 *
66 * RIDICULOUS! CONFIG SHOULD GENERATE AN ioconf.h FOR US, with
67 * mba glue also in `glue.s'. (Unibus adapter glue is special, though.)
d565635a 68 */
47fa50b1 69#if NMBA > 0
8d2ea14f 70int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
cb4a08d0
JB
71#if NMBA > 4
72 Need to expand the table for more than 4 massbus adaptors
47fa50b1 73#endif
cb4a08d0
JB
74#endif
75#if defined(VAX780) || defined(VAX8600)
76int (*ubaintv[])() =
77{
78 Xua0int, Xua1int, Xua2int, Xua3int,
79#if NUBA > 4
80 Xua4int, Xua5int, Xua6int, Xua7int,
81#endif
82#if NUBA > 8
83 Need to expand the table for more than 8 unibus adaptors
84#endif
85};
5aa9d5ea 86#endif
9a0de372
MK
87#if NKDB > 0
88/* kdb50 driver does not appear in udminit[] (not without csr!) */
89int Xkdbintr0(); /* generated by autoconf */
90int (*kdbintv[])() = { Xkdbintr0 };
91#if NKDB > 1
92 Need to expand the table for more than 1 KDB adapter
93#endif
94#endif
d565635a
BJ
95
96/*
97 * This allocates the space for the per-uba information,
98 * such as buffered data path usage.
99 */
9b95def8 100struct uba_hd uba_hd[NUBA];
327f6ec8
BJ
101
102/*
103 * Determine mass storage and memory configuration for a machine.
104 * Get cpu type, and then switch out to machine specific procedures
105 * which will probe adaptors to see what is out there.
106 */
107configure()
108{
109 union cpusid cpusid;
3f3a34c3 110 register struct percpu *ocp;
9a0de372 111 register struct pte *ip;
327f6ec8
BJ
112
113 cpusid.cpusid = mfpr(SID);
9a0de372
MK
114 switch (cpusid.cpuany.cp_type) {
115#if VAX8600
116 case VAX_8600:
117 printf("VAX 8600, serial# %d(%d), hardware ECO level %d(%d)\n",
118 cpusid.cpu780.cp_sno, cpusid.cpu780.cp_plant,
119 cpusid.cpu780.cp_eco >> 4, cpusid.cpu780.cp_eco);
120 break;
121#endif
122#if VAX8200
123 case VAX_8200:
124 printf("\
125VAX 82%c0, hardware rev %d, ucode patch rev %d, sec patch %d, ucode rev %d\n",
126 cpusid.cpu8200.cp_5 ? '5' : '0',
127 cpusid.cpu8200.cp_hrev, cpusid.cpu8200.cp_patch,
128 cpusid.cpu8200.cp_secp, cpusid.cpu8200.cp_urev);
129 mastercpu = mfpr(BINID);
130 break;
131#endif
132#if VAX780
133 case VAX_780:
134 printf("\
135VAX 11/78%c, serial# %d(%d), hardware ECO level %d(%d)\n",
136 cpusid.cpu780.cp_5 ? '5' : '0',
137 cpusid.cpu780.cp_sno, cpusid.cpu780.cp_plant,
138 cpusid.cpu780.cp_eco >> 4, cpusid.cpu780.cp_eco);
139 break;
140#endif
141#if VAX750
142 case VAX_750:
143 printf("VAX 11/750, hardware rev %d, ucode rev %d\n",
144 cpusid.cpu750.cp_hrev, cpusid.cpu750.cp_urev);
145 break;
146#endif
147#if VAX730
148 case VAX_730:
149 printf("VAX 11/730, ucode rev %d\n", cpusid.cpu730.cp_urev);
150 break;
151#endif
152#if VAX630
153 case VAX_630:
154 printf("MicroVAX-II\n");
155 break;
802ae52e
TF
156#endif
157#if VAX650
158 case VAX_650:
159 printf("MicroVAX 3000, ucode rev %d\n", cpusid.cpu650.cp_urev);
160 break;
9a0de372
MK
161#endif
162 }
b17fedcd 163 for (ocp = percpu; ocp->pc_cputype; ocp++)
3f3a34c3 164 if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
3327052b 165 cpuspeed = ocp->pc_cpuspeed;
9a0de372
MK
166 cpuops = ocp->pc_ops;
167 if (cpuops->cpu_init != NULL)
168 (*cpuops->cpu_init)();
0fe372b3 169 probeio(ocp);
d565635a 170 /*
096eb64d
SL
171 * Write protect the scb and UNIBUS interrupt vectors.
172 * It is strange that this code is here, but this is
173 * as soon as we are done mucking with it, and the
d565635a
BJ
174 * write-enable was done in assembly language
175 * to which we will never return.
176 */
9a0de372
MK
177 for (ip = kvtopte(scb); ip < kvtopte(eUNIvec); ip++) {
178 *(int *)ip &= ~PG_PROT;
179 *(int *)ip |= PG_KR;
180 }
181 mtpr(TBIA, 0);
d565635a 182#if GENERIC
25cfc74b
MK
183 if ((boothowto & RB_ASKNAME) == 0)
184 setroot();
185 setconf();
cd97bee2 186#else
25cfc74b 187 setroot();
d565635a 188#endif
9f0281aa
SL
189 /*
190 * Configure swap area and related system
191 * parameter based on device(s) used.
192 */
193 swapconf();
8d2ea14f 194 cold = 0;
c9e9b65b 195 memenable();
3f3a34c3
BJ
196 return;
197 }
d565635a 198 printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
327f6ec8
BJ
199 asm("halt");
200}
201
03d3d455
MK
202#if VAX8600 || VAX780 || VAX750 || VAX730
203int nexnum; /* current nexus number */
204int nsbi; /* current sbi number */
205#endif
9a0de372
MK
206#if VAX8200
207int numkdb; /* current ``kdb'' number */
208int bi_nodes; /* XXX remembers found bi nodes */
209#endif
03d3d455 210
0fe372b3
MK
211/*
212 * Probe the main IO bus(es).
213 * The percpu structure gives us a handle on the addresses and/or types.
214 */
215probeio(pcpu)
216 register struct percpu *pcpu;
cb4a08d0 217{
0fe372b3 218 register struct iobus *iob;
cb4a08d0
JB
219 int ioanum;
220
221 ioanum = 0;
0fe372b3
MK
222 for (iob = pcpu->pc_io; ioanum < pcpu->pc_nioa; ioanum++, iob++) {
223
224 switch (iob->io_type) {
225
802ae52e 226#if VAX630 || VAX650
03d3d455
MK
227 case IO_QBUS:
228 probeqbus((struct qbus *)iob->io_details);
229 break;
230#endif
231
232#if VAX780 || VAX750 || VAX730
0fe372b3
MK
233 case IO_SBI780:
234 case IO_CMI750:
235 case IO_XXX730:
236 probenexi((struct nexusconnect *)iob->io_details);
cb4a08d0
JB
237 break;
238#endif
0fe372b3 239
cb4a08d0 240#if VAX8600
0fe372b3
MK
241 case IO_ABUS:
242 probe_Abus(ioanum, iob);
cb4a08d0
JB
243 break;
244#endif
9a0de372
MK
245
246#if VAX8200
247 case IO_BI:
248 probe_bi((struct bibus *)iob->io_details);
249 break;
250#endif
251
cb4a08d0 252 default:
0fe372b3
MK
253 if (iob->io_addr) {
254 printf(
255 "IO adaptor %d, type %d, at address 0x%x is unsupported\n",
256 ioanum, iob->io_type, iob->io_addr);
cb4a08d0 257 } else
0fe372b3
MK
258 printf("IO adaptor %d, type %d, is unsupported\n",
259 ioanum, iob->io_type);
260 break;
cb4a08d0
JB
261 }
262 }
263}
264
0fe372b3
MK
265#if VAX8600
266probe_Abus(ioanum, iob)
267 register struct iobus *iob;
268{
269 register struct ioa *ioap;
270 union ioacsr ioacsr;
271 int type;
272 struct sbia_regs *sbiaregs;
9a0de372
MK
273#ifdef notyet
274 int sbi1fail(), sbi1alert(), sbi1fault(), sbi1err();
275#endif
0fe372b3
MK
276
277 ioap = &ioa[ioanum];
121c4a08 278 ioaccess(iob->io_addr, Ioamap[ioanum], iob->io_size);
0fe372b3
MK
279 if (badaddr((caddr_t)ioap, 4))
280 return;
281 ioacsr.ioa_csr = ioap->ioacsr.ioa_csr;
282 type = ioacsr.ioa_type & IOA_TYPMSK;
283
284 switch (type) {
285
286 case IOA_SBIA:
287 printf("SBIA%d at IO adaptor %d address 0x%x\n",
288 nsbi, ioanum, iob->io_addr);
9a0de372
MK
289#ifdef notyet
290 /* I AM NOT SURE THESE ARE IN THE SAME PLACES */
291 if (nscb == 1) {
292 scb[1].scb_sbifail = scbentry(sbi1fail, SCB_ISTACK);
293 /* maybe not sbifail, maybe scb1.scb_cmrd */
294 /* but how can I find out without a broken SBIA1? */
295 scb[1].scb_sbialert = scbentry(sbi1alert, SCB_ISTACK);
296 scb[1].scb_sbifault = scbentry(sbi1fault, SCB_ISTACK);
297 scb[1].scb_sbierr = scbentry(sbi1err, SCB_ISTACK);
298 }
299#endif
0fe372b3
MK
300 probenexi((struct nexusconnect *)iob->io_details);
301 nsbi++;
302 sbiaregs = (struct sbia_regs *)ioap;
303 sbiaregs->sbi_errsum = -1;
304 sbiaregs->sbi_error = 0x1000;
305 sbiaregs->sbi_fltsts = 0xc0000;
306 break;
307
308 default:
309 printf("IOA%d at address 0x%x is unsupported (type = 0x%x)\n",
310 ioanum, iob->io_addr, ioacsr.ioa_type);
311 break;
312 }
313}
314#endif
315
03d3d455 316#if VAX8600 || VAX780 || VAX750 || VAX730
327f6ec8 317/*
b17fedcd
BJ
318 * Probe nexus space, finding the interconnects
319 * and setting up and probing mba's and uba's for devices.
327f6ec8 320 */
0fe372b3
MK
321probenexi(pnc)
322 register struct nexusconnect *pnc;
327f6ec8
BJ
323{
324 register struct nexus *nxv;
0fe372b3 325 struct nexus *nxp = pnc->psb_nexbase;
327f6ec8 326 union nexcsr nexcsr;
e83ccfd7 327 int i;
9a0de372
MK
328
329 ioaccess((caddr_t)nxp, Nexmap[nsbi * NNEXSBI],
330 pnc->psb_nnexus * sizeof(struct nexus));
331 nxv = &nexus[nsbi * NNEXSBI];
332 for (nexnum = 0; nexnum < pnc->psb_nnexus; nexnum++, nxp++, nxv++) {
327f6ec8
BJ
333 if (badaddr((caddr_t)nxv, 4))
334 continue;
0fe372b3
MK
335 if (pnc->psb_nextype && pnc->psb_nextype[nexnum] != NEX_ANY)
336 nexcsr.nex_csr = pnc->psb_nextype[nexnum];
b17fedcd
BJ
337 else
338 nexcsr = nxv->nexcsr;
327f6ec8
BJ
339 if (nexcsr.nex_csr&NEX_APD)
340 continue;
327f6ec8
BJ
341 switch (nexcsr.nex_type) {
342
343 case NEX_MBA:
8d2ea14f 344 printf("mba%d at tr%d\n", nummba, nexnum);
a7e7fa7e 345 if (nummba >= NMBA) {
9a0de372 346 printf("%d mba's", ++nummba);
a0eab615 347 goto unconfig;
a7e7fa7e 348 }
d565635a 349#if NMBA > 0
3f3a34c3 350 mbafind(nxv, nxp);
5aa9d5ea 351 nummba++;
47fa50b1 352#endif
d565635a 353 break;
327f6ec8
BJ
354
355 case NEX_UBA0:
356 case NEX_UBA1:
357 case NEX_UBA2:
358 case NEX_UBA3:
d565635a 359 printf("uba%d at tr%d\n", numuba, nexnum);
9a0de372
MK
360 if (numuba >= NUBA) {
361 printf("%d uba's", ++numuba);
362 goto unconfig;
363 }
364#if NUBA > 0
e870748a 365#if VAX750
9b95def8
MK
366 if (numuba >= 2 && cpu == VAX_750) {
367 printf("More than 2 UBA's");
3f3a34c3
BJ
368 goto unsupp;
369 }
9b95def8 370#endif
cb4a08d0 371#if defined(VAX780) || defined(VAX8600)
9a0de372 372 if (cpu == VAX_780 || cpu == VAX_8600)
e83ccfd7
BJ
373 setscbnex(ubaintv[numuba]);
374#endif
3f3a34c3 375 i = nexcsr.nex_type - NEX_UBA0;
03d3d455
MK
376 probeuba((struct uba_regs *)nxv, (struct uba_regs *)nxp,
377 pnc->psb_umaddr[i]);
9a0de372 378#endif /* NUBA */
327f6ec8
BJ
379 break;
380
381 case NEX_DR32:
5aa9d5ea 382 /* there can be more than one... are there other codes??? */
327f6ec8
BJ
383 printf("dr32");
384 goto unsupp;
385
386 case NEX_MEM4:
387 case NEX_MEM4I:
388 case NEX_MEM16:
389 case NEX_MEM16I:
2d192058 390 printf("mcr%d at tr%d\n", nmcr, nexnum);
9a0de372
MK
391 if (nmcr >= MAXNMCR) {
392 printf("%d mcr's", ++nmcr);
393 goto unconfig;
2d192058
MK
394 }
395 switch (cpu) {
9a0de372 396#if VAX780
2d192058 397 case VAX_780:
9a0de372 398 /* only ka780 code looks at type */
2d192058
MK
399 mcrtype[nmcr] = M780C;
400 break;
9a0de372
MK
401#endif
402 default:
2d192058
MK
403 break;
404 }
9a0de372 405 mcraddr[nmcr++] = (caddr_t)nxv;
2d192058
MK
406 break;
407
9a0de372 408#if VAX780
2d192058 409 case NEX_MEM64I:
096eb64d
SL
410 case NEX_MEM64L:
411 case NEX_MEM64LI:
96f412b7
JB
412 case NEX_MEM256I:
413 case NEX_MEM256L:
414 case NEX_MEM256LI:
2d192058 415 printf("mcr%d (el) at tr%d\n", nmcr, nexnum);
9a0de372
MK
416 if (nmcr >= MAXNMCR) {
417 printf("%d mcr's", ++nmcr);
418 goto unconfig;
2d192058 419 }
9a0de372
MK
420 mcrtype[nmcr] = M780EL;
421 mcraddr[nmcr++] = (caddr_t)nxv;
96f412b7 422 if (nexcsr.nex_type != NEX_MEM64I &&
9a0de372 423 nexcsr.nex_type != NEX_MEM256I)
2d192058
MK
424 break;
425 /* fall into ... */
426
096eb64d
SL
427 case NEX_MEM64U:
428 case NEX_MEM64UI:
96f412b7
JB
429 case NEX_MEM256U:
430 case NEX_MEM256UI:
2d192058 431 printf("mcr%d (eu) at tr%d\n", nmcr, nexnum);
9a0de372
MK
432 if (nmcr >= MAXNMCR) {
433 printf("%d mcr's", ++nmcr);
434 goto unconfig;
3f3a34c3 435 }
9a0de372
MK
436 mcrtype[nmcr] = M780EU;
437 mcraddr[nmcr++] = (caddr_t)nxv;
327f6ec8 438 break;
9a0de372 439#endif
327f6ec8
BJ
440
441 case NEX_MPM0:
442 case NEX_MPM1:
443 case NEX_MPM2:
444 case NEX_MPM3:
445 printf("mpm");
446 goto unsupp;
447
096eb64d
SL
448 case NEX_CI:
449 printf("ci");
450 goto unsupp;
451
327f6ec8
BJ
452 default:
453 printf("nexus type %x", nexcsr.nex_type);
30d13fef 454unsupp:
3f3a34c3 455 printf(" unsupported (at tr %d)\n", nexnum);
327f6ec8 456 continue;
d565635a
BJ
457unconfig:
458 printf(" not configured\n");
459 continue;
327f6ec8
BJ
460 }
461 }
9b95def8
MK
462 if (nummba > NMBA)
463 nummba = NMBA;
464 if (numuba > NUBA)
465 numuba = NUBA;
9a0de372
MK
466 if (nmcr > MAXNMCR)
467 nmcr = MAXNMCR;
327f6ec8 468}
30d13fef 469
03d3d455
MK
470setscbnex(fn)
471 int (*fn)();
472{
9a0de372 473 register struct scb *scbp = &scb[nsbi];
03d3d455 474
03d3d455
MK
475 scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
476 scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
477 scbentry(fn, SCB_ISTACK);
478}
479#endif
480
9a0de372
MK
481#include "bi.h"
482#if NBI > 0
483/*
484 * Probe BI node space.
485 *
486 * THIS DEPENDS ON BI SPACE == NEXUS SPACE
487 * THIS WILL NOT WORK FOR MULTIPLE BIs
488 */
489probe_bi(p)
490 register struct bibus *p;
491{
492 register struct bi_node *biv, *bip;
493 register int node;
494 short dtype;
495
496 /* must ignore BI errors while configuring */
497 bip = p->pbi_base;
498 ioaccess((caddr_t)bip, Nexmap[0], sizeof(*bip) * NNODEBI);/* XXX */
499 printf("vaxbi0 at address 0x%x\n", bip);
500 biv = (struct bi_node *) &nexus[0]; /* XXX */
501 for (node = 0; node < NNODEBI; node++, bip++, biv++) {
502 if (badaddr((caddr_t)biv, 4))
503 continue;
504 bi_nodes |= 1 << node; /* XXX */
505 dtype = biv->biic.bi_dtype;
506 /* clear bus errors */
507 biv->biic.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);
508 switch (dtype) {
509
510 case BIDT_KA820: {
511 /* is this right?? */
512 int cp5 = biv->biic.bi_revs & 0x8000 ? '5' : '0';
513
514 if (node != mastercpu) {
515 printf("slave ka82%c cpu", cp5);
516 goto unsupp;
517 }
518 printf("ka82%c cpu at node %x\n", cp5, node);
519 biv->biic.bi_intrdes = 1 << mastercpu;
520 biv->biic.bi_csr |= BICSR_SEIE | BICSR_HEIE;
521 break;
522 }
523
524 case BIDT_DWBUA:
525 if (numuba >= NUBA || /*XXX*/numuba > 2) {
526 printf("%d uba's", ++numuba);
527 goto unconfig;
528 }
529#if NUBA > 0
530 printf("uba%d at node %x\n", numuba, node);
531
532 /*
533 * Run a self test reset to drop any `old' errors,
534 * so that they cannot cause a BI bus error.
535 */
536 (void) bi_selftest(&biv->biic);
537
538 /*
539 * Enable interrupts. DWBUAs must have
540 * high priority.
541 */
542 biv->biic.bi_intrdes = 1 << mastercpu;
543 biv->biic.bi_csr = (biv->biic.bi_csr&~BICSR_ARB_MASK) |
544 BICSR_ARB_HIGH;
545 probeuba((struct uba_regs *)biv, (struct uba_regs *)bip,
546 (caddr_t)UMEM8200(node));
547#endif /* NUBA */
548 break;
549
550 case BIDT_MS820:
551 printf("mcr%d at node %x\n", nmcr, node);
552 if (nmcr >= MAXNMCR) {
553 printf("%d mcr's", ++nmcr);
554 goto unconfig;
555 }
556 mcraddr[nmcr++] = (caddr_t)biv;
557 biv->biic.bi_intrdes = 1 << mastercpu;
558 biv->biic.bi_csr |= BICSR_SEIE | BICSR_HEIE;
559 break;
560
561 case BIDT_KDB50:
562 if (numkdb >= NKDB) {
563 printf("%d kdb's", ++numkdb);
564 goto unconfig;
565 }
566#if NKDB > 0
567 printf("kdb%d at node %x\n", numkdb, node);
568 kdbconfig(numkdb, (struct biiregs *)biv,
569 (struct biiregs *)bip,
570 (int)&scb[0].scb_ipl15[node] - (int)&scb[0]);
571 scb[0].scb_ipl15[node] =
572 scbentry(kdbintv[numkdb], SCB_ISTACK);
573 kdbfind(numkdb);
574#endif
575 numkdb++;
576 break;
577
578 case BIDT_DEBNA:
579 case BIDT_DEBNK:
580 printf("debna/debnk ethernet");
581 goto unsupp;
582
583 default:
584 printf("node type 0x%x ", dtype);
585unsupp:
586 printf(" unsupported (at node %x)\n", node);
587 break;
588unconfig:
589 printf(" not configured (at node %x)\n", node);
590 continue;
591 }
592#ifdef DO_EINTRCSR
593 biv->biic.bi_eintrcsr = BIEIC_IPL17 |
594 (int)&scb[0].scb_bierr - (int)&scb[0];
595 /* but bi reset will need to restore this */
596#endif
597 }
598 if (numuba > NUBA)
599 numuba = NUBA;
600 if (numkdb > NKDB)
601 numkdb = NKDB;
602 if (nmcr > MAXNMCR)
603 nmcr = MAXNMCR;
604}
605
606#if NKDB > 0
607/*
608 * Find drives attached to a particular KDB50.
609 */
610kdbfind(kdbnum)
611 int kdbnum;
612{
613 extern struct uba_driver kdbdriver;
614 register struct uba_device *ui;
615 register struct uba_driver *udp = &kdbdriver;
616 int t;
617
618 for (ui = ubdinit; ui->ui_driver; ui++) {
619 /* ui->ui_ubanum is trash */
620 if (ui->ui_driver != udp || ui->ui_alive ||
621 ui->ui_ctlr != kdbnum && ui->ui_ctlr != '?')
622 continue;
623 t = ui->ui_ctlr;
624 ui->ui_ctlr = kdbnum;
625 if ((*udp->ud_slave)(ui) == 0) {
626 ui->ui_ctlr = t;
627 continue;
628 }
629 ui->ui_alive = 1;
630 ui->ui_ubanum = -1;
631
632 /* make these invalid so we can see if someone uses them */
633 /* might as well make each one different too */
634 ui->ui_hd = (struct uba_hd *)0xc0000010;
635 ui->ui_addr = (caddr_t)0xc0000014;
636 ui->ui_physaddr = (caddr_t)0xc0000018;
637 ui->ui_mi = (struct uba_ctlr *)0xc000001c;
638
639 if (ui->ui_dk && dkn < DK_NDRIVE)
640 ui->ui_dk = dkn++;
641 else
642 ui->ui_dk = -1;
643 /* ui_type comes from driver */
644 udp->ud_dinfo[ui->ui_unit] = ui;
645 printf("%s%d at %s%d slave %d\n",
646 udp->ud_dname, ui->ui_unit,
647 udp->ud_mname, ui->ui_ctlr, ui->ui_slave);
648 (*udp->ud_attach)(ui);
649 }
650}
651#endif /* NKDB > 0 */
652#endif /* NBI > 0 */
653
47fa50b1 654#if NMBA > 0
b721b0ed 655struct mba_device *mbaconfig();
327f6ec8
BJ
656/*
657 * Find devices attached to a particular mba
658 * and look for each device found in the massbus
659 * initialization tables.
660 */
3f3a34c3 661mbafind(nxv, nxp)
30d13fef 662 struct nexus *nxv, *nxp;
327f6ec8
BJ
663{
664 register struct mba_regs *mdp;
665 register struct mba_drv *mbd;
b721b0ed
BJ
666 register struct mba_device *mi;
667 register struct mba_slave *ms;
299100bf 668 int dn, dt, sn;
a0eab615 669 struct mba_device fnd;
327f6ec8 670
3f3a34c3 671 mdp = (struct mba_regs *)nxv;
5aa9d5ea
RE
672 mba_hd[nummba].mh_mba = mdp;
673 mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
a0eab615 674 setscbnex(mbaintv[nummba]);
3761a96c
MK
675 mdp->mba_cr = MBCR_INIT;
676 mdp->mba_cr = MBCR_IE;
327f6ec8 677 fnd.mi_mba = mdp;
5aa9d5ea 678 fnd.mi_mbanum = nummba;
327f6ec8 679 for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
0cf493bf
BJ
680 if ((mbd->mbd_ds&MBDS_DPR) == 0)
681 continue;
51ee2ebf 682 mdp->mba_sr |= MBSR_NED; /* si kludge */
327f6ec8
BJ
683 dt = mbd->mbd_dt & 0xffff;
684 if (dt == 0)
685 continue;
51ee2ebf
BJ
686 if (mdp->mba_sr&MBSR_NED)
687 continue; /* si kludge */
327f6ec8
BJ
688 if (dt == MBDT_MOH)
689 continue;
690 fnd.mi_drive = dn;
299100bf
RE
691#define qeq(a, b) ( a == b || a == '?' )
692 if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP))
693 for (sn = 0; sn < 8; sn++) {
694 mbd->mbd_tc = sn;
695 for (ms = mbsinit; ms->ms_driver; ms++)
696 if (ms->ms_driver == mi->mi_driver &&
697 ms->ms_alive == 0 &&
698 qeq(ms->ms_ctlr, mi->mi_unit) &&
699 qeq(ms->ms_slave, sn) &&
700 (*ms->ms_driver->md_slave)(mi, ms, sn)) {
701 printf("%s%d at %s%d slave %d\n"
702 , ms->ms_driver->md_sname
703 , ms->ms_unit
704 , mi->mi_driver->md_dname
705 , mi->mi_unit
706 , sn
707 );
d565635a
BJ
708 ms->ms_alive = 1;
709 ms->ms_ctlr = mi->mi_unit;
299100bf 710 ms->ms_slave = sn;
1d25441f 711 break;
b721b0ed 712 }
299100bf 713 }
327f6ec8
BJ
714 }
715}
716
717/*
718 * Have found a massbus device;
719 * see if it is in the configuration table.
720 * If so, fill in its data.
721 */
b721b0ed 722struct mba_device *
327f6ec8 723mbaconfig(ni, type)
b721b0ed 724 register struct mba_device *ni;
327f6ec8
BJ
725 register int type;
726{
b721b0ed 727 register struct mba_device *mi;
327f6ec8 728 register short *tp;
71236e46 729 register struct mba_hd *mh;
327f6ec8 730
b721b0ed 731 for (mi = mbdinit; mi->mi_driver; mi++) {
327f6ec8
BJ
732 if (mi->mi_alive)
733 continue;
734 tp = mi->mi_driver->md_type;
735 for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
295446f8 736 if (*tp == (type&MBDT_TYPE))
327f6ec8
BJ
737 goto found;
738 continue;
739found:
740#define match(fld) (ni->fld == mi->fld || mi->fld == '?')
b721b0ed 741 if (!match(mi_drive) || !match(mi_mbanum))
327f6ec8 742 continue;
54c92e75 743 printf("%s%d at mba%d drive %d",
b721b0ed
BJ
744 mi->mi_driver->md_dname, mi->mi_unit,
745 ni->mi_mbanum, ni->mi_drive);
327f6ec8 746 mi->mi_alive = 1;
71236e46
BJ
747 mh = &mba_hd[ni->mi_mbanum];
748 mi->mi_hd = mh;
749 mh->mh_mbip[ni->mi_drive] = mi;
750 mh->mh_ndrive++;
327f6ec8
BJ
751 mi->mi_mba = ni->mi_mba;
752 mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
327f6ec8
BJ
753 mi->mi_mbanum = ni->mi_mbanum;
754 mi->mi_drive = ni->mi_drive;
0d7a9a27
SL
755 /*
756 * If drive has never been seen before,
757 * give it a dkn for statistics.
758 */
759 if (mi->mi_driver->md_info[mi->mi_unit] == 0) {
760 mi->mi_driver->md_info[mi->mi_unit] = mi;
761 if (mi->mi_dk && dkn < DK_NDRIVE)
762 mi->mi_dk = dkn++;
763 else
764 mi->mi_dk = -1;
765 }
b721b0ed 766 (*mi->mi_driver->md_attach)(mi);
54c92e75 767 printf("\n");
b721b0ed 768 return (mi);
327f6ec8 769 }
b721b0ed 770 return (0);
327f6ec8 771}
47fa50b1 772#endif
327f6ec8 773
3f3a34c3 774/*
30d13fef
BJ
775 * Fixctlrmask fixes the masks of the driver ctlr routines
776 * which otherwise save r10 and r11 where the interrupt and br
777 * level are passed through.
778 */
779fixctlrmask()
780{
b721b0ed
BJ
781 register struct uba_ctlr *um;
782 register struct uba_device *ui;
30d13fef
BJ
783 register struct uba_driver *ud;
784#define phys(a,b) ((b)(((int)(a))&0x7fffffff))
785
786 for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
71236e46 787 *phys(ud->ud_probe, short *) &= ~0xc00;
30d13fef 788 for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
71236e46 789 *phys(ud->ud_probe, short *) &= ~0xc00;
30d13fef
BJ
790}
791
9a0de372 792#ifdef QBA
03d3d455
MK
793/*
794 * Configure a Q-bus.
795 */
796probeqbus(qb)
797 struct qbus *qb;
798{
799 register struct uba_hd *uhp = &uba_hd[numuba];
800
9a0de372
MK
801 ioaccess((caddr_t)qb->qb_map, Nexmap[0],
802 qb->qb_memsize * sizeof (struct pte));
03d3d455
MK
803 uhp->uh_type = qb->qb_type;
804 uhp->uh_uba = (struct uba_regs *)0xc0000000; /* no uba adaptor regs */
805 uhp->uh_mr = (struct pte *)&nexus[0];
806 /*
807 * The map registers start right at 20088000 on the
808 * ka630, so we have to subtract out the 2k offset to make the
809 * pointers work..
810 */
811 uhp->uh_physuba = (struct uba_regs *)(((u_long)qb->qb_map)-0x800);
812
813 uhp->uh_memsize = qb->qb_memsize;
814 ioaccess(qb->qb_maddr, UMEMmap[numuba], uhp->uh_memsize * NBPG);
815 uhp->uh_mem = umem[numuba];
816
817 /*
818 * The I/O page is mapped to the 8K of the umem address space
819 * immediately after the memory section that is mapped.
820 */
821 ioaccess(qb->qb_iopage, UMEMmap[numuba] + uhp->uh_memsize,
822 UBAIOPAGES * NBPG);
823 uhp->uh_iopage = umem[numuba] + (uhp->uh_memsize * NBPG);
824
825 unifind(uhp, qb->qb_iopage);
826}
827#endif
828
9a0de372 829#if NUBA > 0
03d3d455
MK
830probeuba(vubp, pubp, pumem)
831 struct uba_regs *vubp, *pubp;
832 caddr_t pumem;
833{
834 register struct uba_hd *uhp = &uba_hd[numuba];
03d3d455
MK
835
836 /*
837 * Save virtual and physical addresses of adaptor.
838 */
839 switch (cpu) {
840#ifdef DW780
841 case VAX_8600:
842 case VAX_780:
843 uhp->uh_type = DW780;
844 break;
845#endif
846#ifdef DW750
847 case VAX_750:
848 uhp->uh_type = DW750;
849 break;
850#endif
851#ifdef DW730
852 case VAX_730:
853 uhp->uh_type = DW730;
854 break;
9a0de372
MK
855#endif
856#ifdef DWBUA
857 case VAX_8200:
858 uhp->uh_type = DWBUA;
859 break;
03d3d455
MK
860#endif
861 default:
862 panic("unknown UBA type");
863 /*NOTREACHED*/
864 }
865 uhp->uh_uba = vubp;
866 uhp->uh_physuba = pubp;
867 uhp->uh_mr = vubp->uba_map;
868 uhp->uh_memsize = UBAPAGES;
869
870 ioaccess(pumem, UMEMmap[numuba], (UBAPAGES + UBAIOPAGES) * NBPG);
871 uhp->uh_mem = umem[numuba];
872 uhp->uh_iopage = umem[numuba] + (uhp->uh_memsize * NBPG);
873
874 unifind(uhp, pumem + (uhp->uh_memsize * NBPG));
875}
876
30d13fef
BJ
877/*
878 * Find devices on a UNIBUS.
879 * Uses per-driver routine to set <br,cvec> into <r11,r10>,
880 * and then fills in the tables, with help from a per-driver
881 * slave initialization routine.
3f3a34c3 882 */
03d3d455
MK
883unifind(uhp0, pumem)
884 struct uba_hd *uhp0;
885 caddr_t pumem;
327f6ec8 886{
a0eab615 887#ifndef lint
30d13fef 888 register int br, cvec; /* MUST BE r11, r10 */
a0eab615
BJ
889#else
890 /*
891 * Lint doesn't realize that these
892 * can be initialized asynchronously
893 * when devices interrupt.
894 */
895 register int br = 0, cvec = 0;
896#endif
b721b0ed
BJ
897 register struct uba_device *ui;
898 register struct uba_ctlr *um;
03d3d455 899 register struct uba_hd *uhp = uhp0;
299100bf 900 u_short *reg, *ap, addr;
327f6ec8 901 struct uba_driver *udp;
cb4a08d0 902 int i, (**ivec)();
4cbd6917 903 caddr_t ualloc;
9a0de372
MK
904 extern quad catcher[128];
905#if DW780 || DWBUA
03d3d455 906 struct uba_regs *vubp = uhp->uh_uba;
90dc7048 907#endif
03d3d455 908
30d13fef
BJ
909 /*
910 * Initialize the UNIBUS, by freeing the map
911 * registers and the buffered data path registers
912 */
fcba03fb 913 uhp->uh_map = (struct map *)
9340d736
MK
914 malloc((u_long)(UAMSIZ * sizeof (struct map)), M_DEVBUF,
915 M_NOWAIT);
0a2e2336
KM
916 if (uhp->uh_map == 0)
917 panic("no mem for unibus map");
9340d736 918 bzero((caddr_t)uhp->uh_map, (unsigned)(UAMSIZ * sizeof (struct map)));
9305c2b9 919 ubainitmaps(uhp);
327f6ec8 920
30d13fef 921 /*
9a0de372
MK
922 * Initialize space for the UNIBUS interrupt vectors.
923 * On the 8600, can't use first slot in UNIvec
924 * (the vectors for the second SBI overlap it);
925 * move each set of vectors forward.
121c4a08 926 */
03d3d455 927#if VAX8600
cb4a08d0 928 if (cpu == VAX_8600)
9a0de372 929 uhp->uh_vec = UNIvec[numuba + 1];
03d3d455
MK
930 else
931#endif
9a0de372 932 uhp->uh_vec = UNIvec[numuba];
30d13fef 933 for (i = 0; i < 128; i++)
9a0de372 934 uhp->uh_vec[i] = scbentry(&catcher[i], SCB_ISTACK);
64614526
BJ
935 /*
936 * Set last free interrupt vector for devices with
937 * programmable interrupt vectors. Use is to decrement
938 * this number and use result as interrupt vector.
939 */
940 uhp->uh_lastiv = 0x200;
941
9a0de372
MK
942#ifdef DWBUA
943 if (uhp->uh_type == DWBUA)
944 BUA(vubp)->bua_offset = (int)uhp->uh_vec - (int)&scb[0];
945#endif
946
03d3d455
MK
947#ifdef DW780
948 if (uhp->uh_type == DW780) {
30d13fef 949 vubp->uba_sr = vubp->uba_sr;
b721b0ed 950 vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
327f6ec8 951 }
327f6ec8 952#endif
e870748a
MK
953 /*
954 * First configure devices that have unibus memory,
955 * allowing them to allocate the correct map registers.
956 */
957 ubameminit(numuba);
299100bf
RE
958 /*
959 * Grab some memory to record the umem address space we allocate,
960 * so we can be sure not to place two devices at the same address.
961 *
962 * We could use just 1/8 of this (we only want a 1 bit flag) but
963 * we are going to give it back anyway, and that would make the
964 * code here bigger (which we can't give back), so ...
965 *
966 * One day, someone will make a unibus with something other than
967 * an 8K i/o address space, & screw this totally.
968 */
9340d736 969 ualloc = (caddr_t)malloc((u_long)(8 * 1024), M_TEMP, M_NOWAIT);
299100bf
RE
970 if (ualloc == (caddr_t)0)
971 panic("no mem for unifind");
50a8dc53 972 bzero(ualloc, 8*1024);
299100bf 973
30d13fef
BJ
974 /*
975 * Map the first page of UNIBUS i/o
976 * space to the first page of memory
977 * for devices which will need to dma
978 * output to produce an interrupt.
979 */
03d3d455 980 *(int *)(&uhp->uh_mr[0]) = UBAMR_MRV;
30d13fef 981
03d3d455 982#define ubaddr(uhp, off) (u_short *)((int)(uhp)->uh_iopage + ubdevreg(off))
30d13fef
BJ
983 /*
984 * Check each unibus mass storage controller.
985 * For each one which is potentially on this uba,
986 * see if it is really there, and if it is record it and
987 * then go looking for slaves.
988 */
989 for (um = ubminit; udp = um->um_driver; um++) {
9a0de372
MK
990 if (um->um_ubanum != numuba && um->um_ubanum != '?' ||
991 um->um_alive)
30d13fef
BJ
992 continue;
993 addr = (u_short)um->um_addr;
299100bf
RE
994 /*
995 * use the particular address specified first,
996 * or if it is given as "0", of there is no device
997 * at that address, try all the standard addresses
998 * in the driver til we find it
999 */
1000 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
1001
03d3d455 1002 if (ualloc[ubdevreg(addr)])
299100bf 1003 continue;
03d3d455 1004 reg = ubaddr(uhp, addr);
30d13fef 1005 if (badaddr((caddr_t)reg, 2))
327f6ec8 1006 continue;
03d3d455
MK
1007#ifdef DW780
1008 if (uhp->uh_type == DW780 && vubp->uba_sr) {
8d2ea14f
BJ
1009 vubp->uba_sr = vubp->uba_sr;
1010 continue;
30d13fef 1011 }
327f6ec8 1012#endif
30d13fef 1013 cvec = 0x200;
e870748a 1014 i = (*udp->ud_probe)(reg, um->um_ctlr, um);
03d3d455
MK
1015#ifdef DW780
1016 if (uhp->uh_type == DW780 && vubp->uba_sr) {
8d2ea14f
BJ
1017 vubp->uba_sr = vubp->uba_sr;
1018 continue;
30d13fef 1019 }
327f6ec8 1020#endif
30d13fef
BJ
1021 if (i == 0)
1022 continue;
8d2ea14f
BJ
1023 printf("%s%d at uba%d csr %o ",
1024 udp->ud_mname, um->um_ctlr, numuba, addr);
30d13fef
BJ
1025 if (cvec == 0) {
1026 printf("zero vector\n");
1027 continue;
1028 }
1029 if (cvec == 0x200) {
1030 printf("didn't interrupt\n");
1031 continue;
1032 }
8d2ea14f 1033 printf("vec %o, ipl %x\n", cvec, br);
7e949ce2 1034 csralloc(ualloc, addr, i);
30d13fef
BJ
1035 um->um_alive = 1;
1036 um->um_ubanum = numuba;
9a0de372 1037 um->um_hd = uhp;
30d13fef
BJ
1038 um->um_addr = (caddr_t)reg;
1039 udp->ud_minfo[um->um_ctlr] = um;
9a0de372
MK
1040 for (cvec /= 4, ivec = um->um_intr; *ivec; cvec++, ivec++)
1041 uhp->uh_vec[cvec] = scbentry(*ivec, SCB_ISTACK);
30d13fef 1042 for (ui = ubdinit; ui->ui_driver; ui++) {
9a0de372
MK
1043 int t;
1044
30d13fef
BJ
1045 if (ui->ui_driver != udp || ui->ui_alive ||
1046 ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
1047 ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
327f6ec8 1048 continue;
9a0de372
MK
1049 t = ui->ui_ctlr;
1050 ui->ui_ctlr = um->um_ctlr;
1051 if ((*udp->ud_slave)(ui, reg) == 0)
1052 ui->ui_ctlr = t;
1053 else {
30d13fef 1054 ui->ui_alive = 1;
30d13fef 1055 ui->ui_ubanum = numuba;
9a0de372 1056 ui->ui_hd = uhp;
30d13fef 1057 ui->ui_addr = (caddr_t)reg;
ddbbb5fb 1058 ui->ui_physaddr = pumem + ubdevreg(addr);
8d2ea14f 1059 if (ui->ui_dk && dkn < DK_NDRIVE)
0801d37f 1060 ui->ui_dk = dkn++;
8d2ea14f
BJ
1061 else
1062 ui->ui_dk = -1;
30d13fef
BJ
1063 ui->ui_mi = um;
1064 /* ui_type comes from driver */
1065 udp->ud_dinfo[ui->ui_unit] = ui;
9a0de372 1066 printf("%s%d at %s%d slave %d",
8d2ea14f
BJ
1067 udp->ud_dname, ui->ui_unit,
1068 udp->ud_mname, um->um_ctlr, ui->ui_slave);
71236e46 1069 (*udp->ud_attach)(ui);
9a0de372 1070 printf("\n");
327f6ec8 1071 }
30d13fef 1072 }
299100bf
RE
1073 break;
1074 }
30d13fef
BJ
1075 }
1076 /*
1077 * Now look for non-mass storage peripherals.
1078 */
1079 for (ui = ubdinit; udp = ui->ui_driver; ui++) {
1080 if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
1081 ui->ui_alive || ui->ui_slave != -1)
1082 continue;
1083 addr = (u_short)ui->ui_addr;
299100bf
RE
1084
1085 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
1086
03d3d455 1087 if (ualloc[ubdevreg(addr)])
299100bf 1088 continue;
03d3d455 1089 reg = ubaddr(uhp, addr);
30d13fef
BJ
1090 if (badaddr((caddr_t)reg, 2))
1091 continue;
03d3d455
MK
1092#ifdef DW780
1093 if (uhp->uh_type == DW780 && vubp->uba_sr) {
8d2ea14f
BJ
1094 vubp->uba_sr = vubp->uba_sr;
1095 continue;
30d13fef
BJ
1096 }
1097#endif
1098 cvec = 0x200;
e870748a 1099 i = (*udp->ud_probe)(reg, ui);
03d3d455
MK
1100#ifdef DW780
1101 if (uhp->uh_type == DW780 && vubp->uba_sr) {
8d2ea14f
BJ
1102 vubp->uba_sr = vubp->uba_sr;
1103 continue;
327f6ec8 1104 }
30d13fef
BJ
1105#endif
1106 if (i == 0)
1107 continue;
8d2ea14f
BJ
1108 printf("%s%d at uba%d csr %o ",
1109 ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
30d13fef
BJ
1110 if (cvec == 0) {
1111 printf("zero vector\n");
1112 continue;
1113 }
1114 if (cvec == 0x200) {
1115 printf("didn't interrupt\n");
1116 continue;
1117 }
8d2ea14f 1118 printf("vec %o, ipl %x\n", cvec, br);
7e949ce2 1119 csralloc(ualloc, addr, i);
9a0de372
MK
1120 ui->ui_hd = uhp;
1121 for (cvec /= 4, ivec = ui->ui_intr; *ivec; cvec++, ivec++)
1122 uhp->uh_vec[cvec] = scbentry(*ivec, SCB_ISTACK);
30d13fef
BJ
1123 ui->ui_alive = 1;
1124 ui->ui_ubanum = numuba;
1125 ui->ui_addr = (caddr_t)reg;
ddbbb5fb 1126 ui->ui_physaddr = pumem + ubdevreg(addr);
8d2ea14f 1127 ui->ui_dk = -1;
30d13fef
BJ
1128 /* ui_type comes from driver */
1129 udp->ud_dinfo[ui->ui_unit] = ui;
71236e46 1130 (*udp->ud_attach)(ui);
299100bf
RE
1131 break;
1132 }
327f6ec8 1133 }
299100bf 1134
03d3d455
MK
1135#ifdef DW780
1136 if (uhp->uh_type == DW780)
1137 uhp->uh_uba->uba_cr = UBACR_IFS | UBACR_BRIE |
1138 UBACR_USEFIE | UBACR_SUEFIE |
1139 (uhp->uh_uba->uba_cr & 0x7c000000);
1140#endif
1141 numuba++;
1142
299100bf
RE
1143#ifdef AUTO_DEBUG
1144 printf("Unibus allocation map");
1145 for (i = 0; i < 8*1024; ) {
1146 register n, m;
1147
1148 if ((i % 128) == 0) {
1149 printf("\n%6o:", i);
1150 for (n = 0; n < 128; n++)
1151 if (ualloc[i+n])
1152 break;
1153 if (n == 128) {
1154 i += 128;
1155 continue;
1156 }
1157 }
1158
1159 for (n = m = 0; n < 16; n++) {
1160 m <<= 1;
1161 m |= ualloc[i++];
1162 }
1163
1164 printf(" %4x", m);
1165 }
1166 printf("\n");
1167#endif
1168
4cbd6917 1169 free(ualloc, M_TEMP);
327f6ec8 1170}
9a0de372 1171#endif /* NUBA */
327f6ec8 1172
7e949ce2
MK
1173/*
1174 * Mark addresses starting at "addr" and continuing
1175 * "size" bytes as allocated in the map "ualloc".
1176 * Warn if the new allocation overlaps a previous allocation.
1177 */
1178static
1179csralloc(ualloc, addr, size)
1180 caddr_t ualloc;
1181 u_short addr;
1182 register int size;
1183{
1184 register caddr_t p;
1185 int warned = 0;
1186
1187 p = &ualloc[ubdevreg(addr+size)];
1188 while (--size >= 0) {
1189 if (*--p && !warned) {
1190 printf(
1191 "WARNING: device registers overlap those for a previous device!\n");
1192 warned = 1;
1193 }
1194 *p = 1;
1195 }
1196}
1197
327f6ec8 1198/*
0fe372b3 1199 * Make an IO register area accessible at physical address physa
327f6ec8 1200 * by mapping kernel ptes starting at pte.
327f6ec8 1201 */
121c4a08 1202ioaccess(physa, pte, size)
0fe372b3 1203 caddr_t physa;
327f6ec8 1204 register struct pte *pte;
cb4a08d0 1205 int size;
327f6ec8 1206{
03d3d455 1207 register int i = btoc(size);
30d13fef 1208 register unsigned v = btop(physa);
327f6ec8
BJ
1209
1210 do
1211 *(int *)pte++ = PG_V|PG_KW|v++;
a0eab615 1212 while (--i > 0);
327f6ec8
BJ
1213 mtpr(TBIA, 0);
1214}
1c1f6ecf 1215
9f0281aa
SL
1216/*
1217 * Configure swap space and related parameters.
1218 */
dd94cc44 1219#ifndef SECSIZE
9f0281aa
SL
1220swapconf()
1221{
1222 register struct swdevt *swp;
220ebf99 1223 register int nblks;
9f0281aa 1224
dd94cc44 1225 for (swp = swdevt; swp->sw_dev; swp++)
e766bd61 1226 if (bdevsw[major(swp->sw_dev)].d_psize) {
220ebf99 1227 nblks =
dd94cc44 1228 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
3761a96c
MK
1229 if (nblks != -1 &&
1230 (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
e766bd61
MK
1231 swp->sw_nblks = nblks;
1232 }
6348b4d1 1233 if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
e766bd61 1234 dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem;
9f0281aa
SL
1235 if (dumplo < 0)
1236 dumplo = 0;
9f0281aa 1237}
dd94cc44
MK
1238#else SECSIZE
1239swapconf()
1240{
1241 register struct swdevt *swp;
1242 register int nblks;
1243 register int bsize;
1244 struct partinfo dpart;
1245
1246 for (swp = swdevt; swp->sw_dev; swp++)
1247 if ((nblks = psize(swp->sw_dev, &swp->sw_blksize,
1248 &swp->sw_bshift)) != -1 &&
1249 (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
1250 swp->sw_nblks = nblks;
1251
1252 if (!cold) /* In case called for addition of another drive */
1253 return;
1254 if (dumplo == 0) {
1255 nblks = psize(dumpdev, (int *)0, (int *)0);
1256 if (nblks == -1 || nblks < ctod(physmem))
1257 dumplo = 0;
1258 else
1259 dumplo = nblks - ctod(physmem);
1260 }
1261}
1262
1263/*
1264 * Return size of disk partition in DEV_BSIZE units.
1265 * If needed, return sector size.
1266 */
1267psize(dev, psize, pshift)
1268 register dev_t dev;
1269 int *psize, *pshift;
1270{
1271 register int nblks, bsize, bshift;
1272 struct partinfo dpart;
1273
1274 if ((*bdevsw[major(dev)].d_ioctl)(dev, DIOCGPART,
1275 (caddr_t)&dpart, FREAD) == 0)
1276 bsize = dpart.disklab->d_secsize;
1277 else
1278 bsize = DEV_BSIZE;
1279 if (psize)
1280 *psize = bsize;
1281 bshift = 0;
1282 for (nblks = DEV_BSIZE / bsize; nblks > 1; nblks >>= 1)
1283 bshift++;
1284 if (pshift)
1285 *pshift = bshift;
1286 nblks = -1;
1287 if (bdevsw[major(dev)].d_psize) {
1288 nblks = (*bdevsw[major(dev)].d_psize)(dev);
1289 if (nblks != -1)
1290 nblks >>= bshift;
1291 }
1292 return (nblks);
1293}
1294#endif SECSIZE
42b84df5
MK
1295
1296#define DOSWAP /* Change swdevt, argdev, and dumpdev too */
1297u_long bootdev; /* should be dev_t, but not until 32 bits */
1298
1299static char devname[][2] = {
1300 'h','p', /* 0 = hp */
1301 0,0, /* 1 = ht */
1302 'u','p', /* 2 = up */
1303 'r','k', /* 3 = hk */
1304 0,0, /* 4 = sw */
1305 0,0, /* 5 = tm */
1306 0,0, /* 6 = ts */
1307 0,0, /* 7 = mt */
1308 0,0, /* 8 = tu */
1309 'r','a', /* 9 = ra */
1310 0,0, /* 10 = ut */
1311 'r','b', /* 11 = rb */
1312 0,0, /* 12 = uu */
1313 0,0, /* 13 = rx */
1314 'r','l', /* 14 = rl */
9a0de372
MK
1315 0,0, /* 15 = tmscp */
1316 'k','r', /* 16 = ra on kdb50 */
42b84df5
MK
1317};
1318
1319#define PARTITIONMASK 0x7
1320#define PARTITIONSHIFT 3
1321
1322/*
1323 * Attempt to find the device from which we were booted.
1324 * If we can do so, and not instructed not to do so,
1325 * change rootdev to correspond to the load device.
1326 */
1327setroot()
1328{
8371001a 1329 int majdev, mindev, unit, part, controller, adaptor;
42b84df5
MK
1330 dev_t temp, orootdev;
1331 struct swdevt *swp;
1332
90dc7048
BK
1333 if (boothowto & RB_DFLTROOT ||
1334 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
25cfc74b 1335 return;
8371001a
MK
1336 majdev = B_TYPE(bootdev);
1337 if (majdev >= sizeof(devname) / sizeof(devname[0]))
25cfc74b 1338 return;
8371001a
MK
1339 adaptor = B_ADAPTOR(bootdev);
1340 controller = B_CONTROLLER(bootdev);
1341 part = B_PARTITION(bootdev);
1342 unit = B_UNIT(bootdev);
42b84df5 1343 if (majdev == 0) { /* MBA device */
cd97bee2 1344#if NMBA > 0
42b84df5 1345 register struct mba_device *mbap;
cd97bee2 1346 int mask;
42b84df5 1347
cd97bee2
MK
1348/*
1349 * The MBA number used at boot time is not necessarily the same as the
1350 * MBA number used by the kernel. In order to change the rootdev we need to
1351 * convert the boot MBA number to the kernel MBA number. The address space
1352 * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number
1353 * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750.
1354 * Therefore we can search the mba_hd table for the MBA that has the physical
1355 * address corresponding to the boot MBA number.
1356 */
1357#define PHYSADRSHFT 13
1358#define PHYSMBAMASK780 0x7
1359#define PHYSMBAMASK750 0x3
1360
1361 switch (cpu) {
1362
1363 case VAX_780:
1364 case VAX_8600:
1365 default:
1366 mask = PHYSMBAMASK780;
1367 break;
1368
1369 case VAX_750:
1370 mask = PHYSMBAMASK750;
1371 break;
1372 }
42b84df5
MK
1373 for (mbap = mbdinit; mbap->mi_driver; mbap++)
1374 if (mbap->mi_alive && mbap->mi_drive == unit &&
cd97bee2
MK
1375 (((long)mbap->mi_hd->mh_physmba >> PHYSADRSHFT)
1376 & mask) == adaptor)
42b84df5
MK
1377 break;
1378 if (mbap->mi_driver == 0)
25cfc74b 1379 return;
42b84df5 1380 mindev = mbap->mi_unit;
cd97bee2 1381#else
25cfc74b 1382 return;
c5c7e511 1383#endif
cd97bee2 1384 } else {
42b84df5
MK
1385 register struct uba_device *ubap;
1386
1387 for (ubap = ubdinit; ubap->ui_driver; ubap++)
1388 if (ubap->ui_alive && ubap->ui_slave == unit &&
8371001a 1389 ubap->ui_ctlr == controller &&
42b84df5
MK
1390 ubap->ui_ubanum == adaptor &&
1391 ubap->ui_driver->ud_dname[0] == devname[majdev][0] &&
1392 ubap->ui_driver->ud_dname[1] == devname[majdev][1])
1393 break;
1394
1395 if (ubap->ui_driver == 0)
25cfc74b 1396 return;
42b84df5
MK
1397 mindev = ubap->ui_unit;
1398 }
1399 mindev = (mindev << PARTITIONSHIFT) + part;
1400 orootdev = rootdev;
1401 rootdev = makedev(majdev, mindev);
42b84df5
MK
1402 /*
1403 * If the original rootdev is the same as the one
1404 * just calculated, don't need to adjust the swap configuration.
1405 */
1406 if (rootdev == orootdev)
25cfc74b 1407 return;
42b84df5 1408
76eb3c51
MK
1409 printf("Changing root device to %c%c%d%c\n",
1410 devname[majdev][0], devname[majdev][1],
1411 mindev >> PARTITIONSHIFT, part + 'a');
2254a193
MK
1412
1413#ifdef DOSWAP
42b84df5
MK
1414 mindev &= ~PARTITIONMASK;
1415 for (swp = swdevt; swp->sw_dev; swp++) {
1416 if (majdev == major(swp->sw_dev) &&
1417 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
1418 temp = swdevt[0].sw_dev;
1419 swdevt[0].sw_dev = swp->sw_dev;
1420 swp->sw_dev = temp;
1421 break;
1422 }
1423 }
1424 if (swp->sw_dev == 0)
25cfc74b 1425 return;
42b84df5
MK
1426
1427 /*
1428 * If argdev and dumpdev were the same as the old primary swap
1429 * device, move them to the new primary swap device.
1430 */
1431 if (temp == dumpdev)
1432 dumpdev = swdevt[0].sw_dev;
1433 if (temp == argdev)
1434 argdev = swdevt[0].sw_dev;
1435#endif
1436}