1 /* $NetBSD: autoconf.c,v 1.6 2012/07/29 18:05:47 mlelstv 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.6 2012/07/29 18:05:47 mlelstv 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
cpu_configure(void)61 cpu_configure(void)
62 {
63
64 /* Kick off autoconfiguration. */
65 (void)splhigh();
66
67 /* Interrupt initialization. */
68 intr_init();
69
70 evcnt_attach_static(&emips_clock_evcnt);
71 evcnt_attach_static(&emips_fpu_evcnt);
72 evcnt_attach_static(&emips_memerr_evcnt);
73
74 if (config_rootfound("mainbus", NULL) == NULL)
75 panic("no mainbus found");
76
77 /* Reset any bus errors due to probing nonexistent devices. */
78 (*platform.bus_reset)();
79
80 /* Configuration is finished, turn on interrupts. */
81 spl0(); /* enable all source forcing SOFT_INTs cleared */
82 }
83
84 /*
85 * Look at the string 'cp' and decode the boot device.
86 * Boot names are something like '0/ace(0,0)/netbsd' or 'tftp()/nfsnetbsd'
87 * meaning:
88 * [BusNumber/]<ControllerName>([<DiskNumber>,<PartitionNumber])/<kernelname>
89 */
90 void
makebootdev(char * cp)91 makebootdev(char *cp)
92 {
93 int i;
94 static char booted_controller_name[8];
95
96 booted_device = NULL;
97 booted_bus = booted_unit = booted_partition = 0;
98 booted_controller = NULL;
99
100 if (*cp >= '0' && *cp <= '9') {
101 booted_bus = *cp++ - '0';
102 if (*cp == '/')
103 cp++;
104 }
105
106 if (strncmp(cp, "tftp(", 5) == 0) {
107 booted_controller = "BOOTP";
108 goto out;
109 }
110
111 /*
112 * Stash away the controller name and use it later
113 */
114 for (i = 0; i < 7 && *cp && *cp != '('; i++)
115 booted_controller_name[i] = *cp++;
116 booted_controller_name[7] = 0; /* sanity */
117
118 if (*cp == '(')
119 cp++;
120 if (*cp >= '0' && *cp <= '9')
121 booted_unit = *cp++ - '0';
122
123 if (*cp == ',')
124 cp++;
125 if (*cp >= '0' && *cp <= '9')
126 booted_partition = *cp - '0';
127 booted_controller = booted_controller_name;
128
129 out:
130 #if DEBUG
131 printf("bootdev: %d/%s(%d,%d)\n",
132 booted_bus, booted_controller, booted_unit, booted_partition);
133 #endif
134 return;
135 }
136
137 void
cpu_rootconf(void)138 cpu_rootconf(void)
139 {
140
141 printf("boot device: %s part%d\n",
142 booted_device ? device_xname(booted_device) : "<unknown>",
143 booted_partition);
144
145 rootconf();
146 }
147
148 /*
149 * Try to determine the boot device.
150 */
151 void
device_register(device_t dev,void * aux)152 device_register(device_t dev, void *aux)
153 {
154 static int found, initted, netboot;
155 static device_t ebusdev;
156 device_t parent = device_parent(dev);
157
158 if (found)
159 return;
160
161 #if 0
162 printf("\n[device_register(%s,%d) class %d]\n",
163 device_xname(dev), device_unit(dev), device_class(dev));
164 #endif
165
166 if (!initted) {
167 netboot = (strcmp(booted_controller, "BOOTP") == 0);
168 initted = 1;
169 }
170
171 /*
172 * Remember the EBUS
173 */
174 if (device_is_a(dev, "ebus")) {
175 ebusdev = dev;
176 return;
177 }
178
179 /*
180 * Check if netbooting.
181 */
182 if (netboot) {
183
184 /* Only one Ethernet interface (on ebus). */
185 if ((parent == ebusdev) &&
186 device_is_a(dev, "enic")) {
187 booted_device = dev;
188 found = 1;
189 return;
190 }
191
192 /* allow any network adapter */
193 if (device_class(dev) == DV_IFNET &&
194 device_is_a(parent, "ebus")) {
195 booted_device = dev;
196 found = 1;
197 return;
198 }
199
200 /* The NIC might be found after the disk, so bail out here */
201 return;
202 }
203
204 /* BUGBUG How would I get to the bus */
205 if (device_is_a(dev, booted_controller) &&
206 (device_unit(dev) == booted_unit)) {
207 booted_device = dev;
208 found = 1;
209 return;
210 }
211 }
212