1 #define DEBUG 2 /* $NetBSD: boot.c,v 1.6 2008/04/28 20:23:35 martin Exp $ */ 3 4 /*- 5 * Copyright (c) 1997 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 35 * Copyright (C) 1995, 1996 TooLs GmbH. 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by TooLs GmbH. 49 * 4. The name of TooLs GmbH may not be used to endorse or promote products 50 * derived from this software without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 55 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 56 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 /* 65 * First try for the boot code 66 * 67 * Input syntax is: 68 * [promdev[{:|,}partition]]/[filename] [flags] 69 */ 70 71 #define ELFSIZE 32 /* We use 32-bit ELF. */ 72 73 #include <sys/param.h> 74 #include <sys/exec.h> 75 #include <sys/exec_elf.h> 76 #include <sys/reboot.h> 77 #include <sys/disklabel.h> 78 #include <sys/boot_flag.h> 79 80 #include <lib/libsa/stand.h> 81 #include <lib/libsa/loadfile.h> 82 #include <lib/libkern/libkern.h> 83 84 #include <machine/cpu.h> 85 86 #include "cache.h" 87 #include "extern.h" 88 #include "ofdev.h" 89 #include "openfirm.h" 90 91 #ifdef DEBUG 92 # define DPRINTF printf 93 #else 94 # define DPRINTF while (/*CONSTCOND*/0) printf 95 #endif 96 97 char bootdev[128]; 98 char bootfile[128]; 99 int boothowto; 100 int debug; 101 102 #ifdef notyet 103 static int ofw_version = 0; 104 #endif 105 static const char *kernels[] = { 106 "/netbsd", "/netbsd.gz", "/netbsd.shark", NULL 107 }; 108 109 static void 110 prom2boot(char *dev) 111 { 112 char *cp, *ocp; 113 114 ocp = dev; 115 cp = dev + strlen(dev) - 1; 116 for (; cp >= ocp; cp--) { 117 if (*cp == ':') { 118 *cp = '\0'; 119 return; 120 } 121 } 122 } 123 124 static void 125 parseargs(char *str, int *howtop) 126 { 127 char *cp; 128 129 /* Allow user to drop back to the PROM. */ 130 if (strcmp(str, "exit") == 0) 131 OF_exit(); 132 133 *howtop = 0; 134 135 for (cp = str; *cp; cp++) 136 if (*cp == ' ' || *cp == '-') 137 goto found; 138 139 return; 140 141 found: 142 *cp++ = '\0'; 143 while (*cp) 144 BOOT_FLAG(*cp++, *howtop); 145 } 146 147 static void 148 chain(void (*entry)(int (*)(void *), void *, u_int), char *args, void *ssym, 149 void *esym) 150 { 151 extern char end[]; 152 u_int l, magic = 0x19730224; 153 154 freeall(); 155 156 /* 157 * Stash pointer to start and end of symbol table after the argument 158 * strings. 159 */ 160 l = strlen(args) + 1; 161 l = (l + 3) & ~3; /* align */ 162 DPRINTF("magic @ %p\n", args + l); 163 memcpy(args + l, &magic, sizeof(magic)); 164 l += sizeof(magic); 165 DPRINTF("ssym @ %p\n", args + l); 166 memcpy(args + l, &ssym, sizeof(ssym)); 167 l += sizeof(ssym); 168 DPRINTF("esym @ %p\n", args + l); 169 memcpy(args + l, &esym, sizeof(esym)); 170 l += sizeof(esym); 171 DPRINTF("args + l -> %p\n", args + l); 172 173 DPRINTF("Calling OF_chain(%p, %tx, %p, %p, %u)\n", 174 (void *)RELOC, end - (char *)RELOC, entry, args, l); 175 OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l); 176 panic("chain"); 177 } 178 179 __dead void 180 _rtt(void) 181 { 182 183 OF_exit(); 184 } 185 186 void 187 main(void) 188 { 189 extern char bootprog_name[], bootprog_rev[], 190 bootprog_maker[], bootprog_date[]; 191 int chosen; 192 char bootline[512]; /* Should check size? */ 193 char *cp, *startbuf, *endbuf; 194 u_long marks[MARK_MAX], size; 195 u_int32_t entry; 196 void *ssym, *esym; 197 198 printf("\n"); 199 printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); 200 printf(">> (%s, %s)\n", bootprog_maker, bootprog_date); 201 202 /* 203 * Get the boot arguments from Openfirmware 204 */ 205 if ((chosen = OF_finddevice("/chosen")) == -1 || 206 OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 || 207 OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) { 208 printf("Invalid Openfirmware environment\n"); 209 OF_exit(); 210 } 211 212 prom2boot(bootdev); 213 parseargs(bootline, &boothowto); 214 DPRINTF("bootline=%s\n", bootline); 215 216 /* 217 * Per the ARM OpenFirmware bindings, the firmware must 218 * allocate and map at least 6MB of physical memory starting 219 * at VA 0xf0000000. We have been loaded at 0xf0000000, 220 * and the memory after us has been unmapped and freed. 221 * We expect to load the kernel at 0xf0100000, so we will 222 * allocate 5MB of virtual memory starting there, and 223 * unmap/free what we don't use. 224 */ 225 startbuf = OF_claim((void *) 0xf0100000, (5 * 1024 * 1024), 0); 226 if (startbuf != (void *) 0xf0100000) { 227 printf("Unable to claim buffer for kernel\n"); 228 OF_exit(); 229 } 230 endbuf = startbuf + (5 * 1024 * 1024); 231 232 for (;;) { 233 int i; 234 235 if (boothowto & RB_ASKNAME) { 236 printf("Boot: "); 237 gets(bootline); 238 parseargs(bootline, &boothowto); 239 } 240 241 if (bootline[0]) { 242 kernels[0] = bootline; 243 kernels[1] = NULL; 244 } 245 246 for (i = 0; kernels[i]; i++) { 247 DPRINTF("Trying %s\n", kernels[i]); 248 249 marks[MARK_START] = 0xf0100000; 250 if (loadfile(kernels[i], marks, LOAD_KERNEL) >= 0) 251 goto loaded; 252 } 253 254 boothowto |= RB_ASKNAME; 255 } 256 loaded: 257 /* 258 * Okay, kernel is loaded, free the extra memory at the end. 259 * Round to the ARM OpenFirmare page size (4k). 260 */ 261 cp = (char *) ((marks[MARK_END] + 0xfff) & ~0xfff); 262 size = (u_long) (endbuf - cp); 263 if (size) 264 OF_release(cp, size); 265 266 #ifdef __notyet__ 267 OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1); 268 cp = bootline; 269 #else 270 strcpy(bootline, opened_name); 271 cp = bootline + strlen(bootline); 272 *cp++ = ' '; 273 #endif 274 *cp = '-'; 275 if (boothowto & RB_ASKNAME) 276 *++cp = 'a'; 277 if (boothowto & RB_SINGLE) 278 *++cp = 's'; 279 if (boothowto & RB_KDB) 280 *++cp = 'd'; 281 if (*cp == '-') 282 #ifdef __notyet__ 283 *cp = 0; 284 #else 285 *--cp = 0; 286 #endif 287 else 288 *++cp = 0; 289 #ifdef __notyet__ 290 OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1); 291 #endif 292 293 entry = marks[MARK_ENTRY]; 294 ssym = (void *)marks[MARK_SYM]; 295 esym = (void *)marks[MARK_END]; 296 297 printf(" start=0x%x\n", entry); 298 299 if (cache_syncI != NULL) { 300 DPRINTF("Syncing I$...\n"); 301 (*cache_syncI)(); 302 } 303 304 chain((void *)entry, bootline, ssym, esym); 305 306 OF_exit(); 307 } 308