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 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 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 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 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 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 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 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 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