xref: /netbsd-src/sys/arch/shark/stand/ofwboot/boot.c (revision 2d48ac808c43ea6701ba8f33cfc3645685301f79)
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