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