xref: /netbsd/sys/arch/sgimips/sgimips/autoconf.c (revision c4a72b64)
1 /*	$NetBSD: autoconf.c,v 1.11 2002/09/27 02:24:22 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 2000 Soren S. Jorvang
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *          This product includes software developed for the
18  *          NetBSD Project.  See http://www.netbsd.org/ for
19  *          information about NetBSD.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "opt_ddb.h"
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/buf.h>
40 #include <sys/conf.h>
41 #include <sys/device.h>
42 
43 #include <machine/cpu.h>
44 #include <machine/sysconf.h>
45 #include <machine/machtype.h>
46 #include <machine/autoconf.h>
47 
48 #include <dev/scsipi/scsi_all.h>
49 #include <dev/scsipi/scsipi_all.h>
50 #include <dev/scsipi/scsiconf.h>
51 
52 struct device	*booted_device = NULL;
53 static struct device *booted_controller = NULL;
54 static int	booted_slot, booted_unit, booted_partition;
55 static char	*booted_protocol = NULL;
56 
57 extern struct platform platform;
58 
59 void
60 cpu_configure()
61 {
62 	int s;
63 
64 	softintr_init();
65 
66 	s = splhigh();
67 	if (config_rootfound("mainbus", "mainbus") == NULL)
68 		panic("no mainbus found");
69 
70 	/*
71 	 * Clear latched bus error registers which may have been
72 	 * caused by probes for non-existent devices.
73 	 */
74 	(*platform.bus_reset)();
75 
76 	printf("biomask %02x netmask %02x ttymask %02x clockmask %02x\n",
77 	    biomask >> 8, netmask >> 8, ttymask >> 8, clockmask >> 8);
78 
79 	_splnone();
80 }
81 
82 /*
83  * Look at the string 'cp' and decode the boot device.  Boot names
84  * can be something like 'bootp(0)netbsd' or
85  * 'scsi(0)disk(1)rdisk(0)partition(0)netbsd' or
86  * 'dksc(0,1,0)netbsd'
87  */
88 void
89 makebootdev(cp)
90 	char *cp;
91 {
92 	if (booted_protocol != NULL)
93 		return;
94 
95 	booted_slot = booted_unit = booted_partition = 0;
96 
97 	if (strncmp(cp, "scsi(", 5) == NULL) {
98 		cp += 5;
99 		if (*cp >= '0' && *cp <= '9')
100 			booted_slot = *cp++ - '0';
101 		if (strncmp(cp, ")disk(", 6) == NULL) {
102 			cp += 6;
103 			if (*cp >= '0' && *cp <= '9')
104 				booted_unit = *cp++ - '0';
105 		}
106 		/* XXX can rdisk() ever be other than 0? */
107 		if (strncmp(cp, ")rdisk(0)partition(", 19) == NULL) {
108 			cp += 19;
109 			while (*cp >= '0' && *cp <= '9')
110 				booted_partition =
111 					booted_partition * 10 + *cp++ - '0';
112 		}
113 		if (*cp != ')')
114 			return;	/* XXX ? */
115 		booted_protocol = "SCSI";
116 		return;
117 	}
118 	if (strncmp(cp, "dksc(", 5) == NULL) {
119 		cp += 5;
120 		if (*cp >= '0' && *cp <= '9')
121 			booted_slot = *cp++ - '0';
122 		if (*cp == ',') {
123 			++cp;
124 			if (*cp >= '0' || *cp <= '9')
125 				booted_unit = *cp++ - '0';
126 			if (*cp == ',') {
127 				++cp;
128 				if (*cp >= '0' && *cp <= '9')
129 					booted_partition = *cp++ - '0';
130 			}
131 		}
132 		if (*cp != ')')
133 			return;		/* XXX ??? */
134 		booted_protocol = "SCSI";
135 		return;
136 	}
137 	if (strncmp(cp, "bootp(", 6) == 0) {
138 		/* XXX controller number?  Needed to
139 		   handle > 1 network controller */
140 		booted_protocol = "BOOTP";
141 		return;
142 	}
143 }
144 
145 void
146 cpu_rootconf()
147 {
148 	printf("boot device: %s\n",
149 		booted_device ? booted_device->dv_xname : "<unknown>");
150 
151 	setroot(booted_device, booted_partition);
152 }
153 
154 /*
155  * Try to determine the boot device.
156  */
157 void
158 device_register(dev, aux)
159 	struct device *dev;
160 	void *aux;
161 {
162 	static int found, initted, scsiboot, netboot;
163 	struct device *parent = dev->dv_parent;
164 	struct cfdata *cf = dev->dv_cfdata;
165 	const char *name = cf->cf_name;
166 
167 	if (found)
168 		return;
169 
170 	if (!initted && booted_protocol) {
171 		scsiboot = strcmp(booted_protocol, "SCSI") == 0;
172 		netboot = (strcmp(booted_protocol, "BOOTP") == 0);
173 		initted = 1;
174 	}
175 
176 	/*
177 	 * Check for WDC controller
178 	 */
179 	if (scsiboot && strcmp(name, "wdsc") == 0) {
180 		/*
181 		 * XXX: this fails if the controllers were attached
182 		 * in an order other than the ARCS-imposed order.
183 		 */
184 		if (dev->dv_unit == booted_slot)
185 			booted_controller = dev;
186 		return;
187 	}
188 
189 	/*
190 	 * Other SCSI controllers ??
191 	 */
192 
193 	/*
194 	 * If we found the boot controller, if check disk/tape/cdrom device
195 	 * on that controller matches.
196 	 */
197 	if (booted_controller && (strcmp(name, "sd") == 0 ||
198 	    strcmp(name, "st") == 0 ||
199 	    strcmp(name, "cd") == 0)) {
200 		struct scsipibus_attach_args *sa = aux;
201 
202 		if (parent->dv_parent != booted_controller)
203 			return;
204 		if (booted_unit != sa->sa_periph->periph_target)
205 			return;
206 		booted_device = dev;
207 		found = 1;
208 		return;
209 	}
210 
211 	/*
212 	 * Check if netboot device.
213 	 */
214 	if (netboot && strcmp(name, "sq") == 0) {
215 		/* XXX Check unit number? (Which we don't parse yet) */
216 		booted_device = dev;
217 		found = 1;
218 		return;
219 	}
220 }
221