1 1.20 joerg /* $NetBSD: boot.c,v 1.20 2011/01/22 19:19:16 joerg 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.11 tsutsui printf(">> Model:\t\t%s\n", cobalt_model[cobalt_id]); 381 1.18 matt printf(">> Memory:\t\t%lu k\n", (memsize - MIPS_KSEG0_START) / 1024); 382 1.1 cdi printf(">> PROM boot string:\t%s\n", bootstring); 383 1.1 cdi } 384 1.1 cdi 385 1.11 tsutsui u_int 386 1.11 tsutsui read_board_id(void) 387 1.11 tsutsui { 388 1.12 tsutsui uint32_t tag, reg; 389 1.11 tsutsui 390 1.11 tsutsui #define PCIB_PCI_BUS 0 391 1.11 tsutsui #define PCIB_PCI_DEV 9 392 1.11 tsutsui #define PCIB_PCI_FUNC 0 393 1.11 tsutsui #define PCIB_BOARD_ID_REG 0x94 394 1.11 tsutsui #define COBALT_BOARD_ID(reg) ((reg & 0x000000f0) >> 4) 395 1.11 tsutsui 396 1.12 tsutsui tag = (PCIB_PCI_BUS << 16) | (PCIB_PCI_DEV << 11) | 397 1.12 tsutsui (PCIB_PCI_FUNC << 8); 398 1.12 tsutsui reg = pcicfgread(tag, PCIB_BOARD_ID_REG); 399 1.11 tsutsui 400 1.11 tsutsui return COBALT_BOARD_ID(reg); 401 1.11 tsutsui } 402 1.11 tsutsui 403 1.1 cdi /* 404 1.1 cdi * Entry point. 405 1.1 cdi * Parse PROM boot string, load the kernel and jump into it 406 1.1 cdi */ 407 1.1 cdi int 408 1.6 tsutsui main(unsigned int memsize) 409 1.1 cdi { 410 1.4 tsutsui char **namep, *dev, *kernel, *bi_addr; 411 1.1 cdi char bootpath[PATH_MAX]; 412 1.1 cdi int win; 413 1.1 cdi u_long marks[MARK_MAX]; 414 1.6 tsutsui void (*entry)(unsigned int, u_int, char *); 415 1.3 cdi 416 1.3 cdi struct btinfo_flags bi_flags; 417 1.3 cdi struct btinfo_symtab bi_syms; 418 1.3 cdi struct btinfo_bootpath bi_bpath; 419 1.7 tsutsui struct btinfo_howto bi_howto; 420 1.10 tsutsui int addr, speed, howto; 421 1.1 cdi 422 1.10 tsutsui try_bootp = 1; 423 1.1 cdi 424 1.3 cdi /* Initialize boot info early */ 425 1.13 tsutsui dev = NULL; 426 1.13 tsutsui kernel = NULL; 427 1.7 tsutsui howto = 0x0; 428 1.3 cdi bi_flags.bi_flags = 0x0; 429 1.3 cdi bi_addr = bi_init(); 430 1.3 cdi 431 1.16 tsutsui lcd_init(); 432 1.11 tsutsui cobalt_id = read_board_id(); 433 1.1 cdi prominit(memsize); 434 1.3 cdi if (cninit(&addr, &speed) != NULL) 435 1.3 cdi bi_flags.bi_flags |= BI_SERIAL_CONSOLE; 436 1.1 cdi 437 1.1 cdi print_banner(memsize); 438 1.1 cdi 439 1.1 cdi memset(marks, 0, sizeof marks); 440 1.7 tsutsui get_bsdbootname(&dev, &kernel, &howto); 441 1.1 cdi 442 1.1 cdi if (kernel != NULL) { 443 1.1 cdi DPRINTF(("kernel: %s\n", kernel)); 444 1.4 tsutsui kernelnames[0] = kernel; 445 1.4 tsutsui kernelnames[1] = NULL; 446 1.1 cdi } else { 447 1.1 cdi DPRINTF(("kernel: NULL\n")); 448 1.4 tsutsui } 449 1.4 tsutsui 450 1.4 tsutsui win = 0; 451 1.4 tsutsui DPRINTF(("Kernel names: %p\n", kernelnames)); 452 1.4 tsutsui for (namep = kernelnames, win = 0; (*namep != NULL) && !win; namep++) { 453 1.4 tsutsui kernel = *namep; 454 1.4 tsutsui 455 1.4 tsutsui bootpath[0] = '\0'; 456 1.4 tsutsui 457 1.4 tsutsui strcpy(bootpath, dev ? dev : DEFBOOTDEV); 458 1.4 tsutsui strcat(bootpath, ":"); 459 1.4 tsutsui strcat(bootpath, kernel); 460 1.4 tsutsui 461 1.16 tsutsui lcd_loadfile(bootpath); 462 1.7 tsutsui printf("Loading: %s", bootpath); 463 1.7 tsutsui if (howto) 464 1.7 tsutsui printf(" (howto 0x%x)", howto); 465 1.7 tsutsui printf("\n"); 466 1.4 tsutsui patch_bootstring(bootpath); 467 1.4 tsutsui win = (loadfile(bootpath, marks, LOAD_ALL) != -1); 468 1.1 cdi } 469 1.1 cdi 470 1.1 cdi if (win) { 471 1.3 cdi strncpy(bi_bpath.bootpath, kernel, BTINFO_BOOTPATH_LEN); 472 1.3 cdi bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath)); 473 1.3 cdi 474 1.6 tsutsui entry = (void *)marks[MARK_ENTRY]; 475 1.3 cdi bi_syms.nsym = marks[MARK_NSYM]; 476 1.3 cdi bi_syms.ssym = marks[MARK_SYM]; 477 1.3 cdi bi_syms.esym = marks[MARK_END]; 478 1.3 cdi bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms)); 479 1.3 cdi 480 1.3 cdi bi_add(&bi_flags, BTINFO_FLAGS, sizeof(bi_flags)); 481 1.3 cdi 482 1.7 tsutsui bi_howto.bi_howto = howto; 483 1.7 tsutsui bi_add(&bi_howto, BTINFO_HOWTO, sizeof(bi_howto)); 484 1.7 tsutsui 485 1.6 tsutsui entry = (void *)marks[MARK_ENTRY]; 486 1.1 cdi 487 1.19 tsutsui DPRINTF(("Bootinfo @ 0x%lx\n", (u_long)bi_addr)); 488 1.19 tsutsui printf("Starting at 0x%lx\n\n", (u_long)entry); 489 1.3 cdi (*entry)(memsize, BOOTINFO_MAGIC, bi_addr); 490 1.1 cdi } 491 1.1 cdi 492 1.17 tsutsui delay(20000); 493 1.17 tsutsui lcd_failed(); 494 1.1 cdi (void)printf("Boot failed! Rebooting...\n"); 495 1.6 tsutsui return 0; 496 1.1 cdi } 497