autoconf.c revision 1.36
1/* $NetBSD: autoconf.c,v 1.36 1996/05/09 20:30:33 is Exp $ */ 2 3/* 4 * Copyright (c) 1994 Christian E. Hopps 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 * 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#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/reboot.h> 35#include <sys/conf.h> 36#include <sys/device.h> 37#include <sys/disklabel.h> 38#include <machine/cpu.h> 39#include <amiga/amiga/cfdev.h> 40#include <amiga/amiga/device.h> 41#include <amiga/amiga/custom.h> 42 43void setroot __P((void)); 44void swapconf __P((void)); 45void mbattach __P((struct device *, struct device *, void *)); 46int mbprint __P((void *, char *)); 47int mbmatch __P((struct device *, void *, void *)); 48 49int cold; /* 1 if still booting */ 50#include <sys/kernel.h> 51/* 52 * called at boot time, configure all devices on system 53 */ 54void 55configure() 56{ 57 /* 58 * this is the real thing baby (i.e. not console init) 59 */ 60 amiga_realconfig = 1; 61#ifdef DRACO 62 if (is_draco()) { 63 *draco_intena &= ~DRIRQ_GLOBAL; 64 } else 65#endif 66 custom.intena = INTF_INTEN; 67 68 if (config_rootfound("mainbus", "mainbus") == NULL) 69 panic("no mainbus found"); 70 71 printf("survived autoconf, going to enable interrupts\n"); 72 73#ifdef DRACO 74 if (is_draco()) { 75 *draco_intena |= DRIRQ_GLOBAL; 76 /* softints always enabled */ 77 } else 78#endif 79 { 80 custom.intena = INTF_SETCLR | INTF_INTEN; 81 82 /* also enable hardware aided software interrupts */ 83 custom.intena = INTF_SETCLR | INTF_SOFTINT; 84 } 85 printf("survived interrupt enable\n"); 86 87#ifdef GENERIC 88 if ((boothowto & RB_ASKNAME) == 0) { 89 setroot(); 90 printf("survived setroot()\n"); 91 } 92 setconf(); 93 printf("survived setconf()\n"); 94#else 95 setroot(); 96 printf("survived setroot()\n"); 97#endif 98 printf("survived root device search\n"); 99 swapconf(); 100 printf("survived swap device search\n"); 101 cold = 0; 102} 103 104/*ARGSUSED*/ 105int 106simple_devprint(auxp, pnp) 107 void *auxp; 108 char *pnp; 109{ 110 return(QUIET); 111} 112 113int 114matchname(fp, sp) 115 char *fp, *sp; 116{ 117 int len; 118 119 len = strlen(fp); 120 if (strlen(sp) != len) 121 return(0); 122 if (bcmp(fp, sp, len) == 0) 123 return(1); 124 return(0); 125} 126 127/* 128 * use config_search to find appropriate device, then call that device 129 * directly with NULL device variable storage. A device can then 130 * always tell the difference betwean the real and console init 131 * by checking for NULL. 132 */ 133int 134amiga_config_found(pcfp, pdp, auxp, pfn) 135 struct cfdata *pcfp; 136 struct device *pdp; 137 void *auxp; 138 cfprint_t pfn; 139{ 140 struct device temp; 141 struct cfdata *cf; 142 143 if (amiga_realconfig) 144 return(config_found(pdp, auxp, pfn) != NULL); 145 146 if (pdp == NULL) 147 pdp = &temp; 148 149 pdp->dv_cfdata = pcfp; 150 if ((cf = config_search((cfmatch_t)NULL, pdp, auxp)) != NULL) { 151 cf->cf_attach->ca_attach(pdp, NULL, auxp); 152 pdp->dv_cfdata = NULL; 153 return(1); 154 } 155 pdp->dv_cfdata = NULL; 156 return(0); 157} 158 159/* 160 * this function needs to get enough configured to do a console 161 * basically this means start attaching the grfxx's that support 162 * the console. Kinda hacky but it works. 163 */ 164void 165config_console() 166{ 167 struct cfdata *cf; 168 169 int i; 170 171 /* 172 * we need mainbus' cfdata. 173 */ 174 cf = config_rootsearch(NULL, "mainbus", "mainbus"); 175 if (cf == NULL) { 176 panic("no mainbus"); 177 } 178 /* 179 * internal grf. 180 */ 181#ifdef DRACO 182 if (!(is_draco())) 183#endif 184 amiga_config_found(cf, NULL, "grfcc", NULL); 185 /* 186 * zbus knows when its not for real and will 187 * only configure the appropriate hardware 188 */ 189 amiga_config_found(cf, NULL, "zbus", NULL); 190} 191 192/* 193 * mainbus driver 194 */ 195struct cfattach mainbus_ca = { 196 sizeof(struct device), mbmatch, mbattach 197}; 198 199struct cfdriver mainbus_cd = { 200 NULL, "mainbus", DV_DULL, NULL, 0 201}; 202 203int 204mbmatch(pdp, match, auxp) 205 struct device *pdp; 206 void *match, *auxp; 207{ 208 struct cfdata *cfp = match; 209 210 if (cfp->cf_unit > 0) 211 return(0); 212 /* 213 * We are always here 214 */ 215 return(1); 216} 217 218/* 219 * "find" all the things that should be there. 220 */ 221void 222mbattach(pdp, dp, auxp) 223 struct device *pdp, *dp; 224 void *auxp; 225{ 226 printf ("\n"); 227 config_found(dp, "clock", simple_devprint); 228#ifdef DRACO 229 if (is_draco()) { 230 config_found(dp, "kbd", simple_devprint); 231 config_found(dp, "drsc", simple_devprint); 232 /* 233 * XXX -- missing here: 234 * SuperIO chip serial, parallel, floppy 235 * or maybe just make that into a pseudo 236 * ISA bus. 237 */ 238 } else 239#endif 240 { 241 config_found(dp, "ser", simple_devprint); 242 config_found(dp, "par", simple_devprint); 243 config_found(dp, "kbd", simple_devprint); 244 config_found(dp, "ms", simple_devprint); 245 config_found(dp, "ms", simple_devprint); 246 config_found(dp, "grfcc", simple_devprint); 247 config_found(dp, "fdc", simple_devprint); 248 } 249 if (is_a4000() || is_a1200()) 250 config_found(dp, "idesc", simple_devprint); 251 if (is_a4000()) /* Try to configure A4000T SCSI */ 252 config_found(dp, "afsc", simple_devprint); 253 config_found(dp, "zbus", simple_devprint); 254 if (is_a3000()) 255 config_found(dp, "ahsc", simple_devprint); 256} 257 258int 259mbprint(auxp, pnp) 260 void *auxp; 261 char *pnp; 262{ 263 if (pnp) 264 printf("%s at %s", (char *)auxp, pnp); 265 return(UNCONF); 266} 267 268void 269swapconf() 270{ 271 struct swdevt *swp; 272 u_int maj; 273 int nb; 274 275 for (swp = swdevt; swp->sw_dev > 0; swp++) { 276 maj = major(swp->sw_dev); 277 278 if (maj > nblkdev) 279 break; 280 281 if (bdevsw[maj].d_psize) { 282 nb = bdevsw[maj].d_psize(swp->sw_dev); 283 if (nb > 0 && 284 (swp->sw_nblks == 0 || swp->sw_nblks > nb)) 285 swp->sw_nblks = nb; 286 else 287 swp->sw_nblks = 0; 288 } 289 swp->sw_nblks = ctod(dtoc(swp->sw_nblks)); 290 } 291 if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize) 292 /*dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem;*/ 293 dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - 294 ctob(physmem)/DEV_BSIZE; 295 if (dumplo < 0) 296 dumplo = 0; 297 298} 299 300#define DOSWAP /* change swdevt and dumpdev */ 301u_long bootdev = 0; /* should be dev_t, but not until 32 bits */ 302 303static char devname[][2] = { 304 { 0 ,0 }, 305 { 0 ,0 }, 306 { 'f' ,'d' }, /* 2 = fd */ 307 { 0 ,0 }, 308 { 's' ,'d' } /* 4 = sd -- new SCSI system */ 309}; 310 311void 312setroot() 313{ 314 int majdev, mindev, unit, part, adaptor; 315 dev_t temp = 0; 316 dev_t orootdev; 317 struct swdevt *swp; 318 319 if (boothowto & RB_DFLTROOT || 320 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 321 return; 322 majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 323 if (majdev > sizeof(devname) / sizeof(devname[0])) 324 return; 325 adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 326 part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 327 unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 328 orootdev = rootdev; 329 rootdev = MAKEDISKDEV(majdev, unit, part); 330 /* 331 * If the original rootdev is the same as the one 332 * just calculated, don't need to adjust the swap configuration. 333 */ 334 if (rootdev == orootdev) 335 return; 336 printf("changing root device to %c%c%d%c\n", 337 devname[majdev][0], devname[majdev][1], 338 unit, part + 'a'); 339#ifdef DOSWAP 340 mindev = DISKUNIT(rootdev); 341 for (swp = swdevt; swp->sw_dev; swp++) { 342 if (majdev == major(swp->sw_dev) && 343 mindev == DISKUNIT(swp->sw_dev)) { 344 temp = swdevt[0].sw_dev; 345 swdevt[0].sw_dev = swp->sw_dev; 346 swp->sw_dev = temp; 347 break; 348 } 349 } 350 if (swp->sw_dev == 0) 351 return; 352 /* 353 * If dumpdev was the same as the old primary swap 354 * device, move it to the new primary swap device. 355 */ 356 if (temp == dumpdev) 357 dumpdev = swdevt[0].sw_dev; 358#endif 359} 360 361 362/* 363 * Try to determine, of this machine is an A3000, which has a builtin 364 * realtime clock and scsi controller, so that this hardware is only 365 * included as "configured" if this IS an A3000 366 */ 367 368int a3000_flag = 1; /* patchable */ 369#ifdef A4000 370int a4000_flag = 1; /* patchable - default to A4000 */ 371#else 372int a4000_flag = 0; /* patchable */ 373#endif 374 375int 376is_a3000() 377{ 378 /* this is a dirty kludge.. but how do you do this RIGHT ? :-) */ 379 extern long boot_fphystart; 380 short sc; 381 382 if ((machineid >> 16) == 3000) 383 return (1); /* It's an A3000 */ 384 if (machineid >> 16) 385 return (0); /* It's not an A3000 */ 386 /* Machine type is unknown, so try to guess it */ 387 /* where is fastram on the A4000 ?? */ 388 /* if fastram is below 0x07000000, assume it's not an A3000 */ 389 if (boot_fphystart < 0x07000000) 390 return(0); 391 /* 392 * OK, fastram starts at or above 0x07000000, check specific 393 * machines 394 */ 395 for (sc = 0; sc < ncfdev; sc++) { 396 switch (cfdev[sc].rom.manid) { 397 case 2026: /* Progressive Peripherals, Inc */ 398 switch (cfdev[sc].rom.prodid) { 399 case 0: /* PPI Mercury - A3000 */ 400 case 1: /* PP&S A3000 '040 */ 401 return(1); 402 case 150: /* PPI Zeus - it's an A2000 */ 403 case 105: /* PP&S A2000 '040 */ 404 case 187: /* PP&S A500 '040 */ 405 return(0); 406 } 407 break; 408 409 case 2112: /* IVS */ 410 switch (cfdev[sc].rom.prodid) { 411 case 242: 412 return(0); /* A2000 accelerator? */ 413 } 414 break; 415 } 416 } 417 return (a3000_flag); /* XXX let flag tell now */ 418} 419 420int 421is_a4000() 422{ 423 if ((machineid >> 16) == 4000) 424 return (1); /* It's an A4000 */ 425 if ((machineid >> 16) == 1200) 426 return (0); /* It's an A1200, so not A4000 */ 427#ifdef DRACO 428 if (is_draco()) 429 return (0); 430#endif 431 /* Do I need this any more? */ 432 if ((custom.deniseid & 0xff) == 0xf8) 433 return (1); 434#ifdef DEBUG 435 if (a4000_flag) 436 printf ("Denise ID = %04x\n", (unsigned short)custom.deniseid); 437#endif 438 if (machineid >> 16) 439 return (0); /* It's not an A4000 */ 440 return (a4000_flag); /* Machine type not set */ 441} 442 443int 444is_a1200() 445{ 446 if ((machineid >> 16) == 1200) 447 return (1); /* It's an A1200 */ 448 return (0); /* Machine type not set */ 449} 450 451#ifdef DRACO 452int 453is_draco() 454{ 455 if ((machineid >> 24) == 0x7D) 456 return ((machineid >> 16) & 0xFF); 457 return (0); 458} 459#endif 460