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