1991299c1Sbostic /*-
2991299c1Sbostic * Copyright (c) 1982, 1986 The Regents of the University of California.
3991299c1Sbostic * All rights reserved.
4e93b0568Smckusick *
5991299c1Sbostic * %sccs.include.redist.c%
6991299c1Sbostic *
7*2c107824Storek * @(#)autoconf.c 7.21 (Berkeley) 04/19/93
8e93b0568Smckusick */
909e5bb10Swnj
10b8054636Swnj /*
1184badb11Swnj * Setup the system to run on the current machine.
1284badb11Swnj *
1384badb11Swnj * Configure() is called at boot time and initializes the uba and mba
1484badb11Swnj * device tables and the memory controller monitoring. Available
1584badb11Swnj * devices are determined (from possibilities mentioned in ioconf.c),
1684badb11Swnj * and the drivers are initialized.
17b8054636Swnj */
18b8054636Swnj
19b96bb200Swnj #include "mba.h"
20b79931fcSsam #include "uba.h"
21762ff349Skarels #include "kra.h" /* XXX wrong file */
2264577cdeSbostic #include "bi.h"
23b96bb200Swnj
2464577cdeSbostic #include "sys/param.h"
2564577cdeSbostic #include "sys/systm.h"
2664577cdeSbostic #include "sys/map.h"
2764577cdeSbostic #include "sys/buf.h"
2864577cdeSbostic #include "sys/dkstat.h"
2964577cdeSbostic #include "sys/vm.h"
3064577cdeSbostic #include "sys/malloc.h"
3164577cdeSbostic #include "sys/conf.h"
3264577cdeSbostic #include "sys/dmap.h"
3364577cdeSbostic #include "sys/reboot.h"
34a486872dSroot
3564577cdeSbostic #include "../include/pte.h"
3664577cdeSbostic #include "../include/cpu.h"
37c3ba2265Sbloom #include "mem.h"
3864577cdeSbostic #include "../include/mtpr.h"
39c3ba2265Sbloom #include "nexus.h"
40c3ba2265Sbloom #include "scb.h"
41a089c9d9Sbloom #include "ioa.h"
4264577cdeSbostic #include "../bi/bireg.h"
4364577cdeSbostic #include "../mba/mbareg.h"
4464577cdeSbostic #include "../mba/mbavar.h"
4564577cdeSbostic #include "../uba/ubareg.h"
4664577cdeSbostic #include "../uba/ubavar.h"
47b8054636Swnj
4884badb11Swnj /*
4984badb11Swnj * The following several variables are related to
5084badb11Swnj * the configuration process, and are used in initializing
5184badb11Swnj * the machine.
5284badb11Swnj */
5384badb11Swnj int cold; /* if 1, still working on cold-start */
5484badb11Swnj int dkn; /* number of iostat dk numbers assigned so far */
55f7b6795bSkarels int cpuspeed = 1; /* relative cpu speed */
56b8054636Swnj
5784badb11Swnj /*
5884badb11Swnj * Addresses of the (locore) routines which bootstrap us from
5984badb11Swnj * hardware traps to C code. Filled into the system control block
6084badb11Swnj * as necessary.
61762ff349Skarels *
62762ff349Skarels * RIDICULOUS! CONFIG SHOULD GENERATE AN ioconf.h FOR US, with
63762ff349Skarels * mba glue also in `glue.s'. (Unibus adapter glue is special, though.)
6484badb11Swnj */
65b96bb200Swnj #if NMBA > 0
668a75d5d5Swnj int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
67a089c9d9Sbloom #if NMBA > 4
68a089c9d9Sbloom Need to expand the table for more than 4 massbus adaptors
69b96bb200Swnj #endif
70a089c9d9Sbloom #endif
71a089c9d9Sbloom #if defined(VAX780) || defined(VAX8600)
72a089c9d9Sbloom int (*ubaintv[])() =
73a089c9d9Sbloom {
74a089c9d9Sbloom Xua0int, Xua1int, Xua2int, Xua3int,
75a089c9d9Sbloom #if NUBA > 4
76a089c9d9Sbloom Xua4int, Xua5int, Xua6int, Xua7int,
77a089c9d9Sbloom #endif
78a089c9d9Sbloom #if NUBA > 8
79a089c9d9Sbloom Need to expand the table for more than 8 unibus adaptors
80a089c9d9Sbloom #endif
81a089c9d9Sbloom };
82e8b91158Skre #endif
83762ff349Skarels #if NKDB > 0
84762ff349Skarels /* kdb50 driver does not appear in udminit[] (not without csr!) */
85762ff349Skarels int Xkdbintr0(); /* generated by autoconf */
86762ff349Skarels int (*kdbintv[])() = { Xkdbintr0 };
87762ff349Skarels #if NKDB > 1
88762ff349Skarels Need to expand the table for more than 1 KDB adapter
89762ff349Skarels #endif
90762ff349Skarels #endif
9184badb11Swnj
9284badb11Swnj /*
9384badb11Swnj * This allocates the space for the per-uba information,
9484badb11Swnj * such as buffered data path usage.
9584badb11Swnj */
96cdfb934eSkarels struct uba_hd uba_hd[NUBA];
9709e5bb10Swnj
9884badb11Swnj /*
99b8054636Swnj * Determine mass storage and memory configuration for a machine.
100b8054636Swnj * Get cpu type, and then switch out to machine specific procedures
101b8054636Swnj * which will probe adaptors to see what is out there.
102b8054636Swnj */
configure()103b8054636Swnj configure()
104b8054636Swnj {
105b8054636Swnj union cpusid cpusid;
10609e5bb10Swnj register struct percpu *ocp;
107762ff349Skarels register struct pte *ip;
108b8054636Swnj
109b8054636Swnj cpusid.cpusid = mfpr(SID);
110762ff349Skarels switch (cpusid.cpuany.cp_type) {
111762ff349Skarels #if VAX8600
112762ff349Skarels case VAX_8600:
113762ff349Skarels printf("VAX 8600, serial# %d(%d), hardware ECO level %d(%d)\n",
1145fe25887Stef cpusid.cpu8600.cp_sno, cpusid.cpu8600.cp_plant,
1155fe25887Stef cpusid.cpu8600.cp_eco >> 4, cpusid.cpu8600.cp_eco);
116762ff349Skarels break;
117762ff349Skarels #endif
118762ff349Skarels #if VAX8200
119762ff349Skarels case VAX_8200:
120762ff349Skarels printf("\
121762ff349Skarels VAX 82%c0, hardware rev %d, ucode patch rev %d, sec patch %d, ucode rev %d\n",
122762ff349Skarels cpusid.cpu8200.cp_5 ? '5' : '0',
123762ff349Skarels cpusid.cpu8200.cp_hrev, cpusid.cpu8200.cp_patch,
124762ff349Skarels cpusid.cpu8200.cp_secp, cpusid.cpu8200.cp_urev);
125762ff349Skarels mastercpu = mfpr(BINID);
126762ff349Skarels break;
127762ff349Skarels #endif
128762ff349Skarels #if VAX780
129762ff349Skarels case VAX_780:
130762ff349Skarels printf("\
131762ff349Skarels VAX 11/78%c, serial# %d(%d), hardware ECO level %d(%d)\n",
132762ff349Skarels cpusid.cpu780.cp_5 ? '5' : '0',
133762ff349Skarels cpusid.cpu780.cp_sno, cpusid.cpu780.cp_plant,
134762ff349Skarels cpusid.cpu780.cp_eco >> 4, cpusid.cpu780.cp_eco);
135762ff349Skarels break;
136762ff349Skarels #endif
137762ff349Skarels #if VAX750
138762ff349Skarels case VAX_750:
139762ff349Skarels printf("VAX 11/750, hardware rev %d, ucode rev %d\n",
140762ff349Skarels cpusid.cpu750.cp_hrev, cpusid.cpu750.cp_urev);
141762ff349Skarels break;
142762ff349Skarels #endif
143762ff349Skarels #if VAX730
144762ff349Skarels case VAX_730:
145762ff349Skarels printf("VAX 11/730, ucode rev %d\n", cpusid.cpu730.cp_urev);
146762ff349Skarels break;
147762ff349Skarels #endif
148762ff349Skarels #if VAX630
149762ff349Skarels case VAX_630:
150762ff349Skarels printf("MicroVAX-II\n");
151762ff349Skarels break;
152762ff349Skarels #endif
15316fb909cStef #if VAX650
15416fb909cStef case VAX_650:
15516fb909cStef printf("MicroVAX 3000, ucode rev %d\n", cpusid.cpu650.cp_urev);
15616fb909cStef break;
15716fb909cStef #endif
158762ff349Skarels }
1590b04a93bSwnj for (ocp = percpu; ocp->pc_cputype; ocp++)
16009e5bb10Swnj if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
161f7b6795bSkarels cpuspeed = ocp->pc_cpuspeed;
162762ff349Skarels cpuops = ocp->pc_ops;
163762ff349Skarels if (cpuops->cpu_init != NULL)
164762ff349Skarels (*cpuops->cpu_init)();
165a8b6ec1fSkarels probeio(ocp);
16684badb11Swnj /*
167e4f0ff2bSsam * Write protect the scb and UNIBUS interrupt vectors.
168e4f0ff2bSsam * It is strange that this code is here, but this is
169e4f0ff2bSsam * as soon as we are done mucking with it, and the
17084badb11Swnj * write-enable was done in assembly language
17184badb11Swnj * to which we will never return.
17284badb11Swnj */
173762ff349Skarels for (ip = kvtopte(scb); ip < kvtopte(eUNIvec); ip++) {
174762ff349Skarels *(int *)ip &= ~PG_PROT;
175762ff349Skarels *(int *)ip |= PG_KR;
176762ff349Skarels }
177762ff349Skarels mtpr(TBIA, 0);
17884badb11Swnj #if GENERIC
179cdd5ba0eSkarels if ((boothowto & RB_ASKNAME) == 0)
180cdd5ba0eSkarels setroot();
18184badb11Swnj setconf();
18214e1df5dSkarels #else
183cdd5ba0eSkarels setroot();
18484badb11Swnj #endif
18501cdfd67Ssam /*
18601cdfd67Ssam * Configure swap area and related system
18701cdfd67Ssam * parameter based on device(s) used.
18801cdfd67Ssam */
18901cdfd67Ssam swapconf();
1908a75d5d5Swnj cold = 0;
191dfa84b8fSwnj memenable();
19209e5bb10Swnj return;
193b8054636Swnj }
19484badb11Swnj printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
195b8054636Swnj asm("halt");
196b8054636Swnj }
197b8054636Swnj
198b3a411d4Skarels #if VAX8600 || VAX780 || VAX750 || VAX730
199b3a411d4Skarels int nexnum; /* current nexus number */
200b3a411d4Skarels int nsbi; /* current sbi number */
201b3a411d4Skarels #endif
202762ff349Skarels #if VAX8200
203762ff349Skarels int numkdb; /* current ``kdb'' number */
204762ff349Skarels int bi_nodes; /* XXX remembers found bi nodes */
205762ff349Skarels #endif
206b3a411d4Skarels
207a8b6ec1fSkarels /*
208a8b6ec1fSkarels * Probe the main IO bus(es).
209a8b6ec1fSkarels * The percpu structure gives us a handle on the addresses and/or types.
210a8b6ec1fSkarels */
probeio(pcpu)211a8b6ec1fSkarels probeio(pcpu)
212a089c9d9Sbloom register struct percpu *pcpu;
213a089c9d9Sbloom {
214a8b6ec1fSkarels register struct iobus *iob;
215a089c9d9Sbloom int ioanum;
216a089c9d9Sbloom
217a089c9d9Sbloom ioanum = 0;
218a8b6ec1fSkarels for (iob = pcpu->pc_io; ioanum < pcpu->pc_nioa; ioanum++, iob++) {
219a8b6ec1fSkarels
220a8b6ec1fSkarels switch (iob->io_type) {
221a8b6ec1fSkarels
22216fb909cStef #if VAX630 || VAX650
223b3a411d4Skarels case IO_QBUS:
224b3a411d4Skarels probeqbus((struct qbus *)iob->io_details);
225b3a411d4Skarels break;
226b3a411d4Skarels #endif
227b3a411d4Skarels
228b3a411d4Skarels #if VAX780 || VAX750 || VAX730
229a8b6ec1fSkarels case IO_SBI780:
230a8b6ec1fSkarels case IO_CMI750:
231a8b6ec1fSkarels case IO_XXX730:
232a8b6ec1fSkarels probenexi((struct nexusconnect *)iob->io_details);
233a8b6ec1fSkarels break;
234a8b6ec1fSkarels #endif
235a8b6ec1fSkarels
236a8b6ec1fSkarels #if VAX8600
237a8b6ec1fSkarels case IO_ABUS:
238a8b6ec1fSkarels probe_Abus(ioanum, iob);
239a8b6ec1fSkarels break;
240a8b6ec1fSkarels #endif
241762ff349Skarels
242762ff349Skarels #if VAX8200
243762ff349Skarels case IO_BI:
244762ff349Skarels probe_bi((struct bibus *)iob->io_details);
245762ff349Skarels break;
246762ff349Skarels #endif
247762ff349Skarels
248a8b6ec1fSkarels default:
249a8b6ec1fSkarels if (iob->io_addr) {
250a8b6ec1fSkarels printf(
251a8b6ec1fSkarels "IO adaptor %d, type %d, at address 0x%x is unsupported\n",
252a8b6ec1fSkarels ioanum, iob->io_type, iob->io_addr);
253a8b6ec1fSkarels } else
254a8b6ec1fSkarels printf("IO adaptor %d, type %d, is unsupported\n",
255a8b6ec1fSkarels ioanum, iob->io_type);
256a8b6ec1fSkarels break;
257a8b6ec1fSkarels }
258a8b6ec1fSkarels }
259a8b6ec1fSkarels }
260a8b6ec1fSkarels
261a8b6ec1fSkarels #if VAX8600
probe_Abus(ioanum,iob)262a8b6ec1fSkarels probe_Abus(ioanum, iob)
263a8b6ec1fSkarels register struct iobus *iob;
264a8b6ec1fSkarels {
265a8b6ec1fSkarels register struct ioa *ioap;
266a8b6ec1fSkarels union ioacsr ioacsr;
267a8b6ec1fSkarels int type;
268a8b6ec1fSkarels struct sbia_regs *sbiaregs;
269762ff349Skarels #ifdef notyet
270762ff349Skarels int sbi1fail(), sbi1alert(), sbi1fault(), sbi1err();
271762ff349Skarels #endif
272a8b6ec1fSkarels
273a8b6ec1fSkarels ioap = &ioa[ioanum];
27432e110b5Skarels ioaccess(iob->io_addr, Ioamap[ioanum], iob->io_size);
275a8b6ec1fSkarels if (badaddr((caddr_t)ioap, 4))
276a8b6ec1fSkarels return;
277a089c9d9Sbloom ioacsr.ioa_csr = ioap->ioacsr.ioa_csr;
278a089c9d9Sbloom type = ioacsr.ioa_type & IOA_TYPMSK;
279a8b6ec1fSkarels
280a089c9d9Sbloom switch (type) {
281a8b6ec1fSkarels
282a089c9d9Sbloom case IOA_SBIA:
283a089c9d9Sbloom printf("SBIA%d at IO adaptor %d address 0x%x\n",
284a8b6ec1fSkarels nsbi, ioanum, iob->io_addr);
285762ff349Skarels #ifdef notyet
286762ff349Skarels /* I AM NOT SURE THESE ARE IN THE SAME PLACES */
287762ff349Skarels if (nscb == 1) {
288762ff349Skarels scb[1].scb_sbifail = scbentry(sbi1fail, SCB_ISTACK);
289762ff349Skarels /* maybe not sbifail, maybe scb1.scb_cmrd */
290762ff349Skarels /* but how can I find out without a broken SBIA1? */
291762ff349Skarels scb[1].scb_sbialert = scbentry(sbi1alert, SCB_ISTACK);
292762ff349Skarels scb[1].scb_sbifault = scbentry(sbi1fault, SCB_ISTACK);
293762ff349Skarels scb[1].scb_sbierr = scbentry(sbi1err, SCB_ISTACK);
294762ff349Skarels }
295762ff349Skarels #endif
296a8b6ec1fSkarels probenexi((struct nexusconnect *)iob->io_details);
297a089c9d9Sbloom nsbi++;
298a089c9d9Sbloom sbiaregs = (struct sbia_regs *)ioap;
299a089c9d9Sbloom sbiaregs->sbi_errsum = -1;
300a089c9d9Sbloom sbiaregs->sbi_error = 0x1000;
301a089c9d9Sbloom sbiaregs->sbi_fltsts = 0xc0000;
302a089c9d9Sbloom break;
303a8b6ec1fSkarels
304a089c9d9Sbloom default:
305a8b6ec1fSkarels printf("IOA%d at address 0x%x is unsupported (type = 0x%x)\n",
306a8b6ec1fSkarels ioanum, iob->io_addr, ioacsr.ioa_type);
307a8b6ec1fSkarels break;
308a089c9d9Sbloom }
309a089c9d9Sbloom }
310a8b6ec1fSkarels #endif
311a089c9d9Sbloom
312b3a411d4Skarels #if VAX8600 || VAX780 || VAX750 || VAX730
313b8054636Swnj /*
3140b04a93bSwnj * Probe nexus space, finding the interconnects
3150b04a93bSwnj * and setting up and probing mba's and uba's for devices.
316b8054636Swnj */
probenexi(pnc)317a8b6ec1fSkarels probenexi(pnc)
318a8b6ec1fSkarels register struct nexusconnect *pnc;
319b8054636Swnj {
320b8054636Swnj register struct nexus *nxv;
321a8b6ec1fSkarels struct nexus *nxp = pnc->psb_nexbase;
322b8054636Swnj union nexcsr nexcsr;
323ce6a472bSwnj int i;
324b8054636Swnj
325762ff349Skarels ioaccess((caddr_t)nxp, Nexmap[nsbi * NNEXSBI],
326762ff349Skarels pnc->psb_nnexus * sizeof(struct nexus));
327762ff349Skarels nxv = &nexus[nsbi * NNEXSBI];
328762ff349Skarels for (nexnum = 0; nexnum < pnc->psb_nnexus; nexnum++, nxp++, nxv++) {
329b8054636Swnj if (badaddr((caddr_t)nxv, 4))
330b8054636Swnj continue;
331a8b6ec1fSkarels if (pnc->psb_nextype && pnc->psb_nextype[nexnum] != NEX_ANY)
332a8b6ec1fSkarels nexcsr.nex_csr = pnc->psb_nextype[nexnum];
3330b04a93bSwnj else
334b8054636Swnj nexcsr = nxv->nexcsr;
335b8054636Swnj if (nexcsr.nex_csr&NEX_APD)
336b8054636Swnj continue;
337b8054636Swnj switch (nexcsr.nex_type) {
338b8054636Swnj
339b8054636Swnj case NEX_MBA:
3408a75d5d5Swnj printf("mba%d at tr%d\n", nummba, nexnum);
341b874d253Swnj if (nummba >= NMBA) {
342762ff349Skarels printf("%d mba's", ++nummba);
3436d315329Swnj goto unconfig;
344b874d253Swnj }
34584badb11Swnj #if NMBA > 0
34609e5bb10Swnj mbafind(nxv, nxp);
347e8b91158Skre nummba++;
348b96bb200Swnj #endif
34984badb11Swnj break;
350b8054636Swnj
351b8054636Swnj case NEX_UBA0:
352b8054636Swnj case NEX_UBA1:
353b8054636Swnj case NEX_UBA2:
354b8054636Swnj case NEX_UBA3:
35584badb11Swnj printf("uba%d at tr%d\n", numuba, nexnum);
356762ff349Skarels if (numuba >= NUBA) {
357762ff349Skarels printf("%d uba's", ++numuba);
358762ff349Skarels goto unconfig;
359762ff349Skarels }
360762ff349Skarels #if NUBA > 0
361b14355dbSkarels #if VAX750
362cdfb934eSkarels if (numuba >= 2 && cpu == VAX_750) {
363cdfb934eSkarels printf("More than 2 UBA's");
36409e5bb10Swnj goto unsupp;
365b8054636Swnj }
366cdfb934eSkarels #endif
367a089c9d9Sbloom #if defined(VAX780) || defined(VAX8600)
368762ff349Skarels if (cpu == VAX_780 || cpu == VAX_8600)
3696d315329Swnj setscbnex(ubaintv[numuba]);
370ce6a472bSwnj #endif
37109e5bb10Swnj i = nexcsr.nex_type - NEX_UBA0;
372b3a411d4Skarels probeuba((struct uba_regs *)nxv, (struct uba_regs *)nxp,
373b3a411d4Skarels pnc->psb_umaddr[i]);
374762ff349Skarels #endif /* NUBA */
375b8054636Swnj break;
376b8054636Swnj
377b8054636Swnj case NEX_DR32:
378e8b91158Skre /* there can be more than one... are there other codes??? */
379b8054636Swnj printf("dr32");
380b8054636Swnj goto unsupp;
381b8054636Swnj
382b8054636Swnj case NEX_MEM4:
383b8054636Swnj case NEX_MEM4I:
384b8054636Swnj case NEX_MEM16:
385b8054636Swnj case NEX_MEM16I:
38684badb11Swnj printf("mcr%d at tr%d\n", nmcr, nexnum);
387762ff349Skarels if (nmcr >= MAXNMCR) {
388762ff349Skarels printf("%d mcr's", ++nmcr);
389762ff349Skarels goto unconfig;
39009e5bb10Swnj }
3912f548fb0Skarels switch (cpu) {
392762ff349Skarels #if VAX780
3932f548fb0Skarels case VAX_780:
394762ff349Skarels /* only ka780 code looks at type */
3952f548fb0Skarels mcrtype[nmcr] = M780C;
3962f548fb0Skarels break;
397762ff349Skarels #endif
398762ff349Skarels default:
3992f548fb0Skarels break;
4002f548fb0Skarels }
401762ff349Skarels mcraddr[nmcr++] = (caddr_t)nxv;
4022f548fb0Skarels break;
4032f548fb0Skarels
404762ff349Skarels #if VAX780
4052f548fb0Skarels case NEX_MEM64I:
4062f548fb0Skarels case NEX_MEM64L:
4072f548fb0Skarels case NEX_MEM64LI:
40864c859b5Sbloom case NEX_MEM256I:
40964c859b5Sbloom case NEX_MEM256L:
41064c859b5Sbloom case NEX_MEM256LI:
4112f548fb0Skarels printf("mcr%d (el) at tr%d\n", nmcr, nexnum);
412762ff349Skarels if (nmcr >= MAXNMCR) {
413762ff349Skarels printf("%d mcr's", ++nmcr);
414762ff349Skarels goto unconfig;
4152f548fb0Skarels }
4162f548fb0Skarels mcrtype[nmcr] = M780EL;
417762ff349Skarels mcraddr[nmcr++] = (caddr_t)nxv;
41864c859b5Sbloom if (nexcsr.nex_type != NEX_MEM64I &&
41964c859b5Sbloom nexcsr.nex_type != NEX_MEM256I)
4202f548fb0Skarels break;
4212f548fb0Skarels /* fall into ... */
4222f548fb0Skarels
4232f548fb0Skarels case NEX_MEM64U:
4242f548fb0Skarels case NEX_MEM64UI:
42564c859b5Sbloom case NEX_MEM256U:
42664c859b5Sbloom case NEX_MEM256UI:
4272f548fb0Skarels printf("mcr%d (eu) at tr%d\n", nmcr, nexnum);
428762ff349Skarels if (nmcr >= MAXNMCR) {
429762ff349Skarels printf("%d mcr's", ++nmcr);
430762ff349Skarels goto unconfig;
4312f548fb0Skarels }
4322f548fb0Skarels mcrtype[nmcr] = M780EU;
433762ff349Skarels mcraddr[nmcr++] = (caddr_t)nxv;
434b8054636Swnj break;
435762ff349Skarels #endif
436b8054636Swnj
437b8054636Swnj case NEX_MPM0:
438b8054636Swnj case NEX_MPM1:
439b8054636Swnj case NEX_MPM2:
440b8054636Swnj case NEX_MPM3:
441b8054636Swnj printf("mpm");
442b8054636Swnj goto unsupp;
443b8054636Swnj
444e4f0ff2bSsam case NEX_CI:
445e4f0ff2bSsam printf("ci");
446e4f0ff2bSsam goto unsupp;
447e4f0ff2bSsam
448b8054636Swnj default:
449b8054636Swnj printf("nexus type %x", nexcsr.nex_type);
450b8054636Swnj unsupp:
45109e5bb10Swnj printf(" unsupported (at tr %d)\n", nexnum);
452b8054636Swnj continue;
45384badb11Swnj unconfig:
45484badb11Swnj printf(" not configured\n");
45584badb11Swnj continue;
456b8054636Swnj }
457b8054636Swnj }
458cdfb934eSkarels if (nummba > NMBA)
459cdfb934eSkarels nummba = NMBA;
460cdfb934eSkarels if (numuba > NUBA)
461cdfb934eSkarels numuba = NUBA;
462762ff349Skarels if (nmcr > MAXNMCR)
463762ff349Skarels nmcr = MAXNMCR;
464b8054636Swnj }
465d9a5e0b6Swnj
466b3a411d4Skarels setscbnex(fn)
467b3a411d4Skarels int (*fn)();
468b3a411d4Skarels {
469762ff349Skarels register struct scb *scbp = &scb[nsbi];
470b3a411d4Skarels
471b3a411d4Skarels scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
472b3a411d4Skarels scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
473b3a411d4Skarels scbentry(fn, SCB_ISTACK);
474b3a411d4Skarels }
475b3a411d4Skarels #endif
476b3a411d4Skarels
477762ff349Skarels #if NBI > 0
478762ff349Skarels /*
479762ff349Skarels * Probe BI node space.
480762ff349Skarels *
481762ff349Skarels * THIS DEPENDS ON BI SPACE == NEXUS SPACE
482762ff349Skarels * THIS WILL NOT WORK FOR MULTIPLE BIs
483762ff349Skarels */
probe_bi(p)484762ff349Skarels probe_bi(p)
485762ff349Skarels register struct bibus *p;
486762ff349Skarels {
487762ff349Skarels register struct bi_node *biv, *bip;
488762ff349Skarels register int node;
489762ff349Skarels short dtype;
490762ff349Skarels
491762ff349Skarels /* must ignore BI errors while configuring */
492762ff349Skarels bip = p->pbi_base;
493762ff349Skarels ioaccess((caddr_t)bip, Nexmap[0], sizeof(*bip) * NNODEBI);/* XXX */
494762ff349Skarels printf("vaxbi0 at address 0x%x\n", bip);
495762ff349Skarels biv = (struct bi_node *) &nexus[0]; /* XXX */
496762ff349Skarels for (node = 0; node < NNODEBI; node++, bip++, biv++) {
497762ff349Skarels if (badaddr((caddr_t)biv, 4))
498762ff349Skarels continue;
499762ff349Skarels bi_nodes |= 1 << node; /* XXX */
500762ff349Skarels dtype = biv->biic.bi_dtype;
501762ff349Skarels /* clear bus errors */
502762ff349Skarels biv->biic.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);
503762ff349Skarels switch (dtype) {
504762ff349Skarels
505762ff349Skarels case BIDT_KA820: {
506762ff349Skarels /* is this right?? */
507762ff349Skarels int cp5 = biv->biic.bi_revs & 0x8000 ? '5' : '0';
508762ff349Skarels
509762ff349Skarels if (node != mastercpu) {
510762ff349Skarels printf("slave ka82%c cpu", cp5);
511762ff349Skarels goto unsupp;
512762ff349Skarels }
513762ff349Skarels printf("ka82%c cpu at node %x\n", cp5, node);
514762ff349Skarels biv->biic.bi_intrdes = 1 << mastercpu;
515762ff349Skarels biv->biic.bi_csr |= BICSR_SEIE | BICSR_HEIE;
516762ff349Skarels break;
517762ff349Skarels }
518762ff349Skarels
519762ff349Skarels case BIDT_DWBUA:
520762ff349Skarels if (numuba >= NUBA || /*XXX*/numuba > 2) {
521762ff349Skarels printf("%d uba's", ++numuba);
522762ff349Skarels goto unconfig;
523762ff349Skarels }
524762ff349Skarels #if NUBA > 0
525762ff349Skarels printf("uba%d at node %x\n", numuba, node);
526762ff349Skarels
527762ff349Skarels /*
528762ff349Skarels * Run a self test reset to drop any `old' errors,
529762ff349Skarels * so that they cannot cause a BI bus error.
530762ff349Skarels */
531762ff349Skarels (void) bi_selftest(&biv->biic);
532762ff349Skarels
533762ff349Skarels /*
534762ff349Skarels * Enable interrupts. DWBUAs must have
535762ff349Skarels * high priority.
536762ff349Skarels */
537762ff349Skarels biv->biic.bi_intrdes = 1 << mastercpu;
538762ff349Skarels biv->biic.bi_csr = (biv->biic.bi_csr&~BICSR_ARB_MASK) |
539762ff349Skarels BICSR_ARB_HIGH;
540762ff349Skarels probeuba((struct uba_regs *)biv, (struct uba_regs *)bip,
541762ff349Skarels (caddr_t)UMEM8200(node));
542762ff349Skarels #endif /* NUBA */
543762ff349Skarels break;
544762ff349Skarels
545762ff349Skarels case BIDT_MS820:
546762ff349Skarels printf("mcr%d at node %x\n", nmcr, node);
547762ff349Skarels if (nmcr >= MAXNMCR) {
548762ff349Skarels printf("%d mcr's", ++nmcr);
549762ff349Skarels goto unconfig;
550762ff349Skarels }
551762ff349Skarels mcraddr[nmcr++] = (caddr_t)biv;
552762ff349Skarels biv->biic.bi_intrdes = 1 << mastercpu;
553762ff349Skarels biv->biic.bi_csr |= BICSR_SEIE | BICSR_HEIE;
554762ff349Skarels break;
555762ff349Skarels
556762ff349Skarels case BIDT_KDB50:
557762ff349Skarels if (numkdb >= NKDB) {
558762ff349Skarels printf("%d kdb's", ++numkdb);
559762ff349Skarels goto unconfig;
560762ff349Skarels }
561762ff349Skarels #if NKDB > 0
562762ff349Skarels printf("kdb%d at node %x\n", numkdb, node);
563762ff349Skarels kdbconfig(numkdb, (struct biiregs *)biv,
564762ff349Skarels (struct biiregs *)bip,
565762ff349Skarels (int)&scb[0].scb_ipl15[node] - (int)&scb[0]);
566762ff349Skarels scb[0].scb_ipl15[node] =
567762ff349Skarels scbentry(kdbintv[numkdb], SCB_ISTACK);
568762ff349Skarels kdbfind(numkdb);
569762ff349Skarels #endif
570762ff349Skarels numkdb++;
571762ff349Skarels break;
572762ff349Skarels
573762ff349Skarels case BIDT_DEBNA:
574762ff349Skarels case BIDT_DEBNK:
575762ff349Skarels printf("debna/debnk ethernet");
576762ff349Skarels goto unsupp;
577762ff349Skarels
578762ff349Skarels default:
579762ff349Skarels printf("node type 0x%x ", dtype);
580762ff349Skarels unsupp:
581762ff349Skarels printf(" unsupported (at node %x)\n", node);
582762ff349Skarels break;
583762ff349Skarels unconfig:
584762ff349Skarels printf(" not configured (at node %x)\n", node);
585762ff349Skarels continue;
586762ff349Skarels }
587762ff349Skarels #ifdef DO_EINTRCSR
588762ff349Skarels biv->biic.bi_eintrcsr = BIEIC_IPL17 |
589762ff349Skarels (int)&scb[0].scb_bierr - (int)&scb[0];
590762ff349Skarels /* but bi reset will need to restore this */
591762ff349Skarels #endif
592762ff349Skarels }
593762ff349Skarels if (numuba > NUBA)
594762ff349Skarels numuba = NUBA;
595762ff349Skarels if (numkdb > NKDB)
596762ff349Skarels numkdb = NKDB;
597762ff349Skarels if (nmcr > MAXNMCR)
598762ff349Skarels nmcr = MAXNMCR;
599762ff349Skarels }
600762ff349Skarels
601762ff349Skarels #if NKDB > 0
602762ff349Skarels /*
603762ff349Skarels * Find drives attached to a particular KDB50.
604762ff349Skarels */
kdbfind(kdbnum)605762ff349Skarels kdbfind(kdbnum)
606762ff349Skarels int kdbnum;
607762ff349Skarels {
608762ff349Skarels extern struct uba_driver kdbdriver;
609762ff349Skarels register struct uba_device *ui;
610762ff349Skarels register struct uba_driver *udp = &kdbdriver;
611762ff349Skarels int t;
612762ff349Skarels
613762ff349Skarels for (ui = ubdinit; ui->ui_driver; ui++) {
614762ff349Skarels /* ui->ui_ubanum is trash */
615762ff349Skarels if (ui->ui_driver != udp || ui->ui_alive ||
616762ff349Skarels ui->ui_ctlr != kdbnum && ui->ui_ctlr != '?')
617762ff349Skarels continue;
618762ff349Skarels t = ui->ui_ctlr;
619762ff349Skarels ui->ui_ctlr = kdbnum;
620762ff349Skarels if ((*udp->ud_slave)(ui) == 0) {
621762ff349Skarels ui->ui_ctlr = t;
622762ff349Skarels continue;
623762ff349Skarels }
624762ff349Skarels ui->ui_alive = 1;
625762ff349Skarels ui->ui_ubanum = -1;
626762ff349Skarels
627762ff349Skarels /* make these invalid so we can see if someone uses them */
628762ff349Skarels /* might as well make each one different too */
629762ff349Skarels ui->ui_hd = (struct uba_hd *)0xc0000010;
630762ff349Skarels ui->ui_addr = (caddr_t)0xc0000014;
631762ff349Skarels ui->ui_physaddr = (caddr_t)0xc0000018;
632762ff349Skarels ui->ui_mi = (struct uba_ctlr *)0xc000001c;
633762ff349Skarels
634762ff349Skarels if (ui->ui_dk && dkn < DK_NDRIVE)
635762ff349Skarels ui->ui_dk = dkn++;
636762ff349Skarels else
637762ff349Skarels ui->ui_dk = -1;
638762ff349Skarels /* ui_type comes from driver */
639762ff349Skarels udp->ud_dinfo[ui->ui_unit] = ui;
640762ff349Skarels printf("%s%d at %s%d slave %d\n",
641762ff349Skarels udp->ud_dname, ui->ui_unit,
642762ff349Skarels udp->ud_mname, ui->ui_ctlr, ui->ui_slave);
643762ff349Skarels (*udp->ud_attach)(ui);
644762ff349Skarels }
645762ff349Skarels }
646762ff349Skarels #endif /* NKDB > 0 */
647762ff349Skarels #endif /* NBI > 0 */
648762ff349Skarels
649b96bb200Swnj #if NMBA > 0
650701f53b0Swnj struct mba_device *mbaconfig();
651b8054636Swnj /*
652b8054636Swnj * Find devices attached to a particular mba
653b8054636Swnj * and look for each device found in the massbus
654b8054636Swnj * initialization tables.
655b8054636Swnj */
65609e5bb10Swnj mbafind(nxv, nxp)
657d9a5e0b6Swnj struct nexus *nxv, *nxp;
658b8054636Swnj {
659b8054636Swnj register struct mba_regs *mdp;
660b8054636Swnj register struct mba_drv *mbd;
661701f53b0Swnj register struct mba_device *mi;
662701f53b0Swnj register struct mba_slave *ms;
6632101e181Skre int dn, dt, sn;
664701f53b0Swnj struct mba_device fnd;
665b8054636Swnj
66609e5bb10Swnj mdp = (struct mba_regs *)nxv;
667e8b91158Skre mba_hd[nummba].mh_mba = mdp;
668e8b91158Skre mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
6696d315329Swnj setscbnex(mbaintv[nummba]);
670e8887a6eSkarels mdp->mba_cr = MBCR_INIT;
671e8887a6eSkarels mdp->mba_cr = MBCR_IE;
672b8054636Swnj fnd.mi_mba = mdp;
673e8b91158Skre fnd.mi_mbanum = nummba;
674b8054636Swnj for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
675f939c6feSwnj if ((mbd->mbd_ds&MBDS_DPR) == 0)
676f939c6feSwnj continue;
6770c0ba551Sroot mdp->mba_sr |= MBSR_NED; /* si kludge */
678b8054636Swnj dt = mbd->mbd_dt & 0xffff;
679b8054636Swnj if (dt == 0)
680b8054636Swnj continue;
6810c0ba551Sroot if (mdp->mba_sr&MBSR_NED)
6820c0ba551Sroot continue; /* si kludge */
683b8054636Swnj if (dt == MBDT_MOH)
684b8054636Swnj continue;
685b8054636Swnj fnd.mi_drive = dn;
6862101e181Skre #define qeq(a, b) ( a == b || a == '?' )
6872101e181Skre if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP))
6882101e181Skre for (sn = 0; sn < 8; sn++) {
6892101e181Skre mbd->mbd_tc = sn;
690701f53b0Swnj for (ms = mbsinit; ms->ms_driver; ms++)
6912101e181Skre if (ms->ms_driver == mi->mi_driver &&
6922101e181Skre ms->ms_alive == 0 &&
6932101e181Skre qeq(ms->ms_ctlr, mi->mi_unit) &&
6942101e181Skre qeq(ms->ms_slave, sn) &&
6952101e181Skre (*ms->ms_driver->md_slave)(mi, ms, sn)) {
6962101e181Skre printf("%s%d at %s%d slave %d\n"
6972101e181Skre , ms->ms_driver->md_sname
6982101e181Skre , ms->ms_unit
6992101e181Skre , mi->mi_driver->md_dname
7002101e181Skre , mi->mi_unit
7012101e181Skre , sn
7022101e181Skre );
70384badb11Swnj ms->ms_alive = 1;
70484badb11Swnj ms->ms_ctlr = mi->mi_unit;
7052101e181Skre ms->ms_slave = sn;
706bb45087dSmckusick break;
707701f53b0Swnj }
708b8054636Swnj }
709b8054636Swnj }
710b8054636Swnj }
711b8054636Swnj
712b8054636Swnj /*
713b8054636Swnj * Have found a massbus device;
714b8054636Swnj * see if it is in the configuration table.
715b8054636Swnj * If so, fill in its data.
716b8054636Swnj */
717701f53b0Swnj struct mba_device *
mbaconfig(ni,type)718b8054636Swnj mbaconfig(ni, type)
719701f53b0Swnj register struct mba_device *ni;
720b8054636Swnj register int type;
721b8054636Swnj {
722701f53b0Swnj register struct mba_device *mi;
723b8054636Swnj register short *tp;
724884ec674Swnj register struct mba_hd *mh;
725b8054636Swnj
726701f53b0Swnj for (mi = mbdinit; mi->mi_driver; mi++) {
727b8054636Swnj if (mi->mi_alive)
728b8054636Swnj continue;
729b8054636Swnj tp = mi->mi_driver->md_type;
730b8054636Swnj for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
731ae520bf5Swnj if (*tp == (type&MBDT_TYPE))
732b8054636Swnj goto found;
733b8054636Swnj continue;
734b8054636Swnj found:
735b8054636Swnj #define match(fld) (ni->fld == mi->fld || mi->fld == '?')
736701f53b0Swnj if (!match(mi_drive) || !match(mi_mbanum))
737b8054636Swnj continue;
738c0ffcddcSkarels printf("%s%d at mba%d drive %d",
739701f53b0Swnj mi->mi_driver->md_dname, mi->mi_unit,
740701f53b0Swnj ni->mi_mbanum, ni->mi_drive);
741b8054636Swnj mi->mi_alive = 1;
742884ec674Swnj mh = &mba_hd[ni->mi_mbanum];
743884ec674Swnj mi->mi_hd = mh;
744884ec674Swnj mh->mh_mbip[ni->mi_drive] = mi;
745884ec674Swnj mh->mh_ndrive++;
746b8054636Swnj mi->mi_mba = ni->mi_mba;
747b8054636Swnj mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
748b8054636Swnj mi->mi_mbanum = ni->mi_mbanum;
749b8054636Swnj mi->mi_drive = ni->mi_drive;
75043668a85Ssam /*
75143668a85Ssam * If drive has never been seen before,
75243668a85Ssam * give it a dkn for statistics.
75343668a85Ssam */
75443668a85Ssam if (mi->mi_driver->md_info[mi->mi_unit] == 0) {
75543668a85Ssam mi->mi_driver->md_info[mi->mi_unit] = mi;
7568a75d5d5Swnj if (mi->mi_dk && dkn < DK_NDRIVE)
7578a75d5d5Swnj mi->mi_dk = dkn++;
7588a75d5d5Swnj else
7598a75d5d5Swnj mi->mi_dk = -1;
76043668a85Ssam }
761701f53b0Swnj (*mi->mi_driver->md_attach)(mi);
762c0ffcddcSkarels printf("\n");
763701f53b0Swnj return (mi);
764b8054636Swnj }
765701f53b0Swnj return (0);
766b8054636Swnj }
767b96bb200Swnj #endif
768b8054636Swnj
76909e5bb10Swnj /*
770d9a5e0b6Swnj * Fixctlrmask fixes the masks of the driver ctlr routines
771d9a5e0b6Swnj * which otherwise save r10 and r11 where the interrupt and br
772d9a5e0b6Swnj * level are passed through.
77309e5bb10Swnj */
fixctlrmask()774d9a5e0b6Swnj fixctlrmask()
775b8054636Swnj {
776701f53b0Swnj register struct uba_ctlr *um;
777701f53b0Swnj register struct uba_device *ui;
778d9a5e0b6Swnj register struct uba_driver *ud;
779d9a5e0b6Swnj #define phys(a,b) ((b)(((int)(a))&0x7fffffff))
780b8054636Swnj
781d9a5e0b6Swnj for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
782884ec674Swnj *phys(ud->ud_probe, short *) &= ~0xc00;
783d9a5e0b6Swnj for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
784884ec674Swnj *phys(ud->ud_probe, short *) &= ~0xc00;
785d9a5e0b6Swnj }
786d9a5e0b6Swnj
787762ff349Skarels #ifdef QBA
788b3a411d4Skarels /*
789b3a411d4Skarels * Configure a Q-bus.
790b3a411d4Skarels */
791b3a411d4Skarels probeqbus(qb)
792b3a411d4Skarels struct qbus *qb;
793b3a411d4Skarels {
794b3a411d4Skarels register struct uba_hd *uhp = &uba_hd[numuba];
795b3a411d4Skarels
796762ff349Skarels ioaccess((caddr_t)qb->qb_map, Nexmap[0],
797762ff349Skarels qb->qb_memsize * sizeof (struct pte));
798b3a411d4Skarels uhp->uh_type = qb->qb_type;
799b3a411d4Skarels uhp->uh_uba = (struct uba_regs *)0xc0000000; /* no uba adaptor regs */
800b3a411d4Skarels uhp->uh_mr = (struct pte *)&nexus[0];
801b3a411d4Skarels /*
802b3a411d4Skarels * The map registers start right at 20088000 on the
803b3a411d4Skarels * ka630, so we have to subtract out the 2k offset to make the
804b3a411d4Skarels * pointers work..
805b3a411d4Skarels */
806b3a411d4Skarels uhp->uh_physuba = (struct uba_regs *)(((u_long)qb->qb_map)-0x800);
807b3a411d4Skarels
808b3a411d4Skarels uhp->uh_memsize = qb->qb_memsize;
809b3a411d4Skarels ioaccess(qb->qb_maddr, UMEMmap[numuba], uhp->uh_memsize * NBPG);
810b3a411d4Skarels uhp->uh_mem = umem[numuba];
811b3a411d4Skarels
812b3a411d4Skarels /*
813b3a411d4Skarels * The I/O page is mapped to the 8K of the umem address space
814b3a411d4Skarels * immediately after the memory section that is mapped.
815b3a411d4Skarels */
816b3a411d4Skarels ioaccess(qb->qb_iopage, UMEMmap[numuba] + uhp->uh_memsize,
817b3a411d4Skarels UBAIOPAGES * NBPG);
818b3a411d4Skarels uhp->uh_iopage = umem[numuba] + (uhp->uh_memsize * NBPG);
819b3a411d4Skarels
820b3a411d4Skarels unifind(uhp, qb->qb_iopage);
821b3a411d4Skarels }
822b3a411d4Skarels #endif
823b3a411d4Skarels
824762ff349Skarels #if NUBA > 0
825b3a411d4Skarels probeuba(vubp, pubp, pumem)
826b3a411d4Skarels struct uba_regs *vubp, *pubp;
827b3a411d4Skarels caddr_t pumem;
828b3a411d4Skarels {
829b3a411d4Skarels register struct uba_hd *uhp = &uba_hd[numuba];
830b3a411d4Skarels
831b3a411d4Skarels /*
832b3a411d4Skarels * Save virtual and physical addresses of adaptor.
833b3a411d4Skarels */
834b3a411d4Skarels switch (cpu) {
835b3a411d4Skarels #ifdef DW780
836b3a411d4Skarels case VAX_8600:
837b3a411d4Skarels case VAX_780:
838b3a411d4Skarels uhp->uh_type = DW780;
839b3a411d4Skarels break;
840b3a411d4Skarels #endif
841b3a411d4Skarels #ifdef DW750
842b3a411d4Skarels case VAX_750:
843b3a411d4Skarels uhp->uh_type = DW750;
844b3a411d4Skarels break;
845b3a411d4Skarels #endif
846b3a411d4Skarels #ifdef DW730
847b3a411d4Skarels case VAX_730:
848b3a411d4Skarels uhp->uh_type = DW730;
849b3a411d4Skarels break;
850b3a411d4Skarels #endif
851762ff349Skarels #ifdef DWBUA
852762ff349Skarels case VAX_8200:
853762ff349Skarels uhp->uh_type = DWBUA;
854762ff349Skarels break;
855762ff349Skarels #endif
856b3a411d4Skarels default:
857b3a411d4Skarels panic("unknown UBA type");
858b3a411d4Skarels /*NOTREACHED*/
859b3a411d4Skarels }
860b3a411d4Skarels uhp->uh_uba = vubp;
861b3a411d4Skarels uhp->uh_physuba = pubp;
862b3a411d4Skarels uhp->uh_mr = vubp->uba_map;
863b3a411d4Skarels uhp->uh_memsize = UBAPAGES;
864b3a411d4Skarels
865b3a411d4Skarels ioaccess(pumem, UMEMmap[numuba], (UBAPAGES + UBAIOPAGES) * NBPG);
866b3a411d4Skarels uhp->uh_mem = umem[numuba];
867b3a411d4Skarels uhp->uh_iopage = umem[numuba] + (uhp->uh_memsize * NBPG);
868b3a411d4Skarels
869b3a411d4Skarels unifind(uhp, pumem + (uhp->uh_memsize * NBPG));
870b3a411d4Skarels }
871b3a411d4Skarels
872d9a5e0b6Swnj /*
873d9a5e0b6Swnj * Find devices on a UNIBUS.
874d9a5e0b6Swnj * Uses per-driver routine to set <br,cvec> into <r11,r10>,
875d9a5e0b6Swnj * and then fills in the tables, with help from a per-driver
876d9a5e0b6Swnj * slave initialization routine.
877d9a5e0b6Swnj */
878b3a411d4Skarels unifind(uhp0, pumem)
879b3a411d4Skarels struct uba_hd *uhp0;
880b3a411d4Skarels caddr_t pumem;
881d9a5e0b6Swnj {
8826d315329Swnj #ifndef lint
883d70b5589Skarels register int rbr, rcvec; /* MUST BE r11, r10 */
8846d315329Swnj #else
8856d315329Swnj /*
8866d315329Swnj * Lint doesn't realize that these
8876d315329Swnj * can be initialized asynchronously
8886d315329Swnj * when devices interrupt.
8896d315329Swnj */
890d70b5589Skarels register int rbr = 0, rcvec = 0;
8916d315329Swnj #endif
892701f53b0Swnj register struct uba_device *ui;
893701f53b0Swnj register struct uba_ctlr *um;
894b3a411d4Skarels register struct uba_hd *uhp = uhp0;
8952101e181Skre u_short *reg, *ap, addr;
896d9a5e0b6Swnj struct uba_driver *udp;
897a089c9d9Sbloom int i, (**ivec)();
898c2f959ceSmckusick caddr_t ualloc;
899762ff349Skarels extern quad catcher[128];
900d70b5589Skarels extern int br, cvec;
901762ff349Skarels #if DW780 || DWBUA
902b3a411d4Skarels struct uba_regs *vubp = uhp->uh_uba;
903de0dda68Skridle #endif
904b3a411d4Skarels
905d9a5e0b6Swnj /*
906d9a5e0b6Swnj * Initialize the UNIBUS, by freeing the map
907d9a5e0b6Swnj * registers and the buffered data path registers
908d9a5e0b6Swnj */
909a3746146Smckusick uhp->uh_map = (struct map *)
91069ae479aSkarels malloc((u_long)(UAMSIZ * sizeof (struct map)), M_DEVBUF,
91169ae479aSkarels M_NOWAIT);
912366b9158Smckusick if (uhp->uh_map == 0)
913366b9158Smckusick panic("no mem for unibus map");
91469ae479aSkarels bzero((caddr_t)uhp->uh_map, (unsigned)(UAMSIZ * sizeof (struct map)));
9150df6cb74Swnj ubainitmaps(uhp);
916d9a5e0b6Swnj
917d9a5e0b6Swnj /*
918762ff349Skarels * Initialize space for the UNIBUS interrupt vectors.
919762ff349Skarels * On the 8600, can't use first slot in UNIvec
920762ff349Skarels * (the vectors for the second SBI overlap it);
921762ff349Skarels * move each set of vectors forward.
92232e110b5Skarels */
923b3a411d4Skarels #if VAX8600
924a089c9d9Sbloom if (cpu == VAX_8600)
925762ff349Skarels uhp->uh_vec = UNIvec[numuba + 1];
926b3a411d4Skarels else
927b3a411d4Skarels #endif
928762ff349Skarels uhp->uh_vec = UNIvec[numuba];
929d9a5e0b6Swnj for (i = 0; i < 128; i++)
930762ff349Skarels uhp->uh_vec[i] = scbentry(&catcher[i], SCB_ISTACK);
931a9c12ad0Swnj /*
932a9c12ad0Swnj * Set last free interrupt vector for devices with
933a9c12ad0Swnj * programmable interrupt vectors. Use is to decrement
934a9c12ad0Swnj * this number and use result as interrupt vector.
935a9c12ad0Swnj */
936a9c12ad0Swnj uhp->uh_lastiv = 0x200;
937a9c12ad0Swnj
938762ff349Skarels #ifdef DWBUA
939762ff349Skarels if (uhp->uh_type == DWBUA)
940762ff349Skarels BUA(vubp)->bua_offset = (int)uhp->uh_vec - (int)&scb[0];
941762ff349Skarels #endif
942762ff349Skarels
943b3a411d4Skarels #ifdef DW780
944b3a411d4Skarels if (uhp->uh_type == DW780) {
945d9a5e0b6Swnj vubp->uba_sr = vubp->uba_sr;
946701f53b0Swnj vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
947b8054636Swnj }
948b8054636Swnj #endif
949d9a5e0b6Swnj /*
950b14355dbSkarels * First configure devices that have unibus memory,
951b14355dbSkarels * allowing them to allocate the correct map registers.
952b14355dbSkarels */
953b14355dbSkarels ubameminit(numuba);
954b14355dbSkarels /*
9552101e181Skre * Grab some memory to record the umem address space we allocate,
9562101e181Skre * so we can be sure not to place two devices at the same address.
9572101e181Skre *
9582101e181Skre * We could use just 1/8 of this (we only want a 1 bit flag) but
9592101e181Skre * we are going to give it back anyway, and that would make the
9602101e181Skre * code here bigger (which we can't give back), so ...
9612101e181Skre *
9622101e181Skre * One day, someone will make a unibus with something other than
9632101e181Skre * an 8K i/o address space, & screw this totally.
9642101e181Skre */
96569ae479aSkarels ualloc = (caddr_t)malloc((u_long)(8 * 1024), M_TEMP, M_NOWAIT);
9662101e181Skre if (ualloc == (caddr_t)0)
9672101e181Skre panic("no mem for unifind");
96839b1d096Skre bzero(ualloc, 8*1024);
9692101e181Skre
9702101e181Skre /*
971d9a5e0b6Swnj * Map the first page of UNIBUS i/o
972d9a5e0b6Swnj * space to the first page of memory
973d9a5e0b6Swnj * for devices which will need to dma
974d9a5e0b6Swnj * output to produce an interrupt.
975d9a5e0b6Swnj */
976b3a411d4Skarels *(int *)(&uhp->uh_mr[0]) = UBAMR_MRV;
977d9a5e0b6Swnj
978b3a411d4Skarels #define ubaddr(uhp, off) (u_short *)((int)(uhp)->uh_iopage + ubdevreg(off))
979d9a5e0b6Swnj /*
980d9a5e0b6Swnj * Check each unibus mass storage controller.
981d9a5e0b6Swnj * For each one which is potentially on this uba,
982d9a5e0b6Swnj * see if it is really there, and if it is record it and
983d9a5e0b6Swnj * then go looking for slaves.
984d9a5e0b6Swnj */
985d9a5e0b6Swnj for (um = ubminit; udp = um->um_driver; um++) {
986762ff349Skarels if (um->um_ubanum != numuba && um->um_ubanum != '?' ||
987762ff349Skarels um->um_alive)
988b8054636Swnj continue;
989d9a5e0b6Swnj addr = (u_short)um->um_addr;
9902101e181Skre /*
9912101e181Skre * use the particular address specified first,
9922101e181Skre * or if it is given as "0", of there is no device
9932101e181Skre * at that address, try all the standard addresses
9942101e181Skre * in the driver til we find it
9952101e181Skre */
9962101e181Skre for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
9972101e181Skre
998b3a411d4Skarels if (ualloc[ubdevreg(addr)])
9992101e181Skre continue;
1000b3a411d4Skarels reg = ubaddr(uhp, addr);
1001b8054636Swnj if (badaddr((caddr_t)reg, 2))
1002b8054636Swnj continue;
1003b3a411d4Skarels #ifdef DW780
1004b3a411d4Skarels if (uhp->uh_type == DW780 && vubp->uba_sr) {
1005d9a5e0b6Swnj vubp->uba_sr = vubp->uba_sr;
1006b8054636Swnj continue;
1007b8054636Swnj }
1008b8054636Swnj #endif
1009b8054636Swnj cvec = 0x200;
1010d70b5589Skarels rcvec = 0x200;
1011b14355dbSkarels i = (*udp->ud_probe)(reg, um->um_ctlr, um);
1012b3a411d4Skarels #ifdef DW780
1013b3a411d4Skarels if (uhp->uh_type == DW780 && vubp->uba_sr) {
1014d9a5e0b6Swnj vubp->uba_sr = vubp->uba_sr;
1015b8054636Swnj continue;
1016b8054636Swnj }
1017b8054636Swnj #endif
1018b8054636Swnj if (i == 0)
1019b8054636Swnj continue;
10208a75d5d5Swnj printf("%s%d at uba%d csr %o ",
10218a75d5d5Swnj udp->ud_mname, um->um_ctlr, numuba, addr);
1022d70b5589Skarels if (rcvec == 0) {
1023d9a5e0b6Swnj printf("zero vector\n");
1024b8054636Swnj continue;
1025b8054636Swnj }
1026d70b5589Skarels if (rcvec == 0x200) {
1027d9a5e0b6Swnj printf("didn't interrupt\n");
1028b8054636Swnj continue;
1029b8054636Swnj }
1030d70b5589Skarels printf("vec %o, ipl %x\n", rcvec, rbr);
1031628b8f95Skarels csralloc(ualloc, addr, i);
1032d9a5e0b6Swnj um->um_alive = 1;
1033d9a5e0b6Swnj um->um_ubanum = numuba;
1034762ff349Skarels um->um_hd = uhp;
1035d9a5e0b6Swnj um->um_addr = (caddr_t)reg;
1036d9a5e0b6Swnj udp->ud_minfo[um->um_ctlr] = um;
1037d70b5589Skarels for (rcvec /= 4, ivec = um->um_intr; *ivec; rcvec++, ivec++)
1038d70b5589Skarels uhp->uh_vec[rcvec] = scbentry(*ivec, SCB_ISTACK);
1039d9a5e0b6Swnj for (ui = ubdinit; ui->ui_driver; ui++) {
1040762ff349Skarels int t;
1041762ff349Skarels
1042d9a5e0b6Swnj if (ui->ui_driver != udp || ui->ui_alive ||
1043d9a5e0b6Swnj ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
1044d9a5e0b6Swnj ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
1045d9a5e0b6Swnj continue;
1046762ff349Skarels t = ui->ui_ctlr;
1047d9a5e0b6Swnj ui->ui_ctlr = um->um_ctlr;
1048762ff349Skarels if ((*udp->ud_slave)(ui, reg) == 0)
1049762ff349Skarels ui->ui_ctlr = t;
1050762ff349Skarels else {
1051762ff349Skarels ui->ui_alive = 1;
105209e5bb10Swnj ui->ui_ubanum = numuba;
1053762ff349Skarels ui->ui_hd = uhp;
1054b8054636Swnj ui->ui_addr = (caddr_t)reg;
105500b653fcSfeldman ui->ui_physaddr = pumem + ubdevreg(addr);
10568a75d5d5Swnj if (ui->ui_dk && dkn < DK_NDRIVE)
1057c5a2c486Swnj ui->ui_dk = dkn++;
10588a75d5d5Swnj else
10598a75d5d5Swnj ui->ui_dk = -1;
1060d9a5e0b6Swnj ui->ui_mi = um;
106109e5bb10Swnj /* ui_type comes from driver */
1062d9a5e0b6Swnj udp->ud_dinfo[ui->ui_unit] = ui;
1063762ff349Skarels printf("%s%d at %s%d slave %d",
10648a75d5d5Swnj udp->ud_dname, ui->ui_unit,
10658a75d5d5Swnj udp->ud_mname, um->um_ctlr, ui->ui_slave);
1066884ec674Swnj (*udp->ud_attach)(ui);
1067762ff349Skarels printf("\n");
1068d9a5e0b6Swnj }
1069d9a5e0b6Swnj }
10702101e181Skre break;
10712101e181Skre }
1072d9a5e0b6Swnj }
1073d9a5e0b6Swnj /*
1074d9a5e0b6Swnj * Now look for non-mass storage peripherals.
1075d9a5e0b6Swnj */
1076d9a5e0b6Swnj for (ui = ubdinit; udp = ui->ui_driver; ui++) {
1077d9a5e0b6Swnj if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
1078d9a5e0b6Swnj ui->ui_alive || ui->ui_slave != -1)
1079d9a5e0b6Swnj continue;
1080d9a5e0b6Swnj addr = (u_short)ui->ui_addr;
10812101e181Skre
10822101e181Skre for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
10832101e181Skre
1084b3a411d4Skarels if (ualloc[ubdevreg(addr)])
10852101e181Skre continue;
1086b3a411d4Skarels reg = ubaddr(uhp, addr);
1087d9a5e0b6Swnj if (badaddr((caddr_t)reg, 2))
1088d9a5e0b6Swnj continue;
1089b3a411d4Skarels #ifdef DW780
1090b3a411d4Skarels if (uhp->uh_type == DW780 && vubp->uba_sr) {
1091d9a5e0b6Swnj vubp->uba_sr = vubp->uba_sr;
1092d9a5e0b6Swnj continue;
1093d9a5e0b6Swnj }
1094d9a5e0b6Swnj #endif
1095d70b5589Skarels rcvec = 0x200;
1096d9a5e0b6Swnj cvec = 0x200;
1097b14355dbSkarels i = (*udp->ud_probe)(reg, ui);
1098b3a411d4Skarels #ifdef DW780
1099b3a411d4Skarels if (uhp->uh_type == DW780 && vubp->uba_sr) {
1100d9a5e0b6Swnj vubp->uba_sr = vubp->uba_sr;
1101d9a5e0b6Swnj continue;
1102d9a5e0b6Swnj }
1103d9a5e0b6Swnj #endif
1104d9a5e0b6Swnj if (i == 0)
1105d9a5e0b6Swnj continue;
11068a75d5d5Swnj printf("%s%d at uba%d csr %o ",
11078a75d5d5Swnj ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
1108d70b5589Skarels if (rcvec == 0) {
1109d9a5e0b6Swnj printf("zero vector\n");
1110d9a5e0b6Swnj continue;
1111d9a5e0b6Swnj }
1112d70b5589Skarels if (rcvec == 0x200) {
1113d9a5e0b6Swnj printf("didn't interrupt\n");
1114d9a5e0b6Swnj continue;
1115d9a5e0b6Swnj }
1116d70b5589Skarels printf("vec %o, ipl %x\n", rcvec, rbr);
1117628b8f95Skarels csralloc(ualloc, addr, i);
1118762ff349Skarels ui->ui_hd = uhp;
1119d70b5589Skarels for (rcvec /= 4, ivec = ui->ui_intr; *ivec; rcvec++, ivec++)
1120d70b5589Skarels uhp->uh_vec[rcvec] = scbentry(*ivec, SCB_ISTACK);
1121d9a5e0b6Swnj ui->ui_alive = 1;
1122d9a5e0b6Swnj ui->ui_ubanum = numuba;
1123d9a5e0b6Swnj ui->ui_addr = (caddr_t)reg;
112400b653fcSfeldman ui->ui_physaddr = pumem + ubdevreg(addr);
11258a75d5d5Swnj ui->ui_dk = -1;
1126d9a5e0b6Swnj /* ui_type comes from driver */
1127d9a5e0b6Swnj udp->ud_dinfo[ui->ui_unit] = ui;
1128884ec674Swnj (*udp->ud_attach)(ui);
11292101e181Skre break;
1130b8054636Swnj }
1131b8054636Swnj }
1132b8054636Swnj
1133b3a411d4Skarels #ifdef DW780
1134b3a411d4Skarels if (uhp->uh_type == DW780)
1135b3a411d4Skarels uhp->uh_uba->uba_cr = UBACR_IFS | UBACR_BRIE |
1136b3a411d4Skarels UBACR_USEFIE | UBACR_SUEFIE |
1137b3a411d4Skarels (uhp->uh_uba->uba_cr & 0x7c000000);
1138b3a411d4Skarels #endif
1139b3a411d4Skarels numuba++;
1140b3a411d4Skarels
11412101e181Skre #ifdef AUTO_DEBUG
11422101e181Skre printf("Unibus allocation map");
11432101e181Skre for (i = 0; i < 8*1024; ) {
11442101e181Skre register n, m;
11452101e181Skre
11462101e181Skre if ((i % 128) == 0) {
11472101e181Skre printf("\n%6o:", i);
11482101e181Skre for (n = 0; n < 128; n++)
11492101e181Skre if (ualloc[i+n])
11502101e181Skre break;
11512101e181Skre if (n == 128) {
11522101e181Skre i += 128;
11532101e181Skre continue;
11542101e181Skre }
11552101e181Skre }
11562101e181Skre
11572101e181Skre for (n = m = 0; n < 16; n++) {
11582101e181Skre m <<= 1;
11592101e181Skre m |= ualloc[i++];
11602101e181Skre }
11612101e181Skre
11622101e181Skre printf(" %4x", m);
11632101e181Skre }
11642101e181Skre printf("\n");
11652101e181Skre #endif
11662101e181Skre
1167c2f959ceSmckusick free(ualloc, M_TEMP);
11682101e181Skre }
1169762ff349Skarels #endif /* NUBA */
11702101e181Skre
1171b8054636Swnj /*
1172628b8f95Skarels * Mark addresses starting at "addr" and continuing
1173628b8f95Skarels * "size" bytes as allocated in the map "ualloc".
1174628b8f95Skarels * Warn if the new allocation overlaps a previous allocation.
1175628b8f95Skarels */
1176628b8f95Skarels static
csralloc(ualloc,addr,size)1177628b8f95Skarels csralloc(ualloc, addr, size)
1178628b8f95Skarels caddr_t ualloc;
1179628b8f95Skarels u_short addr;
1180628b8f95Skarels register int size;
1181628b8f95Skarels {
1182628b8f95Skarels register caddr_t p;
1183628b8f95Skarels int warned = 0;
1184628b8f95Skarels
1185628b8f95Skarels p = &ualloc[ubdevreg(addr+size)];
1186628b8f95Skarels while (--size >= 0) {
1187628b8f95Skarels if (*--p && !warned) {
1188628b8f95Skarels printf(
1189628b8f95Skarels "WARNING: device registers overlap those for a previous device!\n");
1190628b8f95Skarels warned = 1;
1191628b8f95Skarels }
1192628b8f95Skarels *p = 1;
1193628b8f95Skarels }
1194628b8f95Skarels }
1195628b8f95Skarels
1196628b8f95Skarels /*
1197a8b6ec1fSkarels * Make an IO register area accessible at physical address physa
1198b8054636Swnj * by mapping kernel ptes starting at pte.
1199b8054636Swnj */
ioaccess(physa,pte,size)120032e110b5Skarels ioaccess(physa, pte, size)
1201a8b6ec1fSkarels caddr_t physa;
1202b8054636Swnj register struct pte *pte;
1203a089c9d9Sbloom int size;
1204b8054636Swnj {
1205b3a411d4Skarels register int i = btoc(size);
1206d9a5e0b6Swnj register unsigned v = btop(physa);
1207b8054636Swnj
1208b8054636Swnj do
1209b8054636Swnj *(int *)pte++ = PG_V|PG_KW|v++;
12106d315329Swnj while (--i > 0);
1211b8054636Swnj mtpr(TBIA, 0);
1212b8054636Swnj }
1213b404ff6cSfeldman
121401cdfd67Ssam /*
121501cdfd67Ssam * Configure swap space and related parameters.
121601cdfd67Ssam */
swapconf()121701cdfd67Ssam swapconf()
121801cdfd67Ssam {
121901cdfd67Ssam register struct swdevt *swp;
122088df6acbSsam register int nblks;
122101cdfd67Ssam
1222*2c107824Storek for (swp = swdevt; swp->sw_dev != NODEV; swp++)
1223f55d1ae0Skarels if (bdevsw[major(swp->sw_dev)].d_psize) {
122488df6acbSsam nblks =
122501cdfd67Ssam (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
1226e8887a6eSkarels if (nblks != -1 &&
1227e8887a6eSkarels (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
122888df6acbSsam swp->sw_nblks = nblks;
122901cdfd67Ssam }
1230d70b5589Skarels dumpconf();
123101cdfd67Ssam }
1232f187dfb0Skarels
1233f187dfb0Skarels #define DOSWAP /* Change swdevt, argdev, and dumpdev too */
1234f187dfb0Skarels u_long bootdev; /* should be dev_t, but not until 32 bits */
1235f187dfb0Skarels
1236f187dfb0Skarels static char devname[][2] = {
1237f187dfb0Skarels 'h','p', /* 0 = hp */
1238f187dfb0Skarels 0,0, /* 1 = ht */
1239f187dfb0Skarels 'u','p', /* 2 = up */
1240f187dfb0Skarels 'r','k', /* 3 = hk */
1241f187dfb0Skarels 0,0, /* 4 = sw */
1242f187dfb0Skarels 0,0, /* 5 = tm */
1243f187dfb0Skarels 0,0, /* 6 = ts */
1244f187dfb0Skarels 0,0, /* 7 = mt */
1245f187dfb0Skarels 0,0, /* 8 = tu */
1246f187dfb0Skarels 'r','a', /* 9 = ra */
1247f187dfb0Skarels 0,0, /* 10 = ut */
1248f187dfb0Skarels 'r','b', /* 11 = rb */
1249f187dfb0Skarels 0,0, /* 12 = uu */
1250f187dfb0Skarels 0,0, /* 13 = rx */
1251f187dfb0Skarels 'r','l', /* 14 = rl */
1252762ff349Skarels 0,0, /* 15 = tmscp */
1253762ff349Skarels 'k','r', /* 16 = ra on kdb50 */
1254f187dfb0Skarels };
1255f187dfb0Skarels
1256f187dfb0Skarels #define PARTITIONMASK 0x7
1257f187dfb0Skarels #define PARTITIONSHIFT 3
1258f187dfb0Skarels
1259f187dfb0Skarels /*
1260f187dfb0Skarels * Attempt to find the device from which we were booted.
1261f187dfb0Skarels * If we can do so, and not instructed not to do so,
1262f187dfb0Skarels * change rootdev to correspond to the load device.
1263f187dfb0Skarels */
setroot()1264f187dfb0Skarels setroot()
1265f187dfb0Skarels {
12668c011102Skarels int majdev, mindev, unit, part, controller, adaptor;
1267f187dfb0Skarels dev_t temp, orootdev;
1268f187dfb0Skarels struct swdevt *swp;
1269f187dfb0Skarels
1270de0dda68Skridle if (boothowto & RB_DFLTROOT ||
1271de0dda68Skridle (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
1272cdd5ba0eSkarels return;
12738c011102Skarels majdev = B_TYPE(bootdev);
12748c011102Skarels if (majdev >= sizeof(devname) / sizeof(devname[0]))
1275cdd5ba0eSkarels return;
12768c011102Skarels adaptor = B_ADAPTOR(bootdev);
12778c011102Skarels controller = B_CONTROLLER(bootdev);
12788c011102Skarels part = B_PARTITION(bootdev);
12798c011102Skarels unit = B_UNIT(bootdev);
1280f187dfb0Skarels if (majdev == 0) { /* MBA device */
128114e1df5dSkarels #if NMBA > 0
1282f187dfb0Skarels register struct mba_device *mbap;
128314e1df5dSkarels int mask;
1284f187dfb0Skarels
128514e1df5dSkarels /*
128614e1df5dSkarels * The MBA number used at boot time is not necessarily the same as the
128714e1df5dSkarels * MBA number used by the kernel. In order to change the rootdev we need to
128814e1df5dSkarels * convert the boot MBA number to the kernel MBA number. The address space
128914e1df5dSkarels * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number
129014e1df5dSkarels * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750.
129114e1df5dSkarels * Therefore we can search the mba_hd table for the MBA that has the physical
129214e1df5dSkarels * address corresponding to the boot MBA number.
129314e1df5dSkarels */
129414e1df5dSkarels #define PHYSADRSHFT 13
129514e1df5dSkarels #define PHYSMBAMASK780 0x7
129614e1df5dSkarels #define PHYSMBAMASK750 0x3
129714e1df5dSkarels
129814e1df5dSkarels switch (cpu) {
129914e1df5dSkarels
130014e1df5dSkarels case VAX_780:
130114e1df5dSkarels case VAX_8600:
130214e1df5dSkarels default:
130314e1df5dSkarels mask = PHYSMBAMASK780;
130414e1df5dSkarels break;
130514e1df5dSkarels
130614e1df5dSkarels case VAX_750:
130714e1df5dSkarels mask = PHYSMBAMASK750;
130814e1df5dSkarels break;
130914e1df5dSkarels }
1310f187dfb0Skarels for (mbap = mbdinit; mbap->mi_driver; mbap++)
1311f187dfb0Skarels if (mbap->mi_alive && mbap->mi_drive == unit &&
131214e1df5dSkarels (((long)mbap->mi_hd->mh_physmba >> PHYSADRSHFT)
131314e1df5dSkarels & mask) == adaptor)
1314f187dfb0Skarels break;
1315f187dfb0Skarels if (mbap->mi_driver == 0)
1316cdd5ba0eSkarels return;
1317f187dfb0Skarels mindev = mbap->mi_unit;
131814e1df5dSkarels #else
1319cdd5ba0eSkarels return;
13205c841cf1Skarels #endif
132114e1df5dSkarels } else {
1322f187dfb0Skarels register struct uba_device *ubap;
1323f187dfb0Skarels
1324f187dfb0Skarels for (ubap = ubdinit; ubap->ui_driver; ubap++)
1325f187dfb0Skarels if (ubap->ui_alive && ubap->ui_slave == unit &&
13268c011102Skarels ubap->ui_ctlr == controller &&
1327f187dfb0Skarels ubap->ui_ubanum == adaptor &&
1328f187dfb0Skarels ubap->ui_driver->ud_dname[0] == devname[majdev][0] &&
1329f187dfb0Skarels ubap->ui_driver->ud_dname[1] == devname[majdev][1])
1330f187dfb0Skarels break;
1331f187dfb0Skarels
1332f187dfb0Skarels if (ubap->ui_driver == 0)
1333cdd5ba0eSkarels return;
1334f187dfb0Skarels mindev = ubap->ui_unit;
1335f187dfb0Skarels }
1336f187dfb0Skarels mindev = (mindev << PARTITIONSHIFT) + part;
1337f187dfb0Skarels orootdev = rootdev;
1338f187dfb0Skarels rootdev = makedev(majdev, mindev);
1339f187dfb0Skarels /*
1340f187dfb0Skarels * If the original rootdev is the same as the one
1341f187dfb0Skarels * just calculated, don't need to adjust the swap configuration.
1342f187dfb0Skarels */
1343f187dfb0Skarels if (rootdev == orootdev)
1344cdd5ba0eSkarels return;
1345f187dfb0Skarels
13464eec7f0eSkarels printf("Changing root device to %c%c%d%c\n",
13474eec7f0eSkarels devname[majdev][0], devname[majdev][1],
13484eec7f0eSkarels mindev >> PARTITIONSHIFT, part + 'a');
13499a448baeSkarels
13509a448baeSkarels #ifdef DOSWAP
1351f187dfb0Skarels mindev &= ~PARTITIONMASK;
1352*2c107824Storek for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
1353f187dfb0Skarels if (majdev == major(swp->sw_dev) &&
1354f187dfb0Skarels mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
1355f187dfb0Skarels temp = swdevt[0].sw_dev;
1356f187dfb0Skarels swdevt[0].sw_dev = swp->sw_dev;
1357f187dfb0Skarels swp->sw_dev = temp;
1358f187dfb0Skarels break;
1359f187dfb0Skarels }
1360f187dfb0Skarels }
1361*2c107824Storek if (swp->sw_dev == NODEV)
1362cdd5ba0eSkarels return;
1363f187dfb0Skarels
1364f187dfb0Skarels /*
1365f187dfb0Skarels * If argdev and dumpdev were the same as the old primary swap
1366f187dfb0Skarels * device, move them to the new primary swap device.
1367f187dfb0Skarels */
1368f187dfb0Skarels if (temp == dumpdev)
1369f187dfb0Skarels dumpdev = swdevt[0].sw_dev;
1370f187dfb0Skarels if (temp == argdev)
1371f187dfb0Skarels argdev = swdevt[0].sw_dev;
1372f187dfb0Skarels #endif
1373f187dfb0Skarels }
1374