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, Ralph Campbell, Sony Corp. and Kazumasa 9 * Utashiro of Software Research Associates, Inc. 10 * 11 * %sccs.include.redist.c% 12 * 13 * from: Utah $Hdr: autoconf.c 1.31 91/01/21$ 14 * 15 * @(#)autoconf.c 7.1 (Berkeley) 06/04/92 16 */ 17 18 /* 19 * Setup the system to run on the current machine. 20 * 21 * Configure() is called at boot time. Available 22 * devices are determined (from possibilities mentioned in ioconf.c), 23 * and the drivers are initialized. 24 */ 25 26 #include "hb.h" 27 28 #include "param.h" 29 #include "systm.h" 30 #include "map.h" 31 #include "buf.h" 32 #include "dkstat.h" 33 #include "conf.h" 34 #include "dmap.h" 35 #include "reboot.h" 36 37 #include "machid.h" 38 #include "../include/adrsmap.h" 39 #include "../include/cpu.h" 40 41 #if NHB > 0 42 #include "../hbdev/hbvar.h" 43 #endif 44 45 /* 46 * The following several variables are related to 47 * the configuration process, and are used in initializing 48 * the machine. 49 */ 50 int cold = 1; /* if 1, still working on cold-start */ 51 int dkn; /* number of iostat dk numbers assigned so far */ 52 #ifdef __GNUC__ 53 int cpuspeed = 12; /* approx # instr per usec. */ 54 #else 55 int cpuspeed = 6; /* approx # instr per usec. */ 56 #endif 57 58 struct idrom idrom; 59 60 /* 61 * Determine mass storage and memory configuration for a machine. 62 * Get cpu type, and then switch out to machine specific procedures 63 * which will probe adaptors to see what is out there. 64 */ 65 configure() 66 { 67 register struct scsi_device *dp; 68 register struct driver *drp; 69 70 readidrom((u_char *)&idrom); 71 printf("SONY NET WORK STATION, Model %s, ", idrom.id_model); 72 printf("Machine ID #%d\n", idrom.id_serial); 73 74 /* print what type of CPU and FPU we have */ 75 switch (cpu.cpu.cp_imp) { 76 case MIPS_R2000: 77 printf("cpu0 (MIPS R2000 revision %d.%d)\n", 78 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 79 break; 80 81 case MIPS_R3000: 82 printf("cpu0 (MIPS R3000 revision %d.%d)\n", 83 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 84 break; 85 86 case MIPS_R4000: 87 printf("cpu0 (MIPS R4000 revision %d.%d)\n", 88 cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 89 break; 90 91 default: 92 printf("cpu0 (implementation %d revision %d.%d)\n", 93 cpu.cpu.cp_imp, cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); 94 } 95 96 switch (fpu.cpu.cp_imp) { 97 case MIPS_R2010_FPU: 98 printf("fpu0 (MIPS R2010 revision %d.%d)\n", 99 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 100 break; 101 102 case MIPS_R3010_FPU: 103 printf("fpu0 (MIPS R3010 revision %d.%d)\n", 104 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 105 break; 106 107 case MIPS_R4000_FPU: 108 printf("fpu0 (MIPS R4000 revision %d.%d)\n", 109 fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 110 break; 111 112 default: 113 printf("fpu0 (implementation %d revision %d.%d)\n", 114 fpu.cpu.cp_imp, fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); 115 } 116 117 printf("data cache size %dK inst cache size %dK\n", 118 machDataCacheSize >> 10, machInstCacheSize >> 10); 119 120 init_hb_intr(); 121 122 probeio(); 123 124 #if GENERIC 125 if ((boothowto & RB_ASKNAME) == 0) 126 setroot(); 127 setconf(); 128 #else 129 setroot(); 130 #endif 131 swapconf(); 132 cold = 0; 133 } 134 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() 140 { 141 #if NHB > 0 142 hbfind(); 143 #endif 144 } 145 146 #if NHB > 0 147 int scsidev_setup_time = 10; 148 149 /* 150 * Find devices on a Hyper-bus. 151 * Fills in the tables, with help from a per-driver 152 * slave initialization routine. 153 */ 154 hbfind() 155 { 156 register struct hb_device *hi; 157 register struct hb_ctlr *hm; 158 register int intr, i; 159 register caddr_t reg; 160 register struct hb_hd *hhp; 161 register struct hb_driver *hdp; 162 int scsi_inq_done = 0; 163 int scsi_skip = 0; 164 caddr_t calloc(); 165 166 /* 167 * Initialize the SCSI. 168 */ 169 #if defined(RB_NOINITSCSI) 170 if ((boothowto & RB_NOINITSCSI) == 0) { 171 #else 172 if (1) { 173 #endif 174 printf("Initializing SCSI"); 175 scop_init(0); 176 for (i = 0; i < scsidev_setup_time; i++) { 177 printf("."); 178 #ifndef notdef 179 DELAY( 200000); /* 0.2 sec? */ 180 #else 181 DELAY(1000000); /* 1 sec. */ 182 #endif 183 } 184 printf(" done\n"); 185 } 186 187 hhp = &hb_hd; 188 189 /* 190 * Check each Hyper_bus mass storage controller. 191 * For each one which is potentially on Hyper_bus, 192 * see if it is really there, and if it is record it and 193 * then go looking for slaves. 194 */ 195 for (hm = hminit; hdp = hm->hm_driver; hm++) { 196 intr = (int)hm->hm_intr; 197 reg = hm->hm_addr; 198 if (intr < 17) { 199 if ((scsi_inq_done & (1 << intr)) == 0) { 200 scsi_inq_done |= (1 << intr); 201 if (psdprobe(hm) < 0) { 202 scsi_skip |= (1 << intr); 203 continue; 204 } 205 } else if (scsi_skip & (1 << intr)) { 206 continue; 207 } 208 } 209 i = (*hdp->hd_probe)(hm); 210 if (i == 0) 211 continue; 212 scsi_skip |= (1 << intr); 213 if (intr >= 0 && intr <= 13) { 214 /* 215 * SCSI device !! 216 */ 217 /* hm->hm_driver is re-writed by driver probe routine */ 218 hm->hm_scnum = intr / 7; 219 hm->hm_intr = intr % 7; 220 } 221 else { 222 hm->hm_scnum = -1; 223 } 224 printf("%s%d at hb addr %x intr %d\n", 225 hdp->hd_mname, hm->hm_ctlr, hm->hm_addr, intr); 226 hm->hm_alive = 1; 227 hm->hm_hd = &hb_hd; 228 hdp->hd_minfo[hm->hm_ctlr] = hm; 229 for (hi = hdinit; hi->hi_driver; hi++) { 230 if (hi->hi_driver != hdp || hi->hi_alive || 231 hi->hi_ctlr != hm->hm_ctlr && hi->hi_ctlr != '?') 232 continue; 233 if (intr >= 0 && intr <= 13) { 234 hi->hi_ctlr = hm->hm_ctlr; 235 } 236 if ((*hdp->hd_slave)(hi, reg, intr)) { 237 hi->hi_alive = 1; 238 hi->hi_ctlr = hm->hm_ctlr; 239 hi->hi_hd = &hb_hd; 240 hi->hi_addr = (caddr_t)0; 241 if (hi->hi_dk && dkn < DK_NDRIVE) 242 hi->hi_dk = dkn++; 243 else 244 hi->hi_dk = -1; 245 hi->hi_mi = hm; 246 /* hi_type comes from driver */ 247 hdp->hd_dinfo[hi->hi_unit] = hi; 248 printf("%s%d at %s%d slave %d", 249 hdp->hd_dname, hi->hi_unit, 250 hdp->hd_mname, hm->hm_ctlr, hi->hi_slave); 251 if (hi->hi_intr < 16 && (hi->hi_intr & 7) != 7) 252 printf(" (bus=%d, chan=%d, lun=%d)", 253 hi->hi_intr / 8, 254 hi->hi_intr & 7, 255 hi->hi_slave); 256 printf("\n"); 257 (*hdp->hd_attach)(hi); 258 } 259 } 260 } 261 262 /* 263 * Now look for non-mass storage peripherals. 264 */ 265 for (hi = hdinit; hdp = hi->hi_driver; hi++) { 266 if (hi->hi_alive || hi->hi_slave != -1) 267 continue; 268 intr = (int)hi->hi_intr; 269 i = (*hdp->hd_probe)(hi); 270 if (i == 0) 271 continue; 272 printf("%s%d at hb addr %x intr %d", 273 hi->hi_driver->hd_dname, hi->hi_unit, hi->hi_addr, hi->hi_intr); 274 if (hi->hi_intr < 16 && (hi->hi_intr & 7) != 7) 275 printf(" (bus=%d, chan=%d, lun=%d)", 276 hi->hi_intr / 8, 277 hi->hi_intr & 7, 278 hi->hi_slave); 279 printf("\n"); 280 hi->hi_hd = &hb_hd; 281 hi->hi_alive = 1; 282 283 if(hm->hm_intr >= 0 && hm->hm_intr <= 13) { 284 /* This is SCSI device !! */ 285 hm->hm_scnum = (int)hm->hm_intr / 7; 286 hm->hm_intr = hm->hm_intr % 7; 287 } 288 else { 289 hm->hm_scnum = -1 ; 290 } 291 292 hi->hi_addr = (caddr_t)0; 293 hi->hi_dk = -1; 294 /* hi_type comes from driver */ 295 hdp->hd_dinfo[hi->hi_unit] = hi; 296 (*hdp->hd_attach)(hi); 297 } 298 } 299 #endif /* NHB > 0 */ 300 301 /* 302 * Configure swap space and related parameters. 303 */ 304 swapconf() 305 { 306 register struct swdevt *swp; 307 register int nblks; 308 309 for (swp = swdevt; swp->sw_dev; swp++) 310 if (bdevsw[major(swp->sw_dev)].d_psize) { 311 nblks = 312 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 313 if (nblks != -1 && 314 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 315 swp->sw_nblks = nblks; 316 } 317 dumpconf(); 318 } 319 320 #define DOSWAP /* Change swdevt and dumpdev too */ 321 u_long bootdev; /* should be dev_t, but not until 32 bits */ 322 323 static char devname[][2] = { 324 's', 'd', /* 0 = sd */ 325 'f', 'd', /* 1 = fd */ 326 'f', 'h', /* 2 = fh */ 327 0, 0, /* 3 = not use */ 328 0, 0, /* 4 = not use */ 329 'r', 'd', /* 5 = rd */ 330 0, 0, /* 6 = not use */ 331 0, 0, /* 7 = not use */ 332 0, 0, /* 8 = not use */ 333 0, 0, /* 9 = not use */ 334 'o', 'd', /* 10 = od */ 335 }; 336 337 #define PARTITIONMASK 0x7 338 #define PARTITIONSHIFT 3 339 340 /* 341 * Attempt to find the device from which we were booted. 342 * If we can do so, and not instructed not to do so, 343 * change rootdev to correspond to the load device. 344 */ 345 setroot() 346 { 347 register struct hb_device *ip; 348 int majdev, mindev, unit, part, controller; 349 dev_t temp, orootdev; 350 struct swdevt *swp; 351 352 if (boothowto & RB_DFLTROOT || 353 (bootdev & B_MAGICMASK) != B_DEVMAGIC) 354 return; 355 majdev = B_TYPE(bootdev); 356 if (majdev >= sizeof(devname) / sizeof(devname[0])) 357 return; 358 controller = B_CONTROLLER(bootdev); 359 part = B_PARTITION(bootdev); 360 unit = B_UNIT(bootdev); 361 362 for (ip = hdinit; ip->hi_driver; ip++) { 363 if (ip->hi_alive && ip->hi_slave == unit && 364 ip->hi_ctlr == controller && 365 ip->hi_driver->hd_dname[0] == devname[majdev][0] && 366 ip->hi_driver->hd_dname[1] == devname[majdev][1]) 367 break; 368 } 369 370 if (ip->hi_driver == 0) 371 return; 372 mindev = ip->hi_unit; 373 374 /* 375 * Form a new rootdev 376 */ 377 mindev = (mindev << PARTITIONSHIFT) + part; 378 orootdev = rootdev; 379 rootdev = makedev(majdev, mindev); 380 381 /* 382 * If the original rootdev is the same as the one 383 * just calculated, don't need to adjust the swap configuration. 384 */ 385 if (rootdev == orootdev) 386 return; 387 388 printf("Changing root device to %c%c%d%c\n", 389 devname[majdev][0], devname[majdev][1], 390 mindev >> PARTITIONSHIFT, part + 'a'); 391 392 #ifdef DOSWAP 393 mindev &= ~PARTITIONMASK; 394 for (swp = swdevt; swp->sw_dev; swp++) { 395 if (majdev == major(swp->sw_dev) && 396 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 397 temp = swdevt[0].sw_dev; 398 swdevt[0].sw_dev = swp->sw_dev; 399 swp->sw_dev = temp; 400 break; 401 } 402 } 403 if (swp->sw_dev == 0) 404 return; 405 406 /* 407 * If dumpdev was the same as the old primary swap 408 * device, move it to the new primary swap device. 409 */ 410 if (temp == dumpdev) 411 dumpdev = swdevt[0].sw_dev; 412 #endif 413 } 414 415 readidrom(rom) 416 register u_char *rom; 417 { 418 register u_char *p = (u_char *)IDROM; 419 register int i; 420 421 for (i = 0; i < sizeof (struct idrom); i++, p += 2) 422 *rom++ = ((*p & 0x0f) << 4) + (*(p + 1) & 0x0f); 423 return (0); 424 } 425