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