1 /* $NetBSD: autoconf.c,v 1.13 2003/07/15 02:59:33 lukem 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/cdefs.h> 54 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.13 2003/07/15 02:59:33 lukem Exp $"); 55 56 #include <sys/param.h> 57 #include <sys/systm.h> 58 #include <sys/buf.h> 59 #include <sys/conf.h> 60 #include <sys/reboot.h> 61 #include <sys/device.h> 62 63 #include <machine/vmparam.h> 64 #include <machine/autoconf.h> 65 #include <machine/disklabel.h> 66 #include <machine/cpu.h> 67 #include <machine/pte.h> 68 69 #include <next68k/next68k/isr.h> 70 #include <next68k/next68k/nextrom.h> 71 72 #include <next68k/dev/intiovar.h> 73 74 struct device *booted_device; /* boot device */ 75 volatile u_long *intrstat; 76 volatile u_long *intrmask; 77 78 static struct device *getdevunit __P((char *, int)); 79 static int devidentparse __P((const char *, int *, int *, int *)); 80 static int atoi __P((const char *)); 81 82 struct device_equiv { 83 char *alias; 84 char *real; 85 }; 86 static struct device_equiv device_equiv[] = { 87 { "en", "xe" }, 88 { "tp", "xe" }, 89 }; 90 static int ndevice_equivs = (sizeof(device_equiv)/sizeof(device_equiv[0])); 91 92 /* 93 * Determine mass storage and memory configuration for a machine. 94 */ 95 void 96 cpu_configure() 97 { 98 /* int dma_rev; */ 99 extern u_int rom_intrmask; 100 extern u_int rom_intrstat; 101 102 booted_device = NULL; /* set by device drivers (if found) */ 103 104 #if 0 105 dma_rev = ((volatile u_char *)IIOV(NEXT_P_SCR1))[1]; 106 switch (dma_rev) { 107 case 0: 108 intrmask = (volatile u_long *)IIOV(NEXT_P_INTRMASK_0); 109 intrstat = (volatile u_long *)IIOV(NEXT_P_INTRSTAT_0); 110 /* dspreg = (volatile u_long *)IIOV(0x2007000); */ 111 break; 112 case 1: 113 intrmask = (volatile u_long *)IIOV(NEXT_P_INTRMASK); 114 intrstat = (volatile u_long *)IIOV(NEXT_P_INTRSTAT); 115 /* dspreg = (volatile u_long *)IIOV(0x2108000); */ 116 break; 117 default: 118 panic("unknown DMA chip revision"); 119 } 120 #else 121 intrmask = (volatile u_long *)IIOV(rom_intrmask); 122 intrstat = (volatile u_long *)IIOV(rom_intrstat); 123 printf ("intrmask: %p\n", intrmask); 124 printf ("intrstat: %p\n", intrstat); 125 #endif 126 127 INTR_SETMASK(0); 128 129 init_sir(); 130 131 if (config_rootfound("mainbus", NULL) == NULL) 132 panic("autoconfig failed, no root"); 133 134 /* Turn on interrupts */ 135 spl0(); 136 } 137 138 void 139 cpu_rootconf() 140 { 141 int count, lun, part; 142 143 count = lun = part = 0; 144 145 devidentparse (rom_boot_info, &count, &lun, &part); 146 booted_device = getdevunit (rom_boot_dev, count); 147 148 printf("boot device: %s\n", 149 (booted_device) ? booted_device->dv_xname : "<unknown>"); 150 151 setroot(booted_device, part); 152 } 153 154 /* 155 * find a device matching "name" and unit number 156 */ 157 static struct device * 158 getdevunit(name, unit) 159 char *name; 160 int unit; 161 { 162 struct device *dev = alldevs.tqh_first; 163 char num[10], fullname[16]; 164 int lunit; 165 int i; 166 167 for (i = 0; i < ndevice_equivs; i++) 168 if (device_equiv->alias && strcmp (name, device_equiv->alias) == 0) 169 name = device_equiv->real; 170 171 /* compute length of name and decimal expansion of unit number */ 172 sprintf(num, "%d", unit); 173 lunit = strlen(num); 174 if (strlen(name) + lunit >= sizeof(fullname) - 1) 175 panic("config_attach: device name too long"); 176 177 strcpy(fullname, name); 178 strcat(fullname, num); 179 180 while (strcmp(dev->dv_xname, fullname) != 0) { 181 if ((dev = dev->dv_list.tqe_next) == NULL) 182 return NULL; 183 } 184 return dev; 185 } 186 187 /* 188 * Parse a device ident. 189 * 190 * Format: 191 * (count, lun, part) 192 */ 193 static int 194 devidentparse(spec, count, lun, part) 195 const char *spec; 196 int *count; 197 int *lun; 198 int *part; 199 { 200 int i; 201 const char *args[3]; 202 203 if (*spec == '(') { 204 /* tokenize device ident */ 205 args[0] = ++spec; 206 for (i = 1; *spec && *spec != ')' && i<3; spec++) { 207 if (*spec == ',') 208 args[i++] = ++spec; 209 } 210 if (*spec != ')') 211 goto baddev; 212 213 switch(i) { 214 case 3: 215 *count = atoi(args[0]); 216 *lun = atoi(args[1]); 217 *part = atoi(args[2]); 218 break; 219 case 2: 220 *lun = atoi(args[0]); 221 *part = atoi(args[1]); 222 break; 223 case 1: 224 *part = atoi(args[0]); 225 break; 226 case 0: 227 break; 228 } 229 } 230 else 231 goto baddev; 232 233 return 0; 234 235 baddev: 236 return ENXIO; 237 } 238 239 static int 240 atoi(s) 241 const char *s; 242 { 243 int val = 0; 244 245 while(isdigit(*s)) 246 val = val * 10 + (*s++ - '0'); 247 return val; 248 } 249