xref: /netbsd-src/sys/arch/emips/emips/autoconf.c (revision 46f5119e40af2e51998f686b2fdcc76b5488f7f3)
1 /*	$NetBSD: autoconf.c,v 1.3 2011/02/22 08:20:20 matt Exp $	*/
2 
3 /*
4  * Copyright (c) 1988 University of Utah.
5  * Copyright (c) 1992, 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 and Ralph Campbell.
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. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * from: Utah Hdr: autoconf.c 1.31 91/01/21
37  *
38  *	@(#)autoconf.c	8.1 (Berkeley) 6/10/93
39  */
40 
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.3 2011/02/22 08:20:20 matt Exp $");
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/conf.h>
47 #include <sys/reboot.h>
48 #include <sys/device.h>
49 
50 #include <machine/autoconf.h>
51 #include <machine/intr.h>
52 #include <machine/sysconf.h>
53 
54 static int		 booted_bus, booted_unit;
55 static const char	*booted_controller;
56 
57 /*
58  * Configure all devices on system
59  */
60 void
61 cpu_configure(void)
62 {
63 	/* Kick off autoconfiguration. */
64 	(void)splhigh();
65 
66 	evcnt_attach_static(&emips_clock_evcnt);
67 	evcnt_attach_static(&emips_fpu_evcnt);
68 	evcnt_attach_static(&emips_memerr_evcnt);
69 
70 	if (config_rootfound("mainbus", NULL) == NULL)
71 		panic("no mainbus found");
72 
73 	/* Reset any bus errors due to probing nonexistent devices. */
74 	(*platform.bus_reset)();
75 
76 	/* Configuration is finished, turn on interrupts. */
77 	spl0();		/* enable all source forcing SOFT_INTs cleared */
78 }
79 
80 /*
81  * Look at the string 'cp' and decode the boot device.
82  * Boot names are something like '0/ace(0,0)/netbsd' or 'tftp()/nfsnetbsd'
83  * meaning: [BusNumber/]<ControllerName>([<DiskNumber>,<PartitionNumber])/<kernelname>
84  */
85 void
86 makebootdev(char *cp)
87 {
88     int i;
89     static char booted_controller_name[8];
90 
91 	booted_device = NULL;
92 	booted_bus = booted_unit = booted_partition = 0;
93 	booted_controller = NULL;
94 
95     if (*cp >= '0' && *cp <= '9') {
96         booted_bus = *cp++ - '0';
97         if (*cp == '/') cp++;
98     }
99 
100 	if (strncmp(cp, "tftp(", 5) == 0) {
101 		booted_controller = "BOOTP";
102 		goto out;
103 	}
104 
105     /* Stash away the controller name and use it later
106      */
107     for (i = 0; i < 7 && *cp && *cp != '('; i++)
108         booted_controller_name[i] = *cp++;
109     booted_controller_name[7] = 0; /* sanity */
110 
111     if (*cp == '(') cp++;
112     if (*cp >= '0' && *cp <= '9')
113         booted_unit = *cp++ - '0';
114 
115     if (*cp == ',') cp++;
116     if (*cp >= '0' && *cp <= '9')
117         booted_partition = *cp - '0';
118     booted_controller = booted_controller_name;
119 
120  out:
121 #if DEBUG
122     printf("bootdev: %d/%s(%d,%d)\n",booted_bus,booted_controller,booted_unit,booted_partition);
123 #endif
124     return;
125 }
126 
127 void
128 cpu_rootconf(void)
129 {
130 	printf("boot device: %s part%d\n",
131 	    booted_device ? booted_device->dv_xname : "<unknown>",
132            booted_partition);
133 
134 	setroot(booted_device, booted_partition);
135 }
136 
137 /*
138  * Try to determine the boot device.
139  */
140 void
141 device_register(struct device *dev,
142                 void *aux)
143 {
144 	static int found, initted, netboot;
145 	static struct device *ebusdev;
146 	struct device *parent = device_parent(dev);
147 
148 	if (found)
149 		return;
150 
151 #if 0
152     printf("\n[device_register(%s,%d) class %d]\n", dev->dv_xname, dev->dv_unit, dev->dv_class);
153 #endif
154 
155 	if (!initted) {
156 		netboot = (strcmp(booted_controller, "BOOTP") == 0);
157 		initted = 1;
158 	}
159 
160 	/*
161 	 * Remember the EBUS
162 	 */
163 	if (device_is_a(dev, "ebus")) {
164         ebusdev = dev;
165 		return;
166 	}
167 
168 	/*
169 	 * Check if netbooting.
170 	 */
171 	if (netboot) {
172 
173         /* Only one Ethernet interface (on ebus). */
174 		if ((parent == ebusdev)
175 		    && device_is_a(dev, "enic")) {
176 			booted_device = dev;
177 			found = 1;
178 			return;
179 		}
180 
181 		/* allow any network adapter */
182 		if (device_class(dev) == DV_IFNET &&
183 		    device_is_a(parent, "ebus")) {
184 			booted_device = dev;
185 			found = 1;
186 			return;
187 		}
188 
189         /* The NIC might be found after the disk, so bail out here */
190         return;
191 	}
192 
193     /* BUGBUG How would I get to the bus */
194     if (device_is_a(dev,booted_controller) && (dev->dv_unit == booted_unit)) {
195         booted_device = dev;
196         found = 1;
197         return;
198     }
199 
200 }
201