1 /* $NetBSD: autoconf.c,v 1.12 2003/06/18 08:58:39 drochner Exp $ */ 2 3 /* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1982, 1986, 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * from: Utah $Hdr: autoconf.c 1.36 92/12/20$ 41 * 42 * @(#)autoconf.c 8.2 (Berkeley) 1/12/94 43 */ 44 45 /* 46 * Setup the system to run on the current machine. 47 * 48 * Configure() is called at boot time. Available 49 * devices are determined (from possibilities mentioned in ioconf.c), 50 * and the drivers are initialized. 51 */ 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/buf.h> 56 #include <sys/conf.h> 57 #include <sys/reboot.h> 58 #include <sys/device.h> 59 60 #include <machine/vmparam.h> 61 #include <machine/autoconf.h> 62 #include <machine/disklabel.h> 63 #include <machine/cpu.h> 64 #include <machine/pte.h> 65 66 #include <next68k/next68k/isr.h> 67 #include <next68k/next68k/nextrom.h> 68 69 #include <next68k/dev/intiovar.h> 70 71 struct device *booted_device; /* boot device */ 72 volatile u_long *intrstat; 73 volatile u_long *intrmask; 74 75 static struct device *getdevunit __P((char *, int)); 76 static int devidentparse __P((const char *, int *, int *, int *)); 77 static int atoi __P((const char *)); 78 79 struct device_equiv { 80 char *alias; 81 char *real; 82 }; 83 static struct device_equiv device_equiv[] = { 84 { "en", "xe" }, 85 { "tp", "xe" }, 86 }; 87 static int ndevice_equivs = (sizeof(device_equiv)/sizeof(device_equiv[0])); 88 89 /* 90 * Determine mass storage and memory configuration for a machine. 91 */ 92 void 93 cpu_configure() 94 { 95 /* int dma_rev; */ 96 extern u_int rom_intrmask; 97 extern u_int rom_intrstat; 98 99 booted_device = NULL; /* set by device drivers (if found) */ 100 101 #if 0 102 dma_rev = ((volatile u_char *)IIOV(NEXT_P_SCR1))[1]; 103 switch (dma_rev) { 104 case 0: 105 intrmask = (volatile u_long *)IIOV(NEXT_P_INTRMASK_0); 106 intrstat = (volatile u_long *)IIOV(NEXT_P_INTRSTAT_0); 107 /* dspreg = (volatile u_long *)IIOV(0x2007000); */ 108 break; 109 case 1: 110 intrmask = (volatile u_long *)IIOV(NEXT_P_INTRMASK); 111 intrstat = (volatile u_long *)IIOV(NEXT_P_INTRSTAT); 112 /* dspreg = (volatile u_long *)IIOV(0x2108000); */ 113 break; 114 default: 115 panic("unknown DMA chip revision"); 116 } 117 #else 118 intrmask = (volatile u_long *)IIOV(rom_intrmask); 119 intrstat = (volatile u_long *)IIOV(rom_intrstat); 120 printf ("intrmask: %p\n", intrmask); 121 printf ("intrstat: %p\n", intrstat); 122 #endif 123 124 INTR_SETMASK(0); 125 126 init_sir(); 127 128 if (config_rootfound("mainbus", NULL) == NULL) 129 panic("autoconfig failed, no root"); 130 131 /* Turn on interrupts */ 132 spl0(); 133 } 134 135 void 136 cpu_rootconf() 137 { 138 int count, lun, part; 139 140 count = lun = part = 0; 141 142 devidentparse (rom_boot_info, &count, &lun, &part); 143 booted_device = getdevunit (rom_boot_dev, count); 144 145 printf("boot device: %s\n", 146 (booted_device) ? booted_device->dv_xname : "<unknown>"); 147 148 setroot(booted_device, part); 149 } 150 151 /* 152 * find a device matching "name" and unit number 153 */ 154 static struct device * 155 getdevunit(name, unit) 156 char *name; 157 int unit; 158 { 159 struct device *dev = alldevs.tqh_first; 160 char num[10], fullname[16]; 161 int lunit; 162 int i; 163 164 for (i = 0; i < ndevice_equivs; i++) 165 if (device_equiv->alias && strcmp (name, device_equiv->alias) == 0) 166 name = device_equiv->real; 167 168 /* compute length of name and decimal expansion of unit number */ 169 sprintf(num, "%d", unit); 170 lunit = strlen(num); 171 if (strlen(name) + lunit >= sizeof(fullname) - 1) 172 panic("config_attach: device name too long"); 173 174 strcpy(fullname, name); 175 strcat(fullname, num); 176 177 while (strcmp(dev->dv_xname, fullname) != 0) { 178 if ((dev = dev->dv_list.tqe_next) == NULL) 179 return NULL; 180 } 181 return dev; 182 } 183 184 /* 185 * Parse a device ident. 186 * 187 * Format: 188 * (count, lun, part) 189 */ 190 static int 191 devidentparse(spec, count, lun, part) 192 const char *spec; 193 int *count; 194 int *lun; 195 int *part; 196 { 197 int i; 198 const char *args[3]; 199 200 if (*spec == '(') { 201 /* tokenize device ident */ 202 args[0] = ++spec; 203 for (i = 1; *spec && *spec != ')' && i<3; spec++) { 204 if (*spec == ',') 205 args[i++] = ++spec; 206 } 207 if (*spec != ')') 208 goto baddev; 209 210 switch(i) { 211 case 3: 212 *count = atoi(args[0]); 213 *lun = atoi(args[1]); 214 *part = atoi(args[2]); 215 break; 216 case 2: 217 *lun = atoi(args[0]); 218 *part = atoi(args[1]); 219 break; 220 case 1: 221 *part = atoi(args[0]); 222 break; 223 case 0: 224 break; 225 } 226 } 227 else 228 goto baddev; 229 230 return 0; 231 232 baddev: 233 return ENXIO; 234 } 235 236 static int 237 atoi(s) 238 const char *s; 239 { 240 int val = 0; 241 242 while(isdigit(*s)) 243 val = val * 10 + (*s++ - '0'); 244 return val; 245 } 246