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