1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department and Ralph Campbell. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: autoconf.c 1.31 91/01/21$ 13 * 14 * @(#)autoconf.c 8.1 (Berkeley) 06/10/93 15 */ 16 17 /* 18 * Setup the system to run on the current machine. 19 * 20 * Configure() is called at boot time. Available 21 * devices are determined (from possibilities mentioned in ioconf.c), 22 * and the drivers are initialized. 23 */ 24 25 #include <sys/param.h> 26 #include <sys/systm.h> 27 #include <sys/map.h> 28 #include <sys/buf.h> 29 #include <sys/dkstat.h> 30 #include <sys/conf.h> 31 #include <sys/dmap.h> 32 #include <sys/reboot.h> 33 34 #include <machine/cpu.h> 35 #include <pmax/dev/device.h> 36 #include <pmax/pmax/pmaxtype.h> 37 #include <pmax/pmax/turbochannel.h> 38 39 /* 40 * The following several variables are related to 41 * the configuration process, and are used in initializing 42 * the machine. 43 */ 44 int cold = 1; /* if 1, still working on cold-start */ 45 int dkn; /* number of iostat dk numbers assigned so far */ 46 int cpuspeed = 30; /* approx # instr per usec. */ 47 extern int pmax_boardtype; 48 extern tc_option_t tc_slot_info[TC_MAX_LOGICAL_SLOTS]; 49 50 /* 51 * Determine mass storage and memory configuration for a machine. 52 * Get cpu type, and then switch out to machine specific procedures 53 * which will probe adaptors to see what is out there. 54 */ 55 configure() 56 { 57 register struct pmax_ctlr *cp; 58 register struct scsi_device *dp; 59 register struct driver *drp; 60 register int i; 61 62 /* print what type of CPU and FPU we have */ 63 64 /* 65 * for some reason the Pmax has an R2000 cpu with an implementation 66 * level of 2 and DEC's R3000s are level 2 as well? 67 */ 68 if (pmax_boardtype == DS_PMAX) { 69 cpu.cpu.cp_imp = MIPS_R2000; 70 fpu.cpu.cp_imp = MIPS_R2010; 71 } 72 73 switch (cpu.cpu.cp_imp) { 74 case MIPS_R2000: 75 printf("cpu0 (MIPS R2000 revision %d.%d)\n", 76 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 77 break; 78 79 case MIPS_R3000: 80 printf("cpu0 (MIPS R3000 revision %d.%d)\n", 81 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 82 break; 83 84 case MIPS_R4000: 85 printf("cpu0 (MIPS R4000 revision %d.%d)\n", 86 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 87 break; 88 89 default: 90 printf("cpu0 (implementation %d revision %d.%d)\n", 91 cpu.cpu.cp_imp, cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 92 } 93 switch (fpu.cpu.cp_imp) { 94 case MIPS_R2010: 95 printf("fpu0 (MIPS R2010 revision %d.%d)\n", 96 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 97 break; 98 99 case MIPS_R3010: 100 printf("fpu0 (MIPS R3010 revision %d.%d)\n", 101 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 102 break; 103 104 case MIPS_R4010: 105 printf("fpu0 (MIPS R4010 revision %d.%d)\n", 106 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 107 break; 108 109 default: 110 printf("fpu0 (implementation %d revision %d.%d)\n", 111 fpu.cpu.cp_imp, fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 112 } 113 printf("data cache size %dK inst cache size %dK\n", 114 machDataCacheSize >> 10, machInstCacheSize >> 10); 115 116 /* probe and initialize controllers */ 117 for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { 118 switch (pmax_boardtype) { 119 case DS_PMAX: 120 if (cp->pmax_addr == (char *)QUES) 121 continue; 122 if (!(*drp->d_init)(cp)) 123 continue; 124 break; 125 #ifdef DS5000 126 case DS_3MAX: 127 case DS_3MIN: 128 case DS_MAXINE: 129 case DS_3MAXPLUS: 130 /* 131 * If the device is still in an unknown slot, 132 * then it was not found by tc_find_all_options(). 133 */ 134 if (cp->pmax_addr == (char *)QUES) 135 continue; 136 if (!(*drp->d_init)(cp)) { 137 cp->pmax_alive = 0; 138 continue; 139 } 140 if (drp->d_intr && (i = cp->pmax_pri) >= 0) { 141 if (tc_slot_info[i].intr) 142 printf("%s: slot %d already in use\n", 143 drp->d_name, i); 144 tc_slot_info[i].intr = drp->d_intr; 145 tc_slot_info[i].unit = cp->pmax_unit; 146 } 147 break; 148 #endif /* DS5000 */ 149 }; 150 151 cp->pmax_alive = 1; 152 153 /* probe and initialize devices connected to controller */ 154 for (dp = scsi_dinit; drp = dp->sd_driver; dp++) { 155 /* might want to get fancier later */ 156 if (dp->sd_cdriver != cp->pmax_driver || 157 dp->sd_ctlr != cp->pmax_unit) 158 continue; /* not connected */ 159 if (!(*drp->d_init)(dp)) 160 continue; 161 dp->sd_alive = 1; 162 /* if device is a disk, assign number for statistics */ 163 if (dp->sd_dk && dkn < DK_NDRIVE) 164 dp->sd_dk = dkn++; 165 else 166 dp->sd_dk = -1; 167 } 168 } 169 170 #ifdef GENERIC 171 if ((boothowto & RB_ASKNAME) == 0) 172 setroot(); 173 setconf(); 174 #else 175 setroot(); 176 #endif 177 swapconf(); 178 cold = 0; 179 } 180 181 /* 182 * Configure swap space and related parameters. 183 */ 184 swapconf() 185 { 186 register struct swdevt *swp; 187 register int nblks; 188 189 for (swp = swdevt; swp->sw_dev != NODEV; swp++) 190 if (bdevsw[major(swp->sw_dev)].d_psize) { 191 nblks = 192 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 193 if (nblks != -1 && 194 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 195 swp->sw_nblks = nblks; 196 } 197 dumpconf(); 198 } 199 200 #define DOSWAP /* Change swdevt and dumpdev too */ 201 u_long bootdev; /* should be dev_t, but not until 32 bits */ 202 203 static char devname[][2] = { 204 'r','z', /* 0 = rz */ 205 }; 206 207 #define PARTITIONMASK 0x7 208 #define PARTITIONSHIFT 3 209 210 /* 211 * Attempt to find the device from which we were booted. 212 * If we can do so, and not instructed not to do so, 213 * change rootdev to correspond to the load device. 214 */ 215 setroot() 216 { 217 register struct scsi_device *dp; 218 int majdev, mindev, unit, part, controller; 219 dev_t temp, orootdev; 220 struct swdevt *swp; 221 222 if (boothowto & RB_DFLTROOT || 223 (bootdev & B_MAGICMASK) != B_DEVMAGIC) 224 return; 225 majdev = B_TYPE(bootdev); 226 if (majdev >= sizeof(devname) / sizeof(devname[0])) 227 return; 228 controller = B_CONTROLLER(bootdev); 229 part = B_PARTITION(bootdev); 230 unit = B_UNIT(bootdev); 231 232 for (dp = scsi_dinit; ; dp++) { 233 if (dp->sd_driver == 0) 234 return; 235 if (dp->sd_alive && dp->sd_drive == unit && 236 dp->sd_ctlr == controller && 237 dp->sd_driver->d_name[0] == devname[majdev][0] && 238 dp->sd_driver->d_name[1] == devname[majdev][1]) { 239 mindev = dp->sd_unit; 240 break; 241 } 242 } 243 /* 244 * Form a new rootdev 245 */ 246 mindev = (mindev << PARTITIONSHIFT) + part; 247 orootdev = rootdev; 248 rootdev = makedev(majdev, mindev); 249 /* 250 * If the original rootdev is the same as the one 251 * just calculated, don't need to adjust the swap configuration. 252 */ 253 if (rootdev == orootdev) 254 return; 255 256 printf("Changing root device to %c%c%d%c\n", 257 devname[majdev][0], devname[majdev][1], 258 mindev >> PARTITIONSHIFT, part + 'a'); 259 260 #ifdef DOSWAP 261 mindev &= ~PARTITIONMASK; 262 for (swp = swdevt; swp->sw_dev != NODEV; swp++) { 263 if (majdev == major(swp->sw_dev) && 264 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 265 temp = swdevt[0].sw_dev; 266 swdevt[0].sw_dev = swp->sw_dev; 267 swp->sw_dev = temp; 268 break; 269 } 270 } 271 if (swp->sw_dev == NODEV) 272 return; 273 274 /* 275 * If dumpdev was the same as the old primary swap 276 * device, move it to the new primary swap device. 277 */ 278 if (temp == dumpdev) 279 dumpdev = swdevt[0].sw_dev; 280 #endif 281 } 282 283 /* 284 * Look at the string 'cp' and decode the boot device. 285 * Boot names can be something like 'rz(0,0,0)vmunix' or '5/rz0/vmunix'. 286 */ 287 void 288 makebootdev(cp) 289 register char *cp; 290 { 291 int majdev, unit, part, ctrl; 292 293 if (*cp >= '0' && *cp <= '9') { 294 /* XXX should be able to specify controller */ 295 if (cp[1] != '/' || cp[4] < '0' || cp[4] > '9') 296 goto defdev; 297 unit = cp[4] - '0'; 298 if (cp[5] >= 'a' && cp[5] <= 'h') 299 part = cp[5] - 'a'; 300 else 301 part = 0; 302 cp += 2; 303 for (majdev = 0; majdev < sizeof(devname)/sizeof(devname[0]); 304 majdev++) { 305 if (cp[0] == devname[majdev][0] && 306 cp[1] == devname[majdev][1]) { 307 bootdev = MAKEBOOTDEV(majdev, 0, 0, unit, part); 308 return; 309 } 310 } 311 goto defdev; 312 } 313 for (majdev = 0; majdev < sizeof(devname)/sizeof(devname[0]); majdev++) 314 if (cp[0] == devname[majdev][0] && 315 cp[1] == devname[majdev][1] && 316 cp[2] == '(') 317 goto fndmaj; 318 defdev: 319 bootdev = B_DEVMAGIC; 320 return; 321 322 fndmaj: 323 for (ctrl = 0, cp += 3; *cp >= '0' && *cp <= '9'; ) 324 ctrl = ctrl * 10 + *cp++ - '0'; 325 if (*cp == ',') 326 cp++; 327 for (unit = 0; *cp >= '0' && *cp <= '9'; ) 328 unit = unit * 10 + *cp++ - '0'; 329 if (*cp == ',') 330 cp++; 331 for (part = 0; *cp >= '0' && *cp <= '9'; ) 332 part = part * 10 + *cp++ - '0'; 333 if (*cp != ')') 334 goto defdev; 335 bootdev = MAKEBOOTDEV(majdev, 0, ctrl, unit, part); 336 } 337