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