1 /* $NetBSD: bootxx.c,v 1.23 2009/03/23 13:47:32 tsutsui Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Paul Kranenburg. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/param.h> 33 #include <sys/exec.h> 34 #include <sys/bootblock.h> 35 36 #include <lib/libkern/libkern.h> 37 #include <lib/libsa/stand.h> 38 39 #include <machine/promlib.h> 40 #include <sparc/stand/common/promdev.h> 41 42 int debug; 43 int netif_debug; 44 45 /* 46 * Boot device is derived from ROM provided information. 47 */ 48 const char progname[] = "bootxx"; 49 struct open_file io; 50 51 /* 52 * The contents of the bbinfo below are set by installboot(8) 53 * to hold the filesystem data of the second-stage boot program 54 * (typically `/boot'): filesystem block size, # of filesystem 55 * blocks and the block numbers themselves. 56 */ 57 struct shared_bbinfo bbinfo = { 58 { SPARC_BBINFO_MAGIC }, 59 0, 60 SHARED_BBINFO_MAXBLOCKS, 61 { 0 } 62 }; 63 64 int main(void); 65 void loadboot(struct open_file *, char *); 66 67 int 68 main(void) 69 { 70 char *dummy1; 71 const char *dummy; 72 void (*entry)(void *) = (void (*)(void *))PROM_LOADADDR; 73 void *arg; 74 75 #ifdef HEAP_VARIABLE 76 { 77 extern char end[]; 78 setheap((void *)ALIGN(end), (void *)0xffffffff); 79 } 80 #endif 81 prom_init(); 82 dummy = prom_getbootpath(); 83 if (dummy && *dummy != '\0') 84 strcpy(prom_bootdevice, dummy); 85 io.f_flags = F_RAW; 86 if (devopen(&io, 0, &dummy1)) { 87 panic("%s: can't open device `%s'", progname, 88 prom_bootdevice != NULL ? prom_bootdevice : "unknown"); 89 } 90 91 (void)loadboot(&io, (void *)PROM_LOADADDR); 92 (io.f_dev->dv_close)(&io); 93 94 arg = (prom_version() == PROM_OLDMON) ? (void *)PROM_LOADADDR : romp; 95 (*entry)(arg); 96 _rtt(); 97 } 98 99 void 100 loadboot(struct open_file *f, char *addr) 101 { 102 int i; 103 char *buf; 104 size_t n; 105 daddr_t blk; 106 107 /* 108 * Allocate a buffer that we can map into DVMA space; only 109 * needed for sun4 architecture, but use it for all machines 110 * to keep code size down as much as possible. 111 */ 112 buf = alloc(bbinfo.bbi_block_size); 113 if (buf == NULL) 114 panic("%s: alloc failed", progname); 115 116 for (i = 0; i < bbinfo.bbi_block_count; i++) { 117 if ((blk = bbinfo.bbi_block_table[i]) == 0) 118 panic("%s: block table corrupt", progname); 119 120 #ifdef DEBUG 121 printf("%s: block # %d = %d\n", progname, i, blk); 122 #endif 123 if ((f->f_dev->dv_strategy)(f->f_devdata, F_READ, blk, 124 bbinfo.bbi_block_size, buf, &n)) { 125 printf("%s: read failure", progname); 126 _rtt(); 127 } 128 memcpy( addr, buf, bbinfo.bbi_block_size); 129 if (n != bbinfo.bbi_block_size) 130 panic("%s: short read", progname); 131 if (i == 0) { 132 int m = N_GETMAGIC(*(struct exec *)addr); 133 if (m == ZMAGIC || m == NMAGIC || m == OMAGIC) { 134 /* Move exec header out of the way */ 135 memcpy( addr - sizeof(struct exec), addr, n); 136 addr -= sizeof(struct exec); 137 } 138 } 139 addr += n; 140 } 141 142 } 143