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