1 /* $NetBSD: autoconf.c,v 1.101 2023/12/20 15:34:45 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1994 Ludd, University of Lule}, Sweden. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.101 2023/12/20 15:34:45 thorpej Exp $"); 30 31 #include "opt_compat_netbsd.h" 32 #include "opt_cputype.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/bus.h> 37 #include <sys/cpu.h> 38 #include <sys/device.h> 39 #include <sys/disk.h> 40 #include <sys/buf.h> 41 #include <sys/bufq.h> 42 #include <sys/conf.h> 43 44 #include <uvm/uvm_extern.h> 45 46 #include <machine/sid.h> 47 #include <machine/nexus.h> 48 #include <machine/ioa.h> 49 #include <machine/ka820.h> 50 #include <machine/ka750.h> 51 #include <machine/ka650.h> 52 #include <machine/clock.h> 53 #include <machine/rpb.h> 54 #include <machine/mainbus.h> 55 56 #include <vax/vax/gencons.h> 57 58 #include <dev/bi/bireg.h> 59 60 #include "locators.h" 61 #include "ioconf.h" 62 63 void gencnslask(void); 64 65 const struct cpu_dep *dep_call; 66 67 #define MAINBUS 0 68 69 void 70 cpu_configure(void) 71 { 72 73 if (config_rootfound("mainbus", NULL) == NULL) 74 panic("mainbus not configured"); 75 76 /* 77 * We're ready to start up. Clear CPU cold start flag. 78 * Soft cold-start flag will be cleared in configure(). 79 */ 80 if (dep_call->cpu_clrf) 81 (*dep_call->cpu_clrf)(); 82 } 83 84 void 85 cpu_rootconf(void) 86 { 87 /* 88 * The device we booted from are looked for during autoconfig. 89 * If there has been a match, it's already been done. 90 */ 91 92 #ifdef DEBUG 93 printf("booted from type %d unit %d csr 0x%lx adapter %lx slave %d\n", 94 rpb.devtyp, rpb.unit, rpb.csrphy, rpb.adpphy, rpb.slave); 95 #endif 96 printf("boot device: %s\n", 97 booted_device ? device_xname(booted_device) : "<unknown>"); 98 99 rootconf(); 100 } 101 102 static int mainbus_print(void *, const char *); 103 static int mainbus_match(device_t, cfdata_t, void *); 104 static void mainbus_attach(device_t, device_t, void *); 105 106 extern struct vax_bus_space vax_mem_bus_space; 107 extern struct vax_bus_dma_tag vax_bus_dma_tag; 108 109 int 110 mainbus_print(void *aux, const char *name) 111 { 112 struct mainbus_attach_args * const ma = aux; 113 if (name) { 114 aprint_naive("%s at %s", ma->ma_type, name); 115 aprint_normal("%s at %s", ma->ma_type, name); 116 } 117 return UNCONF; 118 } 119 120 int 121 mainbus_match(device_t parent, cfdata_t cf, void *aux) 122 { 123 return 1; /* First (and only) mainbus */ 124 } 125 126 void 127 mainbus_attach(device_t parent, device_t self, void *aux) 128 { 129 struct mainbus_attach_args ma; 130 const char * const * devp; 131 132 aprint_naive("\n"); 133 aprint_normal("\n"); 134 135 for (devp = dep_call->cpu_devs; *devp != NULL; devp++) { 136 ma.ma_type = *devp; 137 ma.ma_iot = &vax_mem_bus_space; 138 ma.ma_dmat = &vax_bus_dma_tag; 139 config_found(self, &ma, mainbus_print, CFARGS_NONE); 140 } 141 142 /* 143 * Hopefully there a master bus? 144 * Maybe should have this as master instead of mainbus. 145 */ 146 147 #if defined(COMPAT_14) 148 if (rpb.rpb_base == (void *)-1) 149 printf("\nWARNING: you must update your boot blocks.\n\n"); 150 #endif 151 152 } 153 154 CFATTACH_DECL_NEW(mainbus, 0, 155 mainbus_match, mainbus_attach, NULL, NULL); 156 157 static int cpu_mainbus_match(device_t, cfdata_t, void *); 158 static void cpu_mainbus_attach(device_t, device_t, void *); 159 160 int 161 cpu_mainbus_match(device_t self, cfdata_t cf, void *aux) 162 { 163 struct mainbus_attach_args *ma = aux; 164 165 return strcmp(cpu_cd.cd_name, ma->ma_type) == 0; 166 } 167 168 void 169 cpu_mainbus_attach(device_t parent, device_t self, void *aux) 170 { 171 struct cpu_info *ci; 172 173 KASSERT(device_private(self) == NULL); 174 ci = curcpu(); 175 device_set_private(self, ci); 176 ci->ci_dev = self; 177 ci->ci_cpuid = device_unit(self); 178 179 if (dep_call->cpu_attach_cpu != NULL) 180 (*dep_call->cpu_attach_cpu)(self); 181 else if (ci->ci_cpustr) { 182 aprint_naive(": %s\n", ci->ci_cpustr); 183 aprint_normal(": %s\n", ci->ci_cpustr); 184 } else { 185 aprint_naive("\n"); 186 aprint_normal("\n"); 187 } 188 } 189 190 CFATTACH_DECL_NEW(cpu_mainbus, 0, 191 cpu_mainbus_match, cpu_mainbus_attach, NULL, NULL); 192 193 #include "sd.h" 194 #include "cd.h" 195 #include "rl.h" 196 #include "ra.h" 197 #include "hp.h" 198 #include "ry.h" 199 200 static int ubtest(void *); 201 static int jmfr(const char *, device_t, int); 202 static int booted_qe(device_t, void *); 203 static int booted_qt(device_t, void *); 204 static int booted_le(device_t, void *); 205 static int booted_ze(device_t, void *); 206 static int booted_de(device_t, void *); 207 static int booted_ni(device_t, void *); 208 #if NSD > 0 || NCD > 0 209 static int booted_sd(device_t, void *); 210 #endif 211 #if NRL > 0 212 static int booted_rl(device_t, void *); 213 #endif 214 #if NRA > 0 || NRACD > 0 215 static int booted_ra(device_t, void *); 216 #endif 217 #if NHP 218 static int booted_hp(device_t, void *); 219 #endif 220 #if NRD 221 static int booted_rd(device_t, void *); 222 #endif 223 224 int (* const devreg[])(device_t, void *) = { 225 booted_qe, 226 booted_qt, 227 booted_le, 228 booted_ze, 229 booted_de, 230 booted_ni, 231 #if NSD > 0 || NCD > 0 232 booted_sd, 233 #endif 234 #if NRL > 0 235 booted_rl, 236 #endif 237 #if NRA 238 booted_ra, 239 #endif 240 #if NHP 241 booted_hp, 242 #endif 243 #if NRD 244 booted_rd, 245 #endif 246 0, 247 }; 248 249 #define ubreg(x) ((x) & 017777) 250 251 void 252 device_register(device_t dev, void *aux) 253 { 254 int (* const * dp)(device_t, void *) = devreg; 255 256 /* If there's a synthetic RPB, we can't trust it */ 257 if (rpb.rpb_base == (void *)-1) 258 return; 259 260 while (*dp) { 261 if ((**dp)(dev, aux)) { 262 booted_device = dev; 263 break; 264 } 265 dp++; 266 } 267 } 268 269 /* 270 * Simple checks. Return 1 on fail. 271 */ 272 int 273 jmfr(const char *n, device_t dev, int nr) 274 { 275 if (rpb.devtyp != nr) 276 return 1; 277 return !device_is_a(dev, n); 278 } 279 280 #include <dev/qbus/ubavar.h> 281 int 282 ubtest(void *aux) 283 { 284 paddr_t p; 285 286 p = kvtophys(((struct uba_attach_args *)aux)->ua_ioh); 287 if (rpb.csrphy != p) 288 return 1; 289 return 0; 290 } 291 292 #if 1 /* NNI */ 293 #include <dev/bi/bivar.h> 294 int 295 booted_ni(device_t dev, void *aux) 296 { 297 struct bi_attach_args *ba = aux; 298 299 if (jmfr("ni", dev, BDEV_NI) || (kvtophys(ba->ba_ioh) != rpb.csrphy)) 300 return 0; 301 302 return 1; 303 } 304 #endif /* NNI */ 305 306 #if 1 /* NDE */ 307 int 308 booted_de(device_t dev, void *aux) 309 { 310 311 if (jmfr("de", dev, BDEV_DE) || ubtest(aux)) 312 return 0; 313 314 return 1; 315 } 316 #endif /* NDE */ 317 318 int 319 booted_le(device_t dev, void *aux) 320 { 321 if (jmfr("le", dev, BDEV_LE)) 322 return 0; 323 return 1; 324 } 325 326 int 327 booted_ze(device_t dev, void *aux) 328 { 329 if (jmfr("ze", dev, BDEV_ZE)) 330 return 0; 331 return 1; 332 } 333 334 int 335 booted_qt(device_t dev, void *aux) 336 { 337 if (jmfr("qt", dev, BDEV_QE) || ubtest(aux)) 338 return 0; 339 340 return 1; 341 } 342 343 #if 1 /* NQE */ 344 int 345 booted_qe(device_t dev, void *aux) 346 { 347 if (jmfr("qe", dev, BDEV_QE) || ubtest(aux)) 348 return 0; 349 350 return 1; 351 } 352 #endif /* NQE */ 353 354 #if NSD > 0 || NCD > 0 355 #include <dev/scsipi/scsipi_all.h> 356 #include <dev/scsipi/scsipiconf.h> 357 int 358 booted_sd(device_t dev, void *aux) 359 { 360 struct scsipibus_attach_args *sa = aux; 361 device_t ppdev; 362 363 /* Is this a SCSI device? */ 364 if (jmfr("sd", dev, BDEV_SD) && jmfr("sd", dev, BDEV_SDN) && 365 jmfr("cd", dev, BDEV_SD) && jmfr("cd", dev, BDEV_SDN)) 366 return 0; 367 368 if (sa->sa_periph->periph_channel->chan_bustype->bustype_type != 369 SCSIPI_BUSTYPE_SCSI) 370 return 0; /* ``Cannot happen'' */ 371 372 if (sa->sa_periph->periph_target != (rpb.unit/100) || 373 sa->sa_periph->periph_lun != (rpb.unit % 100)) 374 return 0; /* Wrong unit */ 375 376 ppdev = device_parent(device_parent(dev)); 377 378 /* VS3100 NCR 53C80 (si) & VS4000 NCR 53C94 (asc) */ 379 if ((jmfr("si", ppdev, BDEV_SD) == 0 || /* new name */ 380 jmfr("asc", ppdev, BDEV_SD) == 0 || 381 jmfr("asc", ppdev, BDEV_SDN) == 0) && 382 (device_cfdata(ppdev)->cf_loc[VSBUSCF_CSR] == rpb.csrphy)) 383 return 1; 384 385 return 0; /* Where did we come from??? */ 386 } 387 #endif 388 #if NRL > 0 389 #include <dev/qbus/rlvar.h> 390 int 391 booted_rl(device_t dev, void *aux) 392 { 393 struct rlc_attach_args *raa = aux; 394 static int ub; 395 396 if (jmfr("rlc", dev, BDEV_RL) == 0) 397 ub = ubtest(aux); 398 if (ub) 399 return 0; 400 if (jmfr("rl", dev, BDEV_RL)) 401 return 0; 402 if (raa->hwid != rpb.unit) 403 return 0; /* Wrong unit number */ 404 return 1; 405 } 406 #endif 407 408 #if NRA > 0 || NRACD > 0 409 #include <dev/mscp/mscp.h> 410 #include <dev/mscp/mscpreg.h> 411 #include <dev/mscp/mscpvar.h> 412 int 413 booted_ra(device_t dev, void *aux) 414 { 415 struct drive_attach_args *da = aux; 416 struct mscp_softc *pdev = device_private(device_parent(dev)); 417 paddr_t ioaddr; 418 419 if (jmfr("ra", dev, BDEV_UDA) && jmfr("racd", dev, BDEV_UDA)) 420 return 0; 421 422 if (da->da_mp->mscp_unit != rpb.unit) 423 return 0; /* Wrong unit number */ 424 425 ioaddr = kvtophys(pdev->mi_iph); /* Get phys addr of CSR */ 426 if (rpb.devtyp == BDEV_UDA && rpb.csrphy == ioaddr) 427 return 1; /* Did match CSR */ 428 429 return 0; 430 } 431 #endif 432 433 #if NHP 434 #include <vax/mba/mbavar.h> 435 int 436 booted_hp(device_t dev, void *aux) 437 { 438 static int mbaaddr; 439 440 /* Save last adapter address */ 441 if (jmfr("mba", dev, BDEV_HP) == 0) { 442 struct sbi_attach_args *sa = aux; 443 444 mbaaddr = kvtophys(sa->sa_ioh); 445 return 0; 446 } 447 448 if (jmfr("hp", dev, BDEV_HP)) 449 return 0; 450 451 if (((struct mba_attach_args *)aux)->ma_unit != rpb.unit) 452 return 0; 453 454 if (mbaaddr != rpb.adpphy) 455 return 0; 456 457 return 1; 458 } 459 #endif 460 #if NRD 461 int 462 booted_rd(device_t dev, void *aux) 463 { 464 int *nr = aux; /* XXX - use the correct attach struct */ 465 466 if (jmfr("rd", dev, BDEV_RD)) 467 return 0; 468 469 if (*nr != rpb.unit) 470 return 0; 471 472 return 1; 473 } 474 #endif 475