xref: /netbsd-src/sys/arch/atari/atari/autoconf.c (revision 2a84159ada57dac1a3a322c289d36b976db1a473)
1 /*	$NetBSD: autoconf.c,v 1.74 2023/01/06 10:28:27 tsutsui Exp $	*/
2 
3 /*
4  * Copyright (c) 1995 Leo Weppelman
5  * Copyright (c) 1994 Christian E. Hopps
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  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Christian E. Hopps.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.74 2023/01/06 10:28:27 tsutsui Exp $");
35 
36 #include "opt_md.h"
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/reboot.h>
41 #include <sys/conf.h>
42 #include <sys/buf.h>
43 #include <sys/device.h>
44 #include <sys/device_impl.h>	/* XXX autoconf abuse */
45 #include <sys/disklabel.h>
46 #include <sys/disk.h>
47 #include <sys/kmem.h>
48 #include <machine/disklabel.h>
49 #include <machine/cpu.h>
50 #include <atari/atari/device.h>
51 
52 #if defined(MEMORY_DISK_HOOKS)
53 #include <dev/md.h>
54 #endif
55 
56 #include "ioconf.h"
57 
58 static void findroot(void);
59 static int mbmatch(device_t, cfdata_t, void *);
60 static void mbattach(device_t, device_t, void *);
61 #if 0
62 static int mbprint(void *, const char *);
63 #endif
64 
65 int atari_realconfig;
66 #include <sys/kernel.h>
67 
68 /*
69  * called at boot time, configure all devices on system
70  */
71 void
cpu_configure(void)72 cpu_configure(void)
73 {
74 
75 	atari_realconfig = 1;
76 
77 	(void)splhigh();
78 
79 	init_sicallback();
80 
81 	if (config_rootfound("mainbus", __UNCONST("mainbus")) == NULL)
82 		panic("no mainbus found");
83 
84 	(void)spl0();
85 }
86 
87 void
cpu_rootconf(void)88 cpu_rootconf(void)
89 {
90 
91 	findroot();
92 #if defined(MEMORY_DISK_HOOKS)
93 	/*
94 	 * XXX
95 	 * quick hacks for atari's traditional "auto-load from floppy on open"
96 	 * installation md(4) ramdisk.
97 	 * See sys/arch/atari/dev/md_root.c for details.
98 	 */
99 #define RAMD_NDEV	3	/* XXX */
100 
101 	if ((boothowto & RB_ASKNAME) != 0) {
102 		int md_major, i;
103 		cfdata_t cf;
104 		struct md_softc *sc;
105 
106 		md_major = devsw_name2blk("md", NULL, 0);
107 		if (md_major >= 0) {
108 			for (i = 0; i < RAMD_NDEV; i++) {
109 				cf = kmem_zalloc(sizeof(*cf), KM_SLEEP);
110 				if (cf == NULL)
111 					break;	/* XXX */
112 				cf->cf_name = md_cd.cd_name;
113 				cf->cf_atname = md_cd.cd_name;
114 				cf->cf_unit = i;
115 				cf->cf_fstate = FSTATE_STAR;
116 				/* XXX mutex */
117 				sc = device_private(config_attach_pseudo(cf));
118 				if (sc == NULL)
119 					break;	/* XXX */
120 			}
121 		}
122 	}
123 #endif
124 	rootconf();
125 }
126 
127 /*ARGSUSED*/
128 int
simple_devprint(void * aux,const char * pnp)129 simple_devprint(void *aux, const char *pnp)
130 {
131 
132 	return QUIET;
133 }
134 
135 /*
136  * use config_search_ia to find appropriate device, then call that device
137  * directly with NULL device variable storage.  A device can then
138  * always tell the difference between the real and console init
139  * by checking for NULL.
140  */
141 int
atari_config_found(cfdata_t pcfp,device_t parent,void * aux,cfprint_t pfn,const struct cfargs * cfargs)142 atari_config_found(cfdata_t pcfp, device_t parent, void *aux, cfprint_t pfn,
143     const struct cfargs *cfargs)
144 {
145 	struct device temp;
146 	cfdata_t cf;
147 	const struct cfattach *ca;
148 	int rv = 0;
149 
150 	if (atari_realconfig) {
151 		rv = config_found(parent, aux, pfn, cfargs) != NULL;
152 		goto out;
153 	}
154 
155 	memset(&temp, 0, sizeof(temp));
156 	if (parent == NULL)
157 		parent = &temp;
158 
159 	parent->dv_cfdata = pcfp;
160 	parent->dv_cfdriver = config_cfdriver_lookup(pcfp->cf_name);
161 	parent->dv_unit = pcfp->cf_unit;
162 
163 	if ((cf = config_search(parent, aux, cfargs)) != NULL) {
164 		ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
165 		if (ca != NULL) {
166 			(*ca->ca_attach)(parent, NULL, aux);
167 			rv = 1;
168 			goto out;
169 		}
170 	}
171 	parent->dv_cfdata = NULL;
172  out:
173 	return rv;
174 }
175 
176 /*
177  * this function needs to get enough configured to do a console
178  * basically this means start attaching the grfxx's that support
179  * the console. Kinda hacky but it works.
180  */
181 void
config_console(void)182 config_console(void)
183 {
184 	cfdata_t cf;
185 
186 	config_init();
187 
188 	/*
189 	 * we need mainbus' cfdata.
190 	 */
191 	cf = config_rootsearch(NULL, "mainbus", __UNCONST("mainbus"));
192 	if (cf == NULL)
193 		panic("no mainbus");
194 
195 	/*
196 	 * Note: The order of the 'atari_config_found()' calls is
197 	 * important! On the Hades, the 'pci-side' of the config does
198 	 * some setup for the 'grf-side'. This make it possible to use
199 	 * a PCI card for both wscons and grfabs.
200 	 */
201 	atari_config_found(cf, NULL, __UNCONST("pcib")  , NULL, CFARGS_NONE);
202 	atari_config_found(cf, NULL, __UNCONST("isab")  , NULL, CFARGS_NONE);
203 	atari_config_found(cf, NULL, __UNCONST("grfbus"), NULL, CFARGS_NONE);
204 }
205 
206 /*
207  * The system will assign the "booted device" indicator (and thus
208  * rootdev if rootspec is wildcarded) to the first partition 'a'
209  * in preference of boot.
210  */
211 #include <sys/fcntl.h>		/* XXXX and all that uses it */
212 #include <sys/proc.h>		/* XXXX and all that uses it */
213 
214 #include "fd.h"
215 #include "sd.h"
216 #include "cd.h"
217 #include "wd.h"
218 #include "ioconf.h"
219 
220 struct cfdriver *genericconf[] = {
221 #if NWD > 0
222 	&wd_cd,
223 #endif
224 #if NSD > 0
225 	&sd_cd,
226 #endif
227 #if NCD > 0
228 	&cd_cd,
229 #endif
230 #if NFD > 0
231 	&fd_cd,
232 #endif
233 	NULL,
234 };
235 
236 void
findroot(void)237 findroot(void)
238 {
239 	struct disk *dkp;
240 	struct partition *pp;
241 	device_t *devs;
242 	const struct bdevsw *bdev;
243 	int i, maj, unit;
244 
245 	if (boothowto & RB_ASKNAME)
246 		return;		/* Don't bother looking */
247 
248 	for (i = 0; genericconf[i] != NULL; i++) {
249 		for (unit = 0; unit < genericconf[i]->cd_ndevs; unit++) {
250 			if (genericconf[i]->cd_devs[unit] == NULL)
251 				continue;
252 
253 			/*
254 			 * Find the disk structure corresponding to the
255 			 * current device.
256 			 */
257 			devs = genericconf[i]->cd_devs;
258 			if ((dkp = disk_find(device_xname(devs[unit]))) == NULL)
259 				continue;
260 
261 			if (dkp->dk_driver == NULL ||
262 			    dkp->dk_driver->d_strategy == NULL)
263 				continue;
264 
265 			maj = devsw_name2blk(genericconf[i]->cd_name, NULL, 0);
266 			if (maj == -1)
267 				continue;
268 			bdev = bdevsw_lookup(makedev(maj, 0));
269 #ifdef DIAGNOSTIC
270 			if (bdev == NULL)
271 				panic("findroot: impossible");
272 #endif
273 			if (bdev == NULL ||
274 			    bdev->d_strategy != dkp->dk_driver->d_strategy)
275 				continue;
276 
277 			/* Open disk; forces read of disklabel. */
278 			if ((*bdev->d_open)(MAKEDISKDEV(maj,
279 			    unit, 0), FREAD|FNONBLOCK, 0, &lwp0))
280 				continue;
281 			(void)(*bdev->d_close)(MAKEDISKDEV(maj,
282 			    unit, 0), FREAD|FNONBLOCK, 0, &lwp0);
283 
284 			pp = &dkp->dk_label->d_partitions[booted_partition];
285 			if (pp->p_size != 0 && pp->p_fstype == FS_BSDFFS) {
286 				booted_device = devs[unit];
287 				return;
288 			}
289 		}
290 	}
291 }
292 
293 /*
294  * mainbus driver
295  */
296 CFATTACH_DECL_NEW(mainbus, 0,
297     mbmatch, mbattach, NULL, NULL);
298 
299 static int mb_attached;
300 
301 static int
mbmatch(device_t parent,cfdata_t cf,void * aux)302 mbmatch(device_t parent, cfdata_t cf, void *aux)
303 {
304 
305 	if (mb_attached)
306 		return 0;
307 	/*
308 	 * We are always here
309 	 */
310 	return 1;
311 }
312 
313 /*
314  * "find" all the things that should be there.
315  */
316 static void
mbattach(device_t parent,device_t self,void * aux)317 mbattach(device_t parent, device_t self, void *aux)
318 {
319 
320 	mb_attached = 1;
321 
322 	aprint_normal("\n");
323 	config_found(self, __UNCONST("clock")   , simple_devprint, CFARGS_NONE);
324 	config_found(self, __UNCONST("grfbus")  , simple_devprint, CFARGS_NONE);
325 	config_found(self, __UNCONST("kbd")     , simple_devprint, CFARGS_NONE);
326 	config_found(self, __UNCONST("fdc")     , simple_devprint, CFARGS_NONE);
327 	config_found(self, __UNCONST("ser")     , simple_devprint, CFARGS_NONE);
328 	config_found(self, __UNCONST("zs")      , simple_devprint, CFARGS_NONE);
329 	config_found(self, __UNCONST("ncrscsi") , simple_devprint, CFARGS_NONE);
330 	config_found(self, __UNCONST("nvr")     , simple_devprint, CFARGS_NONE);
331 	config_found(self, __UNCONST("lpt")     , simple_devprint, CFARGS_NONE);
332 	config_found(self, __UNCONST("wdc")     , simple_devprint, CFARGS_NONE);
333 	config_found(self, __UNCONST("ne")      , simple_devprint, CFARGS_NONE);
334 	config_found(self, __UNCONST("isab")    , simple_devprint, CFARGS_NONE);
335 	config_found(self, __UNCONST("pcib")    , simple_devprint, CFARGS_NONE);
336 	config_found(self, __UNCONST("avmebus") , simple_devprint, CFARGS_NONE);
337 }
338 
339 #if 0
340 static int
341 mbprint(void *aux, const char *pnp)
342 {
343 
344 	if (pnp)
345 		aprint_normal("%s at %s", (char *)aux, pnp);
346 	return UNCONF;
347 }
348 #endif
349