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