autoconf.c revision 1.11 1 /* $NetBSD: autoconf.c,v 1.11 2003/05/03 18:10:56 wiz 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