xref: /netbsd/sys/arch/arc/arc/autoconf.c (revision bf9ec67e)
1 /*	$NetBSD: autoconf.c,v 1.16 2001/06/13 14:36:34 soda Exp $	*/
2 /*	$OpenBSD: autoconf.c,v 1.9 1997/05/18 13:45:20 pefo Exp $	*/
3 
4 /*
5  * Copyright (c) 1996 Per Fogelstrom
6  * Copyright (c) 1988 University of Utah.
7  * Copyright (c) 1992, 1993
8  *	The Regents of the University of California.  All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * the Systems Programming Group of the University of Utah Computer
12  * Science Department and Ralph Campbell.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. All advertising materials mentioning features or use of this software
23  *    must display the following acknowledgement:
24  *	This product includes software developed by the University of
25  *	California, Berkeley and its contributors.
26  * 4. Neither the name of the University nor the names of its contributors
27  *    may be used to endorse or promote products derived from this software
28  *    without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40  * SUCH DAMAGE.
41  *
42  * from: Utah Hdr: autoconf.c 1.31 91/01/21
43  *
44  *	from: @(#)autoconf.c	8.1 (Berkeley) 6/10/93
45  */
46 
47 /*
48  * Setup the system to run on the current machine.
49  *
50  * Configure() is called at boot time.  Available
51  * devices are determined (from possibilities mentioned in ioconf.c),
52  * and the drivers are initialized.
53  */
54 
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/buf.h>
58 #include <sys/disklabel.h>
59 #include <sys/conf.h>
60 #include <sys/reboot.h>
61 #include <sys/device.h>
62 
63 #include <machine/cpu.h>
64 #include <machine/autoconf.h>
65 
66 #include <dev/scsipi/scsi_all.h>
67 #include <dev/scsipi/scsipi_all.h>
68 #include <dev/scsipi/scsiconf.h>
69 
70 struct bootdev_data {
71 	char	*dev_type;
72 	int	bus;
73 	int	unit;
74 	int	partition;
75 };
76 
77 int getpno __P((char **, int *));
78 
79 /*
80  * The following several variables are related to
81  * the configuration process, and are used in initializing
82  * the machine.
83  */
84 struct device *booted_device;
85 struct bootdev_data *bootdev_data;
86 
87 /*
88  *  Configure all devices found that we know about.
89  *  This is done at boot time.
90  */
91 void
92 cpu_configure()
93 {
94 	(void)splhigh();	/* To be really sure.. */
95 	if (config_rootfound("mainbus", "mainbus") == NULL)
96 		panic("no mainbus found");
97 
98 	/* Configuration is finished, turn on interrupts. */
99 	_splnone();	/* enable all source forcing SOFT_INTs cleared */
100 }
101 
102 #if defined(NFS_BOOT_BOOTP) || defined(NFS_BOOT_DHCP)
103 int nfs_boot_rfc951 = 1;
104 #endif
105 
106 void
107 cpu_rootconf()
108 {
109 	printf("boot device: %s\n",
110 	    booted_device ? booted_device->dv_xname : "<unknown>");
111 
112 	setroot(booted_device, booted_device ? bootdev_data->partition : 0);
113 }
114 
115 struct devmap {
116 	char *attachment;
117 	char *dev;
118 };
119 
120 /*
121  * Look at the string 'cp' and decode the boot device.
122  * Boot names look like: scsi()disk(n)rdisk()partition(1)\bsd
123  * (beware for empty scsi id's...)
124  */
125 void
126 makebootdev(cp)
127 	char *cp;
128 {
129 	int ok, junk;
130 	static struct devmap devmap[] = {
131 		{ "multi", "fd" },
132 		{ "eisa", "wd" },
133 		{ "scsi", "sd" },
134 		{ NULL, NULL }
135 	};
136 	struct devmap *dp = &devmap[0];
137 	static struct bootdev_data bd;
138 
139 	/* "scsi()" */
140 	while (dp->attachment) {
141 		if (strncmp (cp, dp->attachment, strlen(dp->attachment)) == 0)
142 			break;
143 		dp++;
144 	}
145 	if (!dp->attachment) {
146 		printf("Warning: boot device unrecognized: %s\n", cp);
147 		return;
148 	}
149 	bd.dev_type = dp->dev;
150 	ok = getpno(&cp, &bd.bus);
151 
152 	/* "multi(2)scsi(0)disk(0)rdisk(0)partition(1)" case */
153 	if (ok && strcmp(dp->attachment, "multi") == 0 &&
154 	    memcmp(cp, "scsi", 4) == 0) {
155 		bd.dev_type = "sd";
156 		ok = getpno(&cp, &bd.bus);
157 	}
158 
159 	/* "disk(N)" */
160 	if (ok)
161 		ok = getpno(&cp, &bd.unit);
162 	else
163 		bd.unit = 0;
164 
165 	/* "rdisk()" */
166 	if (*cp++ == ')')
167 		ok = getpno(&cp, &junk);
168 
169 	/* "partition(1)" */
170 #if 0 /* ignore partition number */
171 	if (ok && getpno(&cp, &bd.partition))
172 		--bd.partition;
173 	else
174 #endif
175 		bd.partition = 0;
176 
177 	bootdev_data = &bd;
178 }
179 
180 int
181 getpno(cp, np)
182 	char **cp;
183 	int *np;
184 {
185 	int val = 0;
186 	char *s = *cp;
187 	int got = 0;
188 
189 	*np = 0;
190 
191 	while (*s && *s != '(')
192 		s++;
193 	if (*s == '(') {
194 		for (s++; *s; s++) {
195 			if (*s == ')') {
196 				s++;
197 				got = 1;
198 				*np = val;
199 				break;
200 			}
201 			val = val * 10 + *s - '0';
202 		}
203 	}
204 	*cp = s;
205 	return (got);
206 }
207 
208 /*
209  * Attempt to find the device from which we were booted.
210  */
211 void
212 device_register(dev, aux)
213 	struct device *dev;
214 	void *aux;
215 {
216 	struct bootdev_data *b = bootdev_data;
217 	struct device *parent = dev->dv_parent;
218 	struct cfdata *cf = dev->dv_cfdata;
219 	struct cfdriver *cd = cf->cf_driver;
220 
221 	static int found = 0, initted = 0, scsiboot = 0;
222 	static struct device *scsibusdev = NULL;
223 
224 	if (b == NULL)
225 		return;	/* There is no hope. */
226 	if (found)
227 		return;
228 
229 	if (!initted) {
230 		if (strcmp(b->dev_type, "sd") == 0)
231 			scsiboot = 1;
232 		initted = 1;
233 	}
234 
235 	if (scsiboot && strcmp(cd->cd_name, "scsibus") == 0) {
236 		if (dev->dv_unit == b->bus) {
237 			scsibusdev = dev;
238 #if 0
239 			printf("\nscsibus = %s\n", dev->dv_xname);
240 #endif
241 		}
242 		return;
243 	}
244 
245 	if (strcmp(b->dev_type, cd->cd_name) != 0)
246 		return;
247 
248 	if (strcmp(cd->cd_name, "sd") == 0) {
249 		struct scsipibus_attach_args *sa = aux;
250 
251 		if (scsiboot && scsibusdev && parent == scsibusdev &&
252 		    sa->sa_periph->periph_target == b->unit) {
253 			booted_device = dev;
254 #if 0
255 			printf("\nbooted_device = %s\n", dev->dv_xname);
256 #endif
257 			found = 1;
258 		}
259 		return;
260 	}
261 	if (dev->dv_unit == b->unit) {
262 		booted_device = dev;
263 #if 0
264 		printf("\nbooted_device = %s\n", dev->dv_xname);
265 #endif
266 		found = 1;
267 	}
268 }
269