]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/alpha/alpha/autoconf.c
This commit was generated by cvs2svn to compensate for changes in r45410,
[FreeBSD/FreeBSD.git] / sys / alpha / alpha / autoconf.c
1 /*-
2  * Copyright (c) 1998 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      $Id: autoconf.c,v 1.14 1999/03/12 14:44:46 gallatin Exp $
27  */
28
29 #include "opt_bootp.h"
30 #include "opt_ffs.h"
31 #include "opt_cd9660.h"
32 #include "opt_mfs.h"
33 #include "opt_nfsroot.h"
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/conf.h>
38 #include <sys/disklabel.h>
39 #include <sys/diskslice.h> /* for BASE_SLICE, MAX_SLICES */
40 #include <sys/reboot.h>
41 #include <sys/kernel.h>
42 #include <sys/mount.h>
43 #include <sys/sysctl.h>
44 #include <sys/bus.h>
45 #include <sys/devicestat.h>
46
47 #include <machine/cons.h>
48 #include <machine/ipl.h>
49 #include <machine/md_var.h>
50 #include <machine/cpuconf.h>
51 #include <machine/rpb.h>
52 #include <machine/bootinfo.h>
53
54 #include <cam/cam.h>
55 #include <cam/cam_ccb.h>
56 #include <cam/cam_sim.h>
57 #include <cam/cam_periph.h>
58 #include <cam/cam_xpt_sim.h>
59 #include <cam/cam_debug.h>
60
61 static void     configure __P((void *));
62 SYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_THIRD, configure, NULL)
63
64 static void     configure_finish __P((void));
65 static void     configure_start __P((void));
66 static int      setdumpdev __P((dev_t dev));
67
68 device_t        isa_bus_device = 0;
69 struct cam_sim *boot_sim = 0;
70
71 static void
72 configure_start()
73 {
74 }
75
76 static void
77 configure_finish()
78 {
79 }
80
81 extern void pci_configure(void);
82
83 static int
84 atoi(const char *s)
85 {
86     int n = 0;
87     while (*s >= '0' && *s <= '9')
88         n = n * 10 + (*s++ - '0');
89     return n;
90 }
91
92 static const char *
93 bootdev_field(int which)
94 {
95         char *p = bootinfo.booted_dev;
96         char *q;
97         static char field[128];
98
99         /* Skip characters to find the right field */
100         for (; which; which--) {
101                 while (*p != ' ' && *p != '\0')
102                         p++;
103                 if (*p)
104                         p++;
105         }
106
107         /* Copy out the field and return it */
108         q = field;
109         while (*p != ' ' && *p != '\0')
110                 *q++ = *p++;
111         *q = '\0';
112
113         return field;
114 }
115
116 static const char *
117 bootdev_protocol(void)
118 {
119         return bootdev_field(0);
120 }
121
122 static int
123 bootdev_slot(void)
124 {
125         return atoi(bootdev_field(2));
126 }
127
128 static int
129 bootdev_unit(void)
130 {
131         return atoi(bootdev_field(5));
132 }
133
134 #if 0
135
136 static int
137 bootdev_bus(void)
138 {
139         return atoi(bootdev_field(1));
140 }
141
142 static int
143 bootdev_channel(void)
144 {
145         return atoi(bootdev_field(3));
146 }
147
148 static const char *
149 bootdev_remote_address(void)
150 {
151         return bootdev_field(4);
152 }
153
154 static int
155 bootdev_boot_dev_type(void)
156 {
157         return atoi(bootdev_field(6));
158 }
159
160 static const char *
161 bootdev_ctrl_dev_type(void)
162 {
163         return bootdev_field(7);
164 }
165
166 #endif
167
168 void
169 alpha_register_pci_scsi(int bus, int slot, struct cam_sim *sim)
170 {
171         if (!strcmp(bootdev_protocol(), "SCSI")) {
172                 int boot_slot = bootdev_slot();
173                 if (bus == boot_slot / 1000
174                     && slot == boot_slot % 1000)
175                         boot_sim = sim;
176         }
177 }
178
179 /*
180  * Determine i/o configuration for a machine.
181  */
182 static void
183 configure(void *dummy)
184 {
185         configure_start();
186
187         device_add_child(root_bus, platform.iobus, 0, 0);
188
189         root_bus_configure();
190
191         if((hwrpb->rpb_type != ST_DEC_3000_300) &&
192            (hwrpb->rpb_type != ST_DEC_3000_500)){
193                 pci_configure();
194
195                 /*
196                  * Probe ISA devices after everything.
197                  */
198                 if (isa_bus_device)
199                         bus_generic_attach(isa_bus_device);
200         } 
201         configure_finish();
202
203         cninit_finish();
204
205         /*
206          * Now we're ready to handle (pending) interrupts.
207          * XXX this is slightly misplaced.
208          */
209         spl0();
210
211         cold = 0;
212 }
213
214 void
215 cpu_rootconf()
216 {
217 #ifdef MFS_ROOT
218         if (!mountrootfsname) {
219                 extern u_char *mfs_getimage __P((void));
220
221                 if (bootverbose)
222                         printf("Considering MFS root f/s.\n");
223                 if (mfs_getimage())
224                         mountrootfsname = "mfs";
225                 else if (bootverbose)
226                         printf("No MFS image available as root f/s.\n");
227         }
228 #endif
229
230 #if defined(FFS) || defined(FFS_ROOT)
231         if (!mountrootfsname) {
232                 static char rootname[] = "da0a";
233
234                 if (bootverbose)
235                         printf("Considering UFS root f/s.\n");
236                 mountrootfsname = "ufs";
237
238                 if (boot_sim) {
239                         struct cam_path *path;
240                         struct cam_periph *periph;
241             
242                         xpt_create_path(&path, NULL,
243                                         cam_sim_path(boot_sim),
244                                         bootdev_unit() / 100, 0);
245                         periph = cam_periph_find(path, "da");
246
247                         if (periph)
248                                 rootdev = makedev(4, dkmakeminor(periph->unit_number,
249                                                                  COMPATIBILITY_SLICE, 0));
250
251                         xpt_free_path(path);
252                 }
253
254                 rootdevs[0] = rootdev;
255                 rootname[2] += dkunit(minor(rootdev));
256                 rootdevnames[0] = rootname;
257         }
258 #endif
259 }
260
261 void
262 cpu_dumpconf()
263 {
264         if (setdumpdev(dumpdev) != 0)
265                 dumpdev = NODEV;
266 }
267
268 static int
269 setdumpdev(dev)
270         dev_t dev;
271 {
272         int maj, psize;
273         long newdumplo;
274
275         if (dev == NODEV) {
276                 dumpdev = dev;
277                 return (0);
278         }
279         maj = major(dev);
280         if (maj >= nblkdev || bdevsw[maj] == NULL)
281                 return (ENXIO);         /* XXX is this right? */
282         if (bdevsw[maj]->d_psize == NULL)
283                 return (ENXIO);         /* XXX should be ENODEV ? */
284         psize = bdevsw[maj]->d_psize(dev);
285         if (psize == -1)
286                 return (ENXIO);         /* XXX should be ENODEV ? */
287         /*
288          * XXX should clean up checking in dumpsys() to be more like this,
289          * and nuke dodump sysctl (too many knobs), and move this to
290          * kern_shutdown.c...
291          */
292         newdumplo = psize - Maxmem * PAGE_SIZE / DEV_BSIZE;
293         if (newdumplo < 0)
294                 return (ENOSPC);
295         dumpdev = dev;
296         dumplo = newdumplo;
297         return (0);
298 }
299
300 static int
301 sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS
302 {
303         int error;
304         dev_t ndumpdev;
305
306         ndumpdev = dumpdev;
307         error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req);
308         if (error == 0 && req->newptr != NULL)
309                 error = setdumpdev(ndumpdev);
310         return (error);
311 }
312
313 SYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW,
314             0, sizeof dumpdev, sysctl_kern_dumpdev, "T,dev_t", "");