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.1 (Berkeley) 01/07/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 57 /* print what type of CPU and FPU we have */ 58 switch (cpu.cpu.cp_imp) { 59 case MIPS_R2000: 60 printf("cpu0 (MIPS R2000 revision %d.%d)\n", 61 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 62 break; 63 64 default: 65 printf("cpu0 (implementation %d revision %d.%d)\n", 66 cpu.cpu.cp_imp, cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 67 } 68 switch (fpu.cpu.cp_imp) { 69 case MIPS_R2010: 70 printf("fpu0 (MIPS R2010 revision %d.%d)\n", 71 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 72 break; 73 74 default: 75 printf("fpu0 (implementation %d revision %d.%d)\n", 76 fpu.cpu.cp_imp, fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 77 } 78 printf("data cache size %dK inst cache size %dK\n", 79 machDataCacheSize >> 10, machInstCacheSize >> 10); 80 81 /* probe and initialize controllers */ 82 for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { 83 if (!(*drp->d_init)(cp)) 84 continue; 85 86 cp->pmax_alive = 1; 87 88 /* probe and initialize devices connected to controller */ 89 for (dp = scsi_dinit; drp = dp->sd_driver; dp++) { 90 /* might want to get fancier later */ 91 if (dp->sd_cdriver != cp->pmax_driver || 92 dp->sd_ctlr != cp->pmax_unit) 93 continue; /* not connected */ 94 if (!(*drp->d_init)(dp)) 95 continue; 96 dp->sd_alive = 1; 97 /* if device is a disk, assign number for statistics */ 98 if (dp->sd_dk && dkn < DK_NDRIVE) 99 dp->sd_dk = dkn++; 100 else 101 dp->sd_dk = -1; 102 } 103 } 104 105 #if GENERIC 106 if ((boothowto & RB_ASKNAME) == 0) 107 setroot(); 108 setconf(); 109 #else 110 setroot(); 111 #endif 112 swapconf(); 113 cold = 0; 114 } 115 116 /* 117 * Configure swap space and related parameters. 118 */ 119 swapconf() 120 { 121 register struct swdevt *swp; 122 register int nblks; 123 124 for (swp = swdevt; swp->sw_dev; swp++) 125 if (bdevsw[major(swp->sw_dev)].d_psize) { 126 nblks = 127 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 128 if (nblks != -1 && 129 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 130 swp->sw_nblks = nblks; 131 } 132 dumpconf(); 133 } 134 135 #define DOSWAP /* Change swdevt and dumpdev too */ 136 u_long bootdev; /* should be dev_t, but not until 32 bits */ 137 138 static char devname[][2] = { 139 'r','z', /* 0 = rz */ 140 }; 141 142 #define PARTITIONMASK 0x7 143 #define PARTITIONSHIFT 3 144 145 /* 146 * Attempt to find the device from which we were booted. 147 * If we can do so, and not instructed not to do so, 148 * change rootdev to correspond to the load device. 149 */ 150 setroot() 151 { 152 register struct scsi_device *dp; 153 int majdev, mindev, unit, part, controller; 154 dev_t temp, orootdev; 155 struct swdevt *swp; 156 157 if (boothowto & RB_DFLTROOT || 158 (bootdev & B_MAGICMASK) != B_DEVMAGIC) 159 return; 160 majdev = B_TYPE(bootdev); 161 if (majdev >= sizeof(devname) / sizeof(devname[0])) 162 return; 163 controller = B_CONTROLLER(bootdev); 164 part = B_PARTITION(bootdev); 165 unit = B_UNIT(bootdev); 166 167 for (dp = scsi_dinit; ; dp++) { 168 if (dp->sd_driver == 0) 169 return; 170 if (dp->sd_alive && dp->sd_drive == unit && 171 dp->sd_ctlr == controller && 172 dp->sd_driver->d_name[0] == devname[majdev][0] && 173 dp->sd_driver->d_name[1] == devname[majdev][1]) { 174 mindev = dp->sd_unit; 175 break; 176 } 177 } 178 /* 179 * Form a new rootdev 180 */ 181 mindev = (mindev << PARTITIONSHIFT) + part; 182 orootdev = rootdev; 183 rootdev = makedev(majdev, mindev); 184 /* 185 * If the original rootdev is the same as the one 186 * just calculated, don't need to adjust the swap configuration. 187 */ 188 if (rootdev == orootdev) 189 return; 190 191 printf("Changing root device to %c%c%d%c\n", 192 devname[majdev][0], devname[majdev][1], 193 mindev >> PARTITIONSHIFT, part + 'a'); 194 195 #ifdef DOSWAP 196 mindev &= ~PARTITIONMASK; 197 for (swp = swdevt; swp->sw_dev; swp++) { 198 if (majdev == major(swp->sw_dev) && 199 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 200 temp = swdevt[0].sw_dev; 201 swdevt[0].sw_dev = swp->sw_dev; 202 swp->sw_dev = temp; 203 break; 204 } 205 } 206 if (swp->sw_dev == 0) 207 return; 208 209 /* 210 * If dumpdev was the same as the old primary swap 211 * device, move it to the new primary swap device. 212 */ 213 if (temp == dumpdev) 214 dumpdev = swdevt[0].sw_dev; 215 #endif 216 } 217 218 /* 219 * Look at the string 'cp' and decode the boot device. 220 */ 221 void 222 makebootdev(cp) 223 register char *cp; 224 { 225 int majdev, unit, part, ctrl; 226 227 for (majdev = 0; majdev < sizeof(devname)/sizeof(devname[0]); majdev++) 228 if (cp[0] == devname[majdev][0] && 229 cp[1] == devname[majdev][1] && 230 cp[2] == '(') 231 goto fndmaj; 232 defdev: 233 bootdev = B_DEVMAGIC; 234 return; 235 236 fndmaj: 237 for (ctrl = 0, cp += 3; *cp >= '0' && *cp <= '9'; ) 238 ctrl = ctrl * 10 + *cp++ - '0'; 239 if (*cp == ',') 240 cp++; 241 for (unit = 0; *cp >= '0' && *cp <= '9'; ) 242 unit = unit * 10 + *cp++ - '0'; 243 if (*cp == ',') 244 cp++; 245 for (part = 0; *cp >= '0' && *cp <= '9'; ) 246 part = part * 10 + *cp++ - '0'; 247 if (*cp != ')') 248 goto defdev; 249 bootdev = (majdev << B_TYPESHIFT) | 250 (ctrl << B_CONTROLLERSHIFT) | 251 (unit << B_UNITSHIFT) | 252 (part << B_PARTITIONSHIFT); 253 } 254