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