autoconf.c revision 1.20
1/* 2 * Copyright (c) 1994 Christian E. Hopps 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Christian E. Hopps. 16 * 4. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $Id: autoconf.c,v 1.20 1994/05/29 01:44:26 chopps Exp $ 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#include <amiga/dev/ztwobusvar.h> 43 44void configure __P((void)); 45void setroot __P((void)); 46void swapconf __P((void)); 47void mbattach __P((struct device *, struct device *, void *)); 48int mbprint __P((void *, char *)); 49int mbmatch __P((struct device *, struct cfdata *, void *)); 50 51int cold; /* 1 if still booting */ 52#include <sys/kernel.h> 53/* 54 * called at boot time, configure all devices on system 55 */ 56void 57configure() 58{ 59 /* 60 * this is the real thing baby (i.e. not console init) 61 */ 62 amiga_realconfig = 1; 63 custom.intena = INTF_INTEN; 64 65 if (config_rootfound("mainbus", "mainbus") == 0) 66 panic("no mainbus found"); 67 68 custom.intena = INTF_SETCLR | INTF_INTEN; 69#ifdef GENERIC 70 if ((boothowto & RB_ASKNAME) == 0) 71 setroot(); 72 setconf(); 73#else 74 setroot(); 75#endif 76 swapconf(); 77 cold = 0; 78} 79 80/*ARGSUSED*/ 81int 82simple_devprint(auxp, pnp) 83 void *auxp; 84 char *pnp; 85{ 86 return(QUIET); 87} 88 89int 90matchname(fp, sp) 91 char *fp, *sp; 92{ 93 int len; 94 95 len = strlen(fp); 96 if (strlen(sp) != len) 97 return(0); 98 if (bcmp(fp, sp, len) == 0) 99 return(1); 100 return(0); 101} 102 103/* 104 * use config_search to find appropriate device, then call that device 105 * directly with NULL device variable storage. A device can then 106 * always tell the difference betwean the real and console init 107 * by checking for NULL. 108 */ 109int 110amiga_config_found(pcfp, pdp, auxp, pfn) 111 struct cfdata *pcfp; 112 struct device *pdp; 113 void *auxp; 114 cfprint_t pfn; 115{ 116 struct device temp; 117 struct cfdata *cf; 118 119 if (amiga_realconfig) 120 return(config_found(pdp, auxp, pfn)); 121 122 if (pdp == NULL) 123 pdp = &temp; 124 125 pdp->dv_cfdata = pcfp; 126 if ((cf = config_search((cfmatch_t)NULL, pdp, auxp)) != NULL) { 127 cf->cf_driver->cd_attach(pdp, NULL, auxp); 128 pdp->dv_cfdata = NULL; 129 return(1); 130 } 131 pdp->dv_cfdata = NULL; 132 return(0); 133} 134 135/* 136 * this function needs to get enough configured to do a console 137 * basically this means start attaching the grfxx's that support 138 * the console. Kinda hacky but it works. 139 */ 140int 141config_console() 142{ 143 extern struct cfdriver mainbuscd, ztwobuscd; 144 struct cfdata *cf; 145 146 /* 147 * we need mainbus' cfdata. 148 */ 149 cf = config_rootsearch(NULL, "mainbus", "mainbus"); 150 if (cf == NULL) 151 panic("no mainbus"); 152 /* 153 * internal grf. 154 */ 155 amiga_config_found(cf, NULL, "grfcc", NULL); 156#if not_yet 157 /* 158 * ztwobus knows when its not for real (amiga_realconfig == 0) 159 */ 160 amiga_config_found(cf, NULL, "ztwobus", NULL); 161#endif 162} 163 164/* 165 * mainbus driver 166 */ 167struct cfdriver mainbuscd = { 168 NULL, "mainbus", mbmatch, mbattach, 169 DV_DULL, sizeof(struct device), NULL, 0 170}; 171 172int 173mbmatch(pdp, cfp, auxp) 174 struct device *pdp; 175 struct cfdata *cfp; 176 void *auxp; 177{ 178 if (cfp->cf_unit > 0) 179 return(0); 180 /* 181 * We are always here 182 */ 183 return(1); 184} 185 186/* 187 * "find" all the things that should be there. 188 */ 189void 190mbattach(pdp, dp, auxp) 191 struct device *pdp, *dp; 192 void *auxp; 193{ 194 printf ("\n"); 195 config_found(dp, "clock", simple_devprint); 196 config_found(dp, "ser", simple_devprint); 197 config_found(dp, "par", simple_devprint); 198 config_found(dp, "kbd", simple_devprint); 199 config_found(dp, "grfcc", simple_devprint); 200 config_found(dp, "fdc", simple_devprint); 201 config_found(dp, "ztwobus", simple_devprint); 202 if (is_a3000()) 203 config_found(dp, "ahsc", simple_devprint); 204 if (is_a3000() || is_a4000()) { 205 config_found(dp, "zthreebus", simple_devprint); 206 } 207 if (is_a4000()) 208 config_found(dp, "idesc", simple_devprint); 209} 210 211int 212mbprint(auxp, pnp) 213 void *auxp; 214 char *pnp; 215{ 216 if (pnp) 217 printf("%s at %s", (char *)auxp, pnp); 218 return(UNCONF); 219} 220 221void 222swapconf() 223{ 224 struct swdevt *swp; 225 u_int maj; 226 int nb; 227 228 for (swp = swdevt; swp->sw_dev > 0; swp++) { 229 maj = major(swp->sw_dev); 230 231 if (maj > nblkdev) 232 break; 233 234 if (bdevsw[maj].d_psize) { 235 nb = bdevsw[maj].d_psize(swp->sw_dev); 236 if (nb > 0 && 237 (swp->sw_nblks == 0 || swp->sw_nblks > nb)) 238 swp->sw_nblks = nb; 239 else 240 swp->sw_nblks = 0; 241 } 242 swp->sw_nblks = ctod(dtoc(swp->sw_nblks)); 243 } 244 if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize) 245 /*dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem;*/ 246 dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - 247 ctob(physmem)/DEV_BSIZE; 248 if (dumplo < 0) 249 dumplo = 0; 250 251} 252 253#define DOSWAP /* change swdevt and dumpdev */ 254u_long bootdev = 0; /* should be dev_t, but not until 32 bits */ 255 256static char devname[][2] = { 257 0,0, 258 0,0, 259 'f','d', /* 2 = fd */ 260 0,0, 261 's','d', /* 4 = sd -- new SCSI system */ 262}; 263 264void 265setroot() 266{ 267 int majdev, mindev, unit, part, adaptor; 268 dev_t temp, orootdev; 269 struct swdevt *swp; 270 271 if (boothowto & RB_DFLTROOT || 272 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 273 return; 274 majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 275 if (majdev > sizeof(devname) / sizeof(devname[0])) 276 return; 277 adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 278 part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 279 unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 280 orootdev = rootdev; 281 rootdev = MAKEDISKDEV(majdev, unit, part); 282 /* 283 * If the original rootdev is the same as the one 284 * just calculated, don't need to adjust the swap configuration. 285 */ 286 if (rootdev == orootdev) 287 return; 288 printf("changing root device to %c%c%d%c\n", 289 devname[majdev][0], devname[majdev][1], 290 unit, part + 'a'); 291#ifdef DOSWAP 292 mindev = DISKUNIT(rootdev); 293 for (swp = swdevt; swp->sw_dev; swp++) { 294 if (majdev == major(swp->sw_dev) && 295 mindev == DISKUNIT(swp->sw_dev)) { 296 temp = swdevt[0].sw_dev; 297 swdevt[0].sw_dev = swp->sw_dev; 298 swp->sw_dev = temp; 299 break; 300 } 301 } 302 if (swp->sw_dev == 0) 303 return; 304 /* 305 * If dumpdev was the same as the old primary swap 306 * device, move it to the new primary swap device. 307 */ 308 if (temp == dumpdev) 309 dumpdev = swdevt[0].sw_dev; 310#endif 311} 312 313 314/* 315 * Try to determine, of this machine is an A3000, which has a builtin 316 * realtime clock and scsi controller, so that this hardware is only 317 * included as "configured" if this IS an A3000 318 */ 319 320int a3000_flag = 1; /* patchable */ 321#ifdef A4000 322int a4000_flag = 1; /* patchable - default to A4000 */ 323#else 324int a4000_flag = 0; /* patchable */ 325#endif 326 327int 328is_a3000() 329{ 330 /* this is a dirty kludge.. but how do you do this RIGHT ? :-) */ 331 extern long orig_fastram_start; 332 short sc; 333 334 if ((machineid >> 16) == 3000) 335 return (1); /* It's an A3000 */ 336 if (machineid >> 16) 337 return (0); /* It's not an A3000 */ 338 /* Machine type is unknown, so try to guess it */ 339 /* where is fastram on the A4000 ?? */ 340 /* if fastram is below 0x07000000, assume it's not an A3000 */ 341 if (orig_fastram_start < 0x07000000) 342 return(0); 343 /* 344 * OK, fastram starts at or above 0x07000000, check specific 345 * machines 346 */ 347 for (sc = 0; sc < ncfdev; sc++) { 348 switch (cfdev[sc].rom.manid) { 349 case 2026: /* Progressive Peripherals, Inc */ 350 switch (cfdev[sc].rom.prodid) { 351 case 0: /* PPI Mercury - A3000 */ 352 case 1: /* PP&S A3000 '040 */ 353 return(1); 354 case 150: /* PPI Zeus - it's an A2000 */ 355 case 105: /* PP&S A2000 '040 */ 356 case 187: /* PP&S A500 '040 */ 357 return(0); 358 } 359 break; 360 361 case 2112: /* IVS */ 362 switch (cfdev[sc].rom.prodid) { 363 case 242: 364 return(0); /* A2000 accelerator? */ 365 } 366 break; 367 } 368 } 369 return (a3000_flag); /* XXX let flag tell now */ 370} 371 372int 373is_a4000() 374{ 375 if ((machineid >> 16) == 4000) 376 return (1); /* It's an A4000 */ 377 if ((custom.deniseid & 0xff) == 0xf8) 378 return (1); 379#ifdef DEBUG 380 if (a4000_flag) 381 printf ("Denise ID = %04x\n", (unsigned short)custom.deniseid); 382#endif 383 if (machineid >> 16) 384 return (0); /* It's not an A4000 */ 385 return (a4000_flag); /* Machine type not set */ 386} 387