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