xref: /netbsd-src/sys/arch/vax/vax/autoconf.c (revision e5fbc36ada28f9b9a5836ecffaf4a06aa1ebb687)
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
cpu_configure(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
cpu_rootconf(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
mainbus_print(void * aux,const char * name)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
mainbus_match(device_t parent,cfdata_t cf,void * aux)121 mainbus_match(device_t parent, cfdata_t cf, void *aux)
122 {
123 	return 1; /* First (and only) mainbus */
124 }
125 
126 void
mainbus_attach(device_t parent,device_t self,void * aux)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
cpu_mainbus_match(device_t self,cfdata_t cf,void * aux)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
cpu_mainbus_attach(device_t parent,device_t self,void * aux)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
device_register(device_t dev,void * aux)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
jmfr(const char * n,device_t dev,int nr)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
ubtest(void * aux)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
booted_ni(device_t dev,void * aux)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
booted_de(device_t dev,void * aux)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
booted_le(device_t dev,void * aux)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
booted_ze(device_t dev,void * aux)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
booted_qt(device_t dev,void * aux)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
booted_qe(device_t dev,void * aux)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
booted_sd(device_t dev,void * aux)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
booted_rl(device_t dev,void * aux)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
booted_ra(device_t dev,void * aux)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
booted_hp(device_t dev,void * aux)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
booted_rd(device_t dev,void * aux)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