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