1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1992 The Regents of the University of California. 4 * 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 7.3 (Berkeley) 03/29/92 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 "param.h" 26 #include "systm.h" 27 #include "map.h" 28 #include "buf.h" 29 #include "dkstat.h" 30 #include "conf.h" 31 #include "dmap.h" 32 #include "reboot.h" 33 34 #include "../include/cpu.h" 35 #include "../dev/device.h" 36 37 /* 38 * The following several variables are related to 39 * the configuration process, and are used in initializing 40 * the machine. 41 */ 42 int cold = 1; /* if 1, still working on cold-start */ 43 int dkn; /* number of iostat dk numbers assigned so far */ 44 int cpuspeed = 30; /* approx # instr per usec. */ 45 46 /* 47 * Determine mass storage and memory configuration for a machine. 48 * Get cpu type, and then switch out to machine specific procedures 49 * which will probe adaptors to see what is out there. 50 */ 51 configure() 52 { 53 register struct pmax_ctlr *cp; 54 register struct scsi_device *dp; 55 register struct driver *drp; 56 #ifdef DS5000 57 register int i; 58 #endif 59 60 /* print what type of CPU and FPU we have */ 61 switch (cpu.cpu.cp_imp) { 62 case MIPS_R2000: 63 printf("cpu0 (MIPS R2000 revision %d.%d)\n", 64 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 65 break; 66 67 case MIPS_R3000: 68 printf("cpu0 (MIPS R3000 revision %d.%d)\n", 69 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 70 break; 71 72 case MIPS_R4000: 73 printf("cpu0 (MIPS R4000 revision %d.%d)\n", 74 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 75 break; 76 77 default: 78 printf("cpu0 (implementation %d revision %d.%d)\n", 79 cpu.cpu.cp_imp, cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 80 } 81 switch (fpu.cpu.cp_imp) { 82 case MIPS_R2010: 83 printf("fpu0 (MIPS R2010 revision %d.%d)\n", 84 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 85 break; 86 87 case MIPS_R3010: 88 printf("fpu0 (MIPS R3010 revision %d.%d)\n", 89 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 90 break; 91 92 case MIPS_R4010: 93 printf("fpu0 (MIPS R4010 revision %d.%d)\n", 94 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 95 break; 96 97 default: 98 printf("fpu0 (implementation %d revision %d.%d)\n", 99 fpu.cpu.cp_imp, fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 100 } 101 printf("data cache size %dK inst cache size %dK\n", 102 machDataCacheSize >> 10, machInstCacheSize >> 10); 103 104 /* probe and initialize controllers */ 105 for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { 106 #ifdef DS3100 107 if (!(*drp->d_init)(cp)) 108 continue; 109 #endif 110 #ifdef DS5000 111 /* 112 * If the device is still in an unknown slot, 113 * then it was not found by tc_find_all_options(). 114 */ 115 if (cp->pmax_addr == (char *)QUES) 116 continue; 117 if (!(*drp->d_init)(cp)) 118 continue; 119 if (drp->d_intr && (i = cp->pmax_pri) >= 0) { 120 if (intr_tab[i].func) 121 printf("%s: slot %d already in use\n", 122 drp->d_name, i); 123 intr_tab[i].func = drp->d_intr; 124 intr_tab[i].unit = cp->pmax_unit; 125 tc_enable_interrupt(i, 1); 126 } 127 #endif 128 129 cp->pmax_alive = 1; 130 131 /* probe and initialize devices connected to controller */ 132 for (dp = scsi_dinit; drp = dp->sd_driver; dp++) { 133 /* might want to get fancier later */ 134 if (dp->sd_cdriver != cp->pmax_driver || 135 dp->sd_ctlr != cp->pmax_unit) 136 continue; /* not connected */ 137 if (!(*drp->d_init)(dp)) 138 continue; 139 dp->sd_alive = 1; 140 /* if device is a disk, assign number for statistics */ 141 if (dp->sd_dk && dkn < DK_NDRIVE) 142 dp->sd_dk = dkn++; 143 else 144 dp->sd_dk = -1; 145 } 146 } 147 148 #if GENERIC 149 if ((boothowto & RB_ASKNAME) == 0) 150 setroot(); 151 setconf(); 152 #else 153 setroot(); 154 #endif 155 swapconf(); 156 cold = 0; 157 } 158 159 /* 160 * Configure swap space and related parameters. 161 */ 162 swapconf() 163 { 164 register struct swdevt *swp; 165 register int nblks; 166 167 for (swp = swdevt; swp->sw_dev; swp++) 168 if (bdevsw[major(swp->sw_dev)].d_psize) { 169 nblks = 170 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 171 if (nblks != -1 && 172 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 173 swp->sw_nblks = nblks; 174 } 175 dumpconf(); 176 } 177 178 #define DOSWAP /* Change swdevt and dumpdev too */ 179 u_long bootdev; /* should be dev_t, but not until 32 bits */ 180 181 static char devname[][2] = { 182 'r','z', /* 0 = rz */ 183 }; 184 185 #define PARTITIONMASK 0x7 186 #define PARTITIONSHIFT 3 187 188 /* 189 * Attempt to find the device from which we were booted. 190 * If we can do so, and not instructed not to do so, 191 * change rootdev to correspond to the load device. 192 */ 193 setroot() 194 { 195 register struct scsi_device *dp; 196 int majdev, mindev, unit, part, controller; 197 dev_t temp, orootdev; 198 struct swdevt *swp; 199 200 if (boothowto & RB_DFLTROOT || 201 (bootdev & B_MAGICMASK) != B_DEVMAGIC) 202 return; 203 majdev = B_TYPE(bootdev); 204 if (majdev >= sizeof(devname) / sizeof(devname[0])) 205 return; 206 controller = B_CONTROLLER(bootdev); 207 part = B_PARTITION(bootdev); 208 unit = B_UNIT(bootdev); 209 210 for (dp = scsi_dinit; ; dp++) { 211 if (dp->sd_driver == 0) 212 return; 213 if (dp->sd_alive && dp->sd_drive == unit && 214 dp->sd_ctlr == controller && 215 dp->sd_driver->d_name[0] == devname[majdev][0] && 216 dp->sd_driver->d_name[1] == devname[majdev][1]) { 217 mindev = dp->sd_unit; 218 break; 219 } 220 } 221 /* 222 * Form a new rootdev 223 */ 224 mindev = (mindev << PARTITIONSHIFT) + part; 225 orootdev = rootdev; 226 rootdev = makedev(majdev, mindev); 227 /* 228 * If the original rootdev is the same as the one 229 * just calculated, don't need to adjust the swap configuration. 230 */ 231 if (rootdev == orootdev) 232 return; 233 234 printf("Changing root device to %c%c%d%c\n", 235 devname[majdev][0], devname[majdev][1], 236 mindev >> PARTITIONSHIFT, part + 'a'); 237 238 #ifdef DOSWAP 239 mindev &= ~PARTITIONMASK; 240 for (swp = swdevt; swp->sw_dev; swp++) { 241 if (majdev == major(swp->sw_dev) && 242 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 243 temp = swdevt[0].sw_dev; 244 swdevt[0].sw_dev = swp->sw_dev; 245 swp->sw_dev = temp; 246 break; 247 } 248 } 249 if (swp->sw_dev == 0) 250 return; 251 252 /* 253 * If dumpdev was the same as the old primary swap 254 * device, move it to the new primary swap device. 255 */ 256 if (temp == dumpdev) 257 dumpdev = swdevt[0].sw_dev; 258 #endif 259 } 260 261 /* 262 * Look at the string 'cp' and decode the boot device. 263 */ 264 void 265 makebootdev(cp) 266 register char *cp; 267 { 268 int majdev, unit, part, ctrl; 269 270 for (majdev = 0; majdev < sizeof(devname)/sizeof(devname[0]); majdev++) 271 if (cp[0] == devname[majdev][0] && 272 cp[1] == devname[majdev][1] && 273 cp[2] == '(') 274 goto fndmaj; 275 defdev: 276 bootdev = B_DEVMAGIC; 277 return; 278 279 fndmaj: 280 for (ctrl = 0, cp += 3; *cp >= '0' && *cp <= '9'; ) 281 ctrl = ctrl * 10 + *cp++ - '0'; 282 if (*cp == ',') 283 cp++; 284 for (unit = 0; *cp >= '0' && *cp <= '9'; ) 285 unit = unit * 10 + *cp++ - '0'; 286 if (*cp == ',') 287 cp++; 288 for (part = 0; *cp >= '0' && *cp <= '9'; ) 289 part = part * 10 + *cp++ - '0'; 290 if (*cp != ')') 291 goto defdev; 292 bootdev = MAKEBOOTDEV(majdev, 0, ctrl, unit, part); 293 } 294