Home | History | Annotate | Line # | Download | only in vax
      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