boot.c revision 1.18 1 1.18 matt /* $NetBSD: boot.c,v 1.18 2009/12/16 19:01:24 matt Exp $ */
2 1.1 cdi
3 1.1 cdi /*-
4 1.1 cdi * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 1.1 cdi * All rights reserved.
6 1.1 cdi *
7 1.1 cdi * This code is derived from software contributed to The NetBSD Foundation
8 1.1 cdi * by Jonathan Stone, Michael Hitch, Simon Burge and Wayne Knowles.
9 1.1 cdi *
10 1.1 cdi * Redistribution and use in source and binary forms, with or without
11 1.1 cdi * modification, are permitted provided that the following conditions
12 1.1 cdi * are met:
13 1.1 cdi * 1. Redistributions of source code must retain the above copyright
14 1.1 cdi * notice, this list of conditions and the following disclaimer.
15 1.1 cdi * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 cdi * notice, this list of conditions and the following disclaimer in the
17 1.1 cdi * documentation and/or other materials provided with the distribution.
18 1.1 cdi *
19 1.1 cdi * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 cdi * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 cdi * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 cdi * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 cdi * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 cdi * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 cdi * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 cdi * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 cdi * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 cdi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 cdi * POSSIBILITY OF SUCH DAMAGE.
30 1.1 cdi */
31 1.1 cdi
32 1.1 cdi /*
33 1.1 cdi * Copyright (c) 1992, 1993
34 1.1 cdi * The Regents of the University of California. All rights reserved.
35 1.1 cdi *
36 1.1 cdi * This code is derived from software contributed to Berkeley by
37 1.1 cdi * Ralph Campbell.
38 1.1 cdi *
39 1.1 cdi * Redistribution and use in source and binary forms, with or without
40 1.1 cdi * modification, are permitted provided that the following conditions
41 1.1 cdi * are met:
42 1.1 cdi * 1. Redistributions of source code must retain the above copyright
43 1.1 cdi * notice, this list of conditions and the following disclaimer.
44 1.1 cdi * 2. Redistributions in binary form must reproduce the above copyright
45 1.1 cdi * notice, this list of conditions and the following disclaimer in the
46 1.1 cdi * documentation and/or other materials provided with the distribution.
47 1.2 agc * 3. Neither the name of the University nor the names of its contributors
48 1.1 cdi * may be used to endorse or promote products derived from this software
49 1.1 cdi * without specific prior written permission.
50 1.1 cdi *
51 1.1 cdi * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 1.1 cdi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 1.1 cdi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 1.1 cdi * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 1.1 cdi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 1.1 cdi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 1.1 cdi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 1.1 cdi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 1.1 cdi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 1.1 cdi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 1.1 cdi * SUCH DAMAGE.
62 1.1 cdi *
63 1.1 cdi * @(#)boot.c 8.1 (Berkeley) 6/10/93
64 1.1 cdi */
65 1.1 cdi
66 1.1 cdi #include <lib/libsa/stand.h>
67 1.1 cdi #include <lib/libsa/loadfile.h>
68 1.10 tsutsui #include <lib/libsa/dev_net.h>
69 1.1 cdi #include <lib/libkern/libkern.h>
70 1.1 cdi
71 1.1 cdi #include <sys/param.h>
72 1.4 tsutsui #include <sys/boot_flag.h>
73 1.1 cdi #include <sys/exec.h>
74 1.1 cdi #include <sys/exec_elf.h>
75 1.1 cdi
76 1.14 tsutsui #include <machine/cpu.h>
77 1.14 tsutsui
78 1.11 tsutsui #include <cobalt/dev/gtreg.h>
79 1.11 tsutsui
80 1.1 cdi #include "boot.h"
81 1.1 cdi #include "cons.h"
82 1.1 cdi #include "common.h"
83 1.3 cdi #include "bootinfo.h"
84 1.1 cdi
85 1.1 cdi char *kernelnames[] = {
86 1.1 cdi "netbsd",
87 1.1 cdi "netbsd.gz",
88 1.1 cdi "onetbsd",
89 1.1 cdi "onetbsd.gz",
90 1.1 cdi "netbsd.bak",
91 1.1 cdi "netbsd.bak.gz",
92 1.1 cdi "netbsd.old",
93 1.1 cdi "netbsd.old.gz",
94 1.1 cdi "netbsd.cobalt",
95 1.1 cdi "netbsd.cobalt.gz",
96 1.1 cdi "netbsd.elf",
97 1.1 cdi "netbsd.elf.gz",
98 1.1 cdi NULL
99 1.1 cdi };
100 1.1 cdi
101 1.11 tsutsui u_int cobalt_id;
102 1.11 tsutsui static const char * const cobalt_model[] =
103 1.11 tsutsui {
104 1.11 tsutsui [0] = "Unknown Cobalt",
105 1.11 tsutsui [COBALT_ID_QUBE2700] = "Cobalt Qube 2700",
106 1.11 tsutsui [COBALT_ID_RAQ] = "Cobalt RaQ",
107 1.11 tsutsui [COBALT_ID_QUBE2] = "Cobalt Qube 2",
108 1.11 tsutsui [COBALT_ID_RAQ2] = "Cobalt RaQ 2"
109 1.11 tsutsui };
110 1.11 tsutsui #define COBALT_MODELS __arraycount(cobalt_model)
111 1.11 tsutsui
112 1.3 cdi extern u_long end; /* Boot loader code end address */
113 1.3 cdi void start(void);
114 1.3 cdi
115 1.1 cdi static char *bootstring;
116 1.1 cdi
117 1.10 tsutsui static int patch_bootstring(char *bootspec);
118 1.7 tsutsui static int get_bsdbootname(char **, char **, int *);
119 1.4 tsutsui static int parse_bootname(char *, int, char **, char **);
120 1.10 tsutsui static void prominit(unsigned int memsize);
121 1.10 tsutsui static void print_banner(unsigned int memsize);
122 1.11 tsutsui static u_int read_board_id(void);
123 1.1 cdi
124 1.10 tsutsui void cpu_reboot(void);
125 1.3 cdi
126 1.1 cdi int main(unsigned int memsize);
127 1.1 cdi
128 1.1 cdi /*
129 1.1 cdi * Perform CPU reboot.
130 1.1 cdi */
131 1.10 tsutsui void
132 1.6 tsutsui cpu_reboot(void)
133 1.1 cdi {
134 1.10 tsutsui
135 1.1 cdi printf("rebooting...\n\n");
136 1.1 cdi
137 1.6 tsutsui *(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(LED_ADDR) = LED_RESET;
138 1.1 cdi printf("WARNING: reboot failed!\n");
139 1.1 cdi
140 1.6 tsutsui for (;;)
141 1.6 tsutsui ;
142 1.1 cdi }
143 1.1 cdi
144 1.1 cdi /*
145 1.1 cdi * Substitute root value with NetBSD root partition name.
146 1.1 cdi */
147 1.1 cdi int
148 1.6 tsutsui patch_bootstring(char *bootspec)
149 1.1 cdi {
150 1.1 cdi char *sp = bootstring;
151 1.6 tsutsui uint8_t unit, part;
152 1.10 tsutsui int dev;
153 1.1 cdi char *file;
154 1.1 cdi
155 1.1 cdi DPRINTF(("patch_bootstring: %s\n", bootspec));
156 1.1 cdi
157 1.1 cdi /* get boot parameters */
158 1.1 cdi if (devparse(bootspec, &dev, &unit, &part, (const char **)&file) != 0)
159 1.1 cdi unit = part = 0;
160 1.1 cdi
161 1.10 tsutsui DPRINTF(("patch_bootstring: unit = %d, part = %d\n", unit, part));
162 1.1 cdi
163 1.1 cdi /* take out the 'root=xxx' parameter */
164 1.6 tsutsui if ((sp = strstr(bootstring, "root=")) != NULL) {
165 1.1 cdi const char *end;
166 1.1 cdi
167 1.1 cdi end = strchr(sp, ' ');
168 1.1 cdi
169 1.1 cdi /* strip off leading spaces */
170 1.1 cdi for (--sp; (sp > bootstring) && (*sp == ' '); --sp)
171 1.1 cdi ;
172 1.1 cdi
173 1.1 cdi if (end != NULL)
174 1.1 cdi strcpy(++sp, end);
175 1.1 cdi else
176 1.1 cdi *++sp = '\0';
177 1.1 cdi }
178 1.1 cdi
179 1.1 cdi DPRINTF(("patch_bootstring: [%s]\n", bootstring));
180 1.1 cdi
181 1.1 cdi #define DEVNAMESIZE (MAXDEVNAME + sizeof(" root=/dev/hd") + sizeof("0a"))
182 1.10 tsutsui if (strcmp(devsw[dev].dv_name, "wd") == 0 &&
183 1.10 tsutsui strlen(bootstring) <= (511 - DEVNAMESIZE)) {
184 1.1 cdi int len;
185 1.1 cdi
186 1.10 tsutsui /* omit "nfsroot=" arg on wd boot */
187 1.10 tsutsui if ((sp = strstr(bootstring, "nfsroot=")) != NULL) {
188 1.10 tsutsui const char *end;
189 1.10 tsutsui
190 1.10 tsutsui end = strchr(sp, ' ');
191 1.10 tsutsui
192 1.10 tsutsui /* strip off leading spaces */
193 1.10 tsutsui for (--sp; (sp > bootstring) && (*sp == ' '); --sp)
194 1.10 tsutsui ;
195 1.10 tsutsui
196 1.10 tsutsui if (end != NULL)
197 1.10 tsutsui strcpy(++sp, end);
198 1.10 tsutsui else
199 1.10 tsutsui *++sp = '\0';
200 1.10 tsutsui }
201 1.10 tsutsui
202 1.10 tsutsui /* bsd notation -> linux notation (wd0a -> hda1) */
203 1.1 cdi strcat(bootstring, " root=/dev/hd");
204 1.1 cdi
205 1.1 cdi len = strlen(bootstring);
206 1.1 cdi bootstring[len++] = unit + 'a';
207 1.1 cdi bootstring[len++] = part + '1';
208 1.1 cdi bootstring[len++] = '\0';
209 1.1 cdi }
210 1.1 cdi
211 1.1 cdi DPRINTF(("patch_bootstring: -> %s\n", bootstring));
212 1.6 tsutsui return 0;
213 1.1 cdi }
214 1.1 cdi
215 1.1 cdi /*
216 1.1 cdi * Extract NetBSD boot specification
217 1.1 cdi */
218 1.4 tsutsui static int
219 1.7 tsutsui get_bsdbootname(char **dev, char **kname, int *howtop)
220 1.1 cdi {
221 1.10 tsutsui int len;
222 1.8 tsutsui int bootunit, bootpart;
223 1.4 tsutsui char *bootstr_dev, *bootstr_kname;
224 1.4 tsutsui char *prompt_dev, *prompt_kname;
225 1.4 tsutsui char *ptr, *spec;
226 1.4 tsutsui char c, namebuf[PATH_MAX];
227 1.8 tsutsui static char bootdev[] = "wd0a";
228 1.10 tsutsui static char nfsbootdev[] = "nfs";
229 1.4 tsutsui
230 1.4 tsutsui bootstr_dev = prompt_dev = NULL;
231 1.4 tsutsui bootstr_kname = prompt_kname = NULL;
232 1.4 tsutsui
233 1.8 tsutsui /* first, get root device specified by the firmware */
234 1.8 tsutsui spec = bootstring;
235 1.10 tsutsui
236 1.8 tsutsui /* assume the last one is valid */
237 1.8 tsutsui while ((spec = strstr(spec, "root=")) != NULL) {
238 1.8 tsutsui spec += 5; /* skip 'root=' */
239 1.8 tsutsui ptr = strchr(spec, ' ');
240 1.8 tsutsui len = (ptr == NULL) ? strlen(spec) : ptr - spec;
241 1.8 tsutsui /* decode unit and part from "/dev/hd[ab][1-4]" strings */
242 1.8 tsutsui if (len == 9 && memcmp("/dev/hd", spec, 7) == 0) {
243 1.8 tsutsui bootunit = spec[7] - 'a';
244 1.8 tsutsui bootpart = spec[8] - '1';
245 1.8 tsutsui if (bootunit >= 0 && bootunit < 2 &&
246 1.8 tsutsui bootpart >= 0 && bootpart < 4) {
247 1.8 tsutsui bootdev[sizeof(bootdev) - 3] = '0' + bootunit;
248 1.8 tsutsui #if 0 /* bootpart is fdisk partition of Linux root */
249 1.8 tsutsui bootdev[sizeof(bootdev) - 2] = 'a' + bootpart;
250 1.8 tsutsui #endif
251 1.8 tsutsui bootstr_dev = bootdev;
252 1.8 tsutsui }
253 1.8 tsutsui }
254 1.8 tsutsui spec += len;
255 1.8 tsutsui }
256 1.8 tsutsui
257 1.8 tsutsui /* second, get bootname from bootstrings */
258 1.4 tsutsui if ((spec = strstr(bootstring, "nbsd=")) != NULL) {
259 1.4 tsutsui ptr = strchr(spec, ' ');
260 1.1 cdi spec += 5; /* skip 'nbsd=' */
261 1.1 cdi len = (ptr == NULL) ? strlen(spec) : ptr - spec;
262 1.4 tsutsui if (len > 0) {
263 1.4 tsutsui if (parse_bootname(spec, len,
264 1.4 tsutsui &bootstr_dev, &bootstr_kname))
265 1.4 tsutsui return 1;
266 1.4 tsutsui }
267 1.4 tsutsui }
268 1.1 cdi
269 1.10 tsutsui /* third, check if netboot */
270 1.10 tsutsui if (strstr(bootstring, "nfsroot=") != NULL) {
271 1.10 tsutsui bootstr_dev = nfsbootdev;
272 1.10 tsutsui }
273 1.10 tsutsui
274 1.4 tsutsui DPRINTF(("bootstr_dev = %s, bootstr_kname = %s\n",
275 1.4 tsutsui bootstr_dev ? bootstr_dev : "<NULL>",
276 1.4 tsutsui bootstr_kname ? bootstr_kname : "<NULL>"));
277 1.4 tsutsui
278 1.4 tsutsui spec = NULL;
279 1.4 tsutsui len = 0;
280 1.4 tsutsui
281 1.4 tsutsui memset(namebuf, 0, sizeof namebuf);
282 1.4 tsutsui printf("Boot [%s:%s]: ",
283 1.4 tsutsui bootstr_dev ? bootstr_dev : DEFBOOTDEV,
284 1.4 tsutsui bootstr_kname ? bootstr_kname : DEFKERNELNAME);
285 1.4 tsutsui
286 1.4 tsutsui if (tgets(namebuf) == -1)
287 1.4 tsutsui printf("\n");
288 1.4 tsutsui
289 1.4 tsutsui ptr = namebuf;
290 1.4 tsutsui while ((c = *ptr) != '\0') {
291 1.4 tsutsui while (c == ' ')
292 1.4 tsutsui c = *++ptr;
293 1.4 tsutsui if (c == '\0')
294 1.4 tsutsui break;
295 1.4 tsutsui if (c == '-') {
296 1.4 tsutsui while ((c = *++ptr) && c != ' ')
297 1.7 tsutsui BOOT_FLAG(c, *howtop);
298 1.4 tsutsui } else {
299 1.4 tsutsui spec = ptr;
300 1.4 tsutsui while ((c = *++ptr) && c != ' ')
301 1.4 tsutsui ;
302 1.4 tsutsui if (c)
303 1.4 tsutsui *ptr++ = '\0';
304 1.4 tsutsui len = strlen(spec);
305 1.1 cdi }
306 1.1 cdi }
307 1.1 cdi
308 1.4 tsutsui if (len > 0) {
309 1.4 tsutsui if (parse_bootname(spec, len, &prompt_dev, &prompt_kname))
310 1.4 tsutsui return 1;
311 1.4 tsutsui }
312 1.4 tsutsui
313 1.4 tsutsui DPRINTF(("prompt_dev = %s, prompt_kname = %s\n",
314 1.4 tsutsui prompt_dev ? prompt_dev : "<NULL>",
315 1.4 tsutsui prompt_kname ? prompt_kname : "<NULL>"));
316 1.4 tsutsui
317 1.4 tsutsui if (prompt_dev)
318 1.4 tsutsui *dev = prompt_dev;
319 1.4 tsutsui else
320 1.4 tsutsui *dev = bootstr_dev;
321 1.4 tsutsui
322 1.4 tsutsui if (prompt_kname)
323 1.4 tsutsui *kname = prompt_kname;
324 1.4 tsutsui else
325 1.4 tsutsui *kname = bootstr_kname;
326 1.4 tsutsui
327 1.4 tsutsui DPRINTF(("dev = %s, kname = %s\n",
328 1.4 tsutsui *dev ? *dev : "<NULL>",
329 1.4 tsutsui *kname ? *kname : "<NULL>"));
330 1.4 tsutsui
331 1.4 tsutsui return 0;
332 1.4 tsutsui }
333 1.4 tsutsui
334 1.4 tsutsui static int
335 1.6 tsutsui parse_bootname(char *spec, int len, char **dev, char **kname)
336 1.4 tsutsui {
337 1.4 tsutsui char *bootname, *ptr;
338 1.4 tsutsui
339 1.4 tsutsui bootname = alloc(len + 1);
340 1.4 tsutsui if (bootname == NULL)
341 1.4 tsutsui return 1;
342 1.4 tsutsui memcpy(bootname, spec, len);
343 1.4 tsutsui bootname[len] = '\0';
344 1.4 tsutsui
345 1.4 tsutsui if ((ptr = memchr(bootname, ':', len)) != NULL) {
346 1.4 tsutsui /* "wdXX:kernel" */
347 1.4 tsutsui *ptr = '\0';
348 1.4 tsutsui *dev = bootname;
349 1.4 tsutsui if (*++ptr)
350 1.4 tsutsui *kname = ptr;
351 1.4 tsutsui } else
352 1.4 tsutsui /* "kernel" */
353 1.4 tsutsui *kname = bootname;
354 1.4 tsutsui return 0;
355 1.1 cdi }
356 1.1 cdi
357 1.1 cdi /*
358 1.1 cdi * Get the bootstring from PROM.
359 1.1 cdi */
360 1.10 tsutsui void
361 1.6 tsutsui prominit(unsigned int memsize)
362 1.1 cdi {
363 1.6 tsutsui
364 1.1 cdi bootstring = (char *)(memsize - 512);
365 1.1 cdi bootstring[511] = '\0';
366 1.1 cdi }
367 1.1 cdi
368 1.1 cdi /*
369 1.1 cdi * Print boot message.
370 1.1 cdi */
371 1.10 tsutsui void
372 1.6 tsutsui print_banner(unsigned int memsize)
373 1.1 cdi {
374 1.6 tsutsui
375 1.16 tsutsui lcd_banner();
376 1.16 tsutsui
377 1.1 cdi printf("\n");
378 1.1 cdi printf(">> %s " NETBSD_VERS " Bootloader, Revision %s [@%p]\n",
379 1.3 cdi bootprog_name, bootprog_rev, (void*)&start);
380 1.1 cdi printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
381 1.11 tsutsui printf(">> Model:\t\t%s\n", cobalt_model[cobalt_id]);
382 1.18 matt printf(">> Memory:\t\t%lu k\n", (memsize - MIPS_KSEG0_START) / 1024);
383 1.1 cdi printf(">> PROM boot string:\t%s\n", bootstring);
384 1.1 cdi }
385 1.1 cdi
386 1.11 tsutsui u_int
387 1.11 tsutsui read_board_id(void)
388 1.11 tsutsui {
389 1.12 tsutsui uint32_t tag, reg;
390 1.11 tsutsui
391 1.11 tsutsui #define PCIB_PCI_BUS 0
392 1.11 tsutsui #define PCIB_PCI_DEV 9
393 1.11 tsutsui #define PCIB_PCI_FUNC 0
394 1.11 tsutsui #define PCIB_BOARD_ID_REG 0x94
395 1.11 tsutsui #define COBALT_BOARD_ID(reg) ((reg & 0x000000f0) >> 4)
396 1.11 tsutsui
397 1.12 tsutsui tag = (PCIB_PCI_BUS << 16) | (PCIB_PCI_DEV << 11) |
398 1.12 tsutsui (PCIB_PCI_FUNC << 8);
399 1.12 tsutsui reg = pcicfgread(tag, PCIB_BOARD_ID_REG);
400 1.11 tsutsui
401 1.11 tsutsui return COBALT_BOARD_ID(reg);
402 1.11 tsutsui }
403 1.11 tsutsui
404 1.1 cdi /*
405 1.1 cdi * Entry point.
406 1.1 cdi * Parse PROM boot string, load the kernel and jump into it
407 1.1 cdi */
408 1.1 cdi int
409 1.6 tsutsui main(unsigned int memsize)
410 1.1 cdi {
411 1.4 tsutsui char **namep, *dev, *kernel, *bi_addr;
412 1.1 cdi char bootpath[PATH_MAX];
413 1.1 cdi int win;
414 1.1 cdi u_long marks[MARK_MAX];
415 1.6 tsutsui void (*entry)(unsigned int, u_int, char *);
416 1.3 cdi
417 1.3 cdi struct btinfo_flags bi_flags;
418 1.3 cdi struct btinfo_symtab bi_syms;
419 1.3 cdi struct btinfo_bootpath bi_bpath;
420 1.7 tsutsui struct btinfo_howto bi_howto;
421 1.10 tsutsui int addr, speed, howto;
422 1.1 cdi
423 1.10 tsutsui try_bootp = 1;
424 1.1 cdi
425 1.3 cdi /* Initialize boot info early */
426 1.13 tsutsui dev = NULL;
427 1.13 tsutsui kernel = NULL;
428 1.7 tsutsui howto = 0x0;
429 1.3 cdi bi_flags.bi_flags = 0x0;
430 1.3 cdi bi_addr = bi_init();
431 1.3 cdi
432 1.16 tsutsui lcd_init();
433 1.11 tsutsui cobalt_id = read_board_id();
434 1.1 cdi prominit(memsize);
435 1.3 cdi if (cninit(&addr, &speed) != NULL)
436 1.3 cdi bi_flags.bi_flags |= BI_SERIAL_CONSOLE;
437 1.1 cdi
438 1.1 cdi print_banner(memsize);
439 1.1 cdi
440 1.1 cdi memset(marks, 0, sizeof marks);
441 1.7 tsutsui get_bsdbootname(&dev, &kernel, &howto);
442 1.1 cdi
443 1.1 cdi if (kernel != NULL) {
444 1.1 cdi DPRINTF(("kernel: %s\n", kernel));
445 1.4 tsutsui kernelnames[0] = kernel;
446 1.4 tsutsui kernelnames[1] = NULL;
447 1.1 cdi } else {
448 1.1 cdi DPRINTF(("kernel: NULL\n"));
449 1.4 tsutsui }
450 1.4 tsutsui
451 1.4 tsutsui win = 0;
452 1.4 tsutsui DPRINTF(("Kernel names: %p\n", kernelnames));
453 1.4 tsutsui for (namep = kernelnames, win = 0; (*namep != NULL) && !win; namep++) {
454 1.4 tsutsui kernel = *namep;
455 1.4 tsutsui
456 1.4 tsutsui bootpath[0] = '\0';
457 1.4 tsutsui
458 1.4 tsutsui strcpy(bootpath, dev ? dev : DEFBOOTDEV);
459 1.4 tsutsui strcat(bootpath, ":");
460 1.4 tsutsui strcat(bootpath, kernel);
461 1.4 tsutsui
462 1.16 tsutsui lcd_loadfile(bootpath);
463 1.7 tsutsui printf("Loading: %s", bootpath);
464 1.7 tsutsui if (howto)
465 1.7 tsutsui printf(" (howto 0x%x)", howto);
466 1.7 tsutsui printf("\n");
467 1.4 tsutsui patch_bootstring(bootpath);
468 1.4 tsutsui win = (loadfile(bootpath, marks, LOAD_ALL) != -1);
469 1.1 cdi }
470 1.1 cdi
471 1.1 cdi if (win) {
472 1.3 cdi strncpy(bi_bpath.bootpath, kernel, BTINFO_BOOTPATH_LEN);
473 1.3 cdi bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath));
474 1.3 cdi
475 1.6 tsutsui entry = (void *)marks[MARK_ENTRY];
476 1.3 cdi bi_syms.nsym = marks[MARK_NSYM];
477 1.3 cdi bi_syms.ssym = marks[MARK_SYM];
478 1.3 cdi bi_syms.esym = marks[MARK_END];
479 1.3 cdi bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms));
480 1.3 cdi
481 1.3 cdi bi_add(&bi_flags, BTINFO_FLAGS, sizeof(bi_flags));
482 1.3 cdi
483 1.7 tsutsui bi_howto.bi_howto = howto;
484 1.7 tsutsui bi_add(&bi_howto, BTINFO_HOWTO, sizeof(bi_howto));
485 1.7 tsutsui
486 1.6 tsutsui entry = (void *)marks[MARK_ENTRY];
487 1.1 cdi
488 1.3 cdi DPRINTF(("Bootinfo @ 0x%x\n", bi_addr));
489 1.1 cdi printf("Starting at 0x%x\n\n", (u_int)entry);
490 1.3 cdi (*entry)(memsize, BOOTINFO_MAGIC, bi_addr);
491 1.1 cdi }
492 1.1 cdi
493 1.17 tsutsui delay(20000);
494 1.17 tsutsui lcd_failed();
495 1.1 cdi (void)printf("Boot failed! Rebooting...\n");
496 1.6 tsutsui return 0;
497 1.1 cdi }
498