xref: /netbsd-src/sys/arch/sun3/sun3/autoconf.c (revision 2a399c6883d870daece976daec6ffa7bb7f934ce)
1 /*	$NetBSD: autoconf.c,v 1.49 1997/08/27 11:24:30 bouyer Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Adam Glass and Gordon W. Ross.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Setup the system to run on the current machine.
41  *
42  * Configure() is called at boot time.  Available devices are
43  * determined (from possibilities mentioned in ioconf.c), and
44  * the drivers are initialized.
45  */
46 
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/conf.h>
50 #include <sys/device.h>
51 
52 #include <dev/scsipi/scsi_all.h>
53 #include <dev/scsipi/scsipi_all.h>
54 #include <dev/scsipi/scsiconf.h>
55 
56 #include <machine/autoconf.h>
57 #include <machine/machdep.h>
58 #include <machine/mon.h>
59 
60 /* Want compile-time initialization here. */
61 int cold = 1;
62 
63 /*
64  * Do general device autoconfiguration,
65  * then choose root device (etc.)
66  * Called by machdep.c: cpu_startup()
67  */
68 void
69 configure()
70 {
71 
72 	/* General device autoconfiguration. */
73 	if (config_rootfound("mainbus", NULL) == NULL)
74 		panic("configure: mainbus not found");
75 
76 	/*
77 	 * Now that device autoconfiguration is finished,
78 	 * we can safely enable interrupts.
79 	 */
80 	printf("enabling interrupts\n");
81 	(void)spl0();
82 	cold = 0;
83 }
84 
85 /****************************************************************/
86 
87 /*
88  * Support code to find the boot device.
89  */
90 
91 static struct devnametobdevmaj nam2blk[] = {
92 	{ "xy",		3 },
93 	{ "sd",		7 },
94 	{ "xd",		10 },
95 	{ "md",		13 },
96 	{ "cd",		18 },
97 	{ NULL,		0 },
98 };
99 
100 /* This takes the args: name, ctlr, unit */
101 typedef struct device * (*findfunc_t) __P((char *, int, int));
102 
103 static struct device * find_dev_byname __P((char *));
104 static struct device * net_find  __P((char *, int, int));
105 static struct device * scsi_find __P((char *, int, int));
106 static struct device * xx_find   __P((char *, int, int));
107 
108 struct prom_n2f {
109 	const char name[4];
110 	findfunc_t func;
111 };
112 static struct prom_n2f prom_dev_table[] = {
113 	{ "ie",		net_find },
114 	{ "le",		net_find },
115 	{ "sd",		scsi_find },
116 	{ "xy",		xx_find },
117 	{ "xd",		xx_find },
118 	{ "",		0 },
119 };
120 
121 /*
122  * Choose root and swap devices.
123  */
124 void
125 cpu_rootconf()
126 {
127 	MachMonBootParam *bp;
128 	struct prom_n2f *nf;
129 	struct device *boot_device;
130 	int boot_partition;
131 	char *devname;
132 	findfunc_t find;
133 	char promname[4];
134 	char partname[4];
135 
136 	/* PROM boot parameters. */
137 	bp = *romVectorPtr->bootParam;
138 
139 	/*
140 	 * Copy PROM boot device name (two letters)
141 	 * to a normal, null terminated string.
142 	 * (No terminating null in bp->devName)
143 	 */
144 	promname[0] = bp->devName[0];
145 	promname[1] = bp->devName[1];
146 	promname[2] = '\0';
147 
148 	/* Default to "unknown" */
149 	boot_device = NULL;
150 	boot_partition = 0;
151 	devname = "<unknown>";
152 	partname[0] = '\0';
153 	find = NULL;
154 
155 	/* Do we know anything about the PROM boot device? */
156 	for (nf = prom_dev_table; nf->func; nf++)
157 		if (!strcmp(nf->name, promname)) {
158 			find = nf->func;
159 			break;
160 		}
161 	if (find)
162 		boot_device = (*find)(promname, bp->ctlrNum, bp->unitNum);
163 	if (boot_device) {
164 		devname = boot_device->dv_xname;
165 		if (boot_device->dv_class == DV_DISK) {
166 			boot_partition = bp->partNum & 7;
167 			partname[0] = 'a' + boot_partition;
168 			partname[1] = '\0';
169 		}
170 	}
171 
172 	printf("boot device: %s%s\n", devname, partname);
173 	setroot(boot_device, boot_partition, nam2blk);
174 }
175 
176 /*
177  * Functions to find devices using PROM boot parameters.
178  */
179 
180 /*
181  * Network device:  Just use controller number.
182  */
183 static struct device *
184 net_find(name, ctlr, unit)
185 	char *name;
186 	int ctlr, unit;
187 {
188 	char tname[16];
189 
190 	sprintf(tname, "%s%d", name, ctlr);
191 	return (find_dev_byname(tname));
192 }
193 
194 /*
195  * SCSI device:  The controller number corresponds to the
196  * scsibus number, and the unit number is (targ*8 + LUN).
197  */
198 static struct device *
199 scsi_find(name, ctlr, unit)
200 	char *name;
201 	int ctlr, unit;
202 {
203 	struct device *scsibus;
204 	struct scsibus_softc *sbsc;
205 	struct scsipi_link *sc_link;
206 	int target, lun;
207 	char tname[16];
208 
209 	sprintf(tname, "scsibus%d", ctlr);
210 	scsibus = find_dev_byname(tname);
211 	if (scsibus == NULL)
212 		return (NULL);
213 
214 	/* Compute SCSI target/LUN from PROM unit. */
215 	target = (unit >> 3) & 7;
216 	lun = unit & 7;
217 
218 	/* Find the device at this target/LUN */
219 	sbsc = (struct scsibus_softc *)scsibus;
220 	sc_link = sbsc->sc_link[target][lun];
221 	if (sc_link == NULL)
222 		return (NULL);
223 
224 	return (sc_link->device_softc);
225 }
226 
227 /*
228  * Xylogics SMD disk: (xy, xd)
229  * Assume wired-in unit numbers for now...
230  */
231 static struct device *
232 xx_find(name, ctlr, unit)
233 	char *name;
234 	int ctlr, unit;
235 {
236 	int diskunit;
237 	char tname[16];
238 
239 	diskunit = (ctlr * 2) + unit;
240 	sprintf(tname, "%s%d", name, diskunit);
241 	return (find_dev_byname(tname));
242 }
243 
244 /*
245  * Given a device name, find its struct device
246  * XXX - Move this to some common file?
247  */
248 static struct device *
249 find_dev_byname(name)
250 	char *name;
251 {
252 	struct device *dv;
253 
254 	for (dv = alldevs.tqh_first; dv != NULL;
255 	    dv = dv->dv_list.tqe_next) {
256 		if (!strcmp(dv->dv_xname, name)) {
257 			return(dv);
258 		}
259 	}
260 	return (NULL);
261 }
262