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