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