1 /* $NetBSD: bootxx.c,v 1.19 2007/03/08 17:14:16 he 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/param.h> 40 #include <sys/exec.h> 41 #include <sys/bootblock.h> 42 43 #include <lib/libkern/libkern.h> 44 #include <lib/libsa/stand.h> 45 46 #include <machine/promlib.h> 47 #include <sparc/stand/common/promdev.h> 48 49 int debug; 50 int netif_debug; 51 52 /* 53 * Boot device is derived from ROM provided information. 54 */ 55 const char progname[] = "bootxx"; 56 struct open_file io; 57 58 /* 59 * The contents of the bbinfo below are set by installboot(8) 60 * to hold the filesystem data of the second-stage boot program 61 * (typically `/boot'): filesystem block size, # of filesystem 62 * blocks and the block numbers themselves. 63 */ 64 struct shared_bbinfo bbinfo = { 65 { SPARC_BBINFO_MAGIC }, 66 0, 67 SHARED_BBINFO_MAXBLOCKS, 68 { 0 } 69 }; 70 71 int main(void); 72 void loadboot(struct open_file *, char *); 73 74 int 75 main(void) 76 { 77 char *dummy1; 78 const char *dummy; 79 void (*entry)(void *) = (void (*)(void *))PROM_LOADADDR; 80 void *arg; 81 82 #ifdef HEAP_VARIABLE 83 { 84 extern char end[]; 85 setheap((void *)ALIGN(end), (void *)0xffffffff); 86 } 87 #endif 88 prom_init(); 89 dummy = prom_getbootpath(); 90 if (dummy && *dummy != '\0') 91 strcpy(prom_bootdevice, dummy); 92 io.f_flags = F_RAW; 93 if (devopen(&io, 0, &dummy1)) { 94 panic("%s: can't open device `%s'", progname, 95 prom_bootdevice != NULL ? prom_bootdevice : "unknown"); 96 } 97 98 (void)loadboot(&io, (void *)PROM_LOADADDR); 99 (io.f_dev->dv_close)(&io); 100 101 arg = (prom_version() == PROM_OLDMON) ? (void *)PROM_LOADADDR : romp; 102 (*entry)(arg); 103 _rtt(); 104 } 105 106 void 107 loadboot(struct open_file *f, char *addr) 108 { 109 int i; 110 char *buf; 111 size_t n; 112 daddr_t blk; 113 114 /* 115 * Allocate a buffer that we can map into DVMA space; only 116 * needed for sun4 architecture, but use it for all machines 117 * to keep code size down as much as possible. 118 */ 119 buf = alloc(bbinfo.bbi_block_size); 120 if (buf == NULL) 121 panic("%s: alloc failed", progname); 122 123 for (i = 0; i < bbinfo.bbi_block_count; i++) { 124 if ((blk = bbinfo.bbi_block_table[i]) == 0) 125 panic("%s: block table corrupt", progname); 126 127 #ifdef DEBUG 128 printf("%s: block # %d = %d\n", progname, i, blk); 129 #endif 130 if ((f->f_dev->dv_strategy)(f->f_devdata, F_READ, blk, 131 bbinfo.bbi_block_size, buf, &n)) { 132 printf("%s: read failure", progname); 133 _rtt(); 134 } 135 bcopy(buf, addr, bbinfo.bbi_block_size); 136 if (n != bbinfo.bbi_block_size) 137 panic("%s: short read", progname); 138 if (i == 0) { 139 int m = N_GETMAGIC(*(struct exec *)addr); 140 if (m == ZMAGIC || m == NMAGIC || m == OMAGIC) { 141 /* Move exec header out of the way */ 142 bcopy(addr, addr - sizeof(struct exec), n); 143 addr -= sizeof(struct exec); 144 } 145 } 146 addr += n; 147 } 148 149 } 150 151 /* 152 * We don't need the overlap handling feature that the libkern version 153 * of bcopy() provides. We DO need code compactness.. 154 */ 155 void 156 bcopy(const void *src, void *dst, size_t n) 157 { 158 const char *p = src; 159 char *q = dst; 160 161 while (n-- > 0) 162 *q++ = *p++; 163 } 164