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