xref: /netbsd-src/sys/arch/shark/stand/ofwboot/boot.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 #define	DEBUG
2 /*	$NetBSD: boot.c,v 1.9 2016/07/07 06:55:38 msaitoh 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 	int chosen;
191 	char bootline[512];		/* Should check size? */
192 	char *cp, *startbuf, *endbuf;
193 	u_long marks[MARK_MAX], size;
194 	u_int32_t entry;
195 	void *ssym, *esym;
196 
197 	printf("\n");
198 	printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
199 
200 	/*
201 	 * Get the boot arguments from Openfirmware
202 	 */
203 	if ((chosen = OF_finddevice("/chosen")) == -1 ||
204 	    OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 ||
205 	    OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
206 		printf("Invalid Openfirmware environment\n");
207 		OF_exit();
208 	}
209 
210 	prom2boot(bootdev);
211 	parseargs(bootline, &boothowto);
212 	DPRINTF("bootline=%s\n", bootline);
213 
214 	/*
215 	 * Per the ARM OpenFirmware bindings, the firmware must
216 	 * allocate and map at least 6MB of physical memory starting
217 	 * at VA 0xf0000000.  We have been loaded at 0xf0000000,
218 	 * and the memory after us has been unmapped and freed.
219 	 * We expect to load the kernel at 0xf0100000, so we will
220 	 * allocate 5MB of virtual memory starting there, and
221 	 * unmap/free what we don't use.
222 	 */
223 	startbuf = OF_claim((void *) 0xf0100000, (5 * 1024 * 1024), 0);
224 	if (startbuf != (void *) 0xf0100000) {
225 		printf("Unable to claim buffer for kernel\n");
226 		OF_exit();
227 	}
228 	endbuf = startbuf + (5 * 1024 * 1024);
229 
230 	for (;;) {
231 		int i;
232 
233 		if (boothowto & RB_ASKNAME) {
234 			printf("Boot: ");
235 			kgets(bootline, sizeof(bootline));
236 			parseargs(bootline, &boothowto);
237 		}
238 
239 		if (bootline[0]) {
240 			kernels[0] = bootline;
241 			kernels[1] = NULL;
242 		}
243 
244 		for (i = 0; kernels[i]; i++) {
245 			DPRINTF("Trying %s\n", kernels[i]);
246 
247 			marks[MARK_START] = 0xf0100000;
248 			if (loadfile(kernels[i], marks, LOAD_KERNEL) >= 0)
249 				goto loaded;
250 		}
251 
252 		boothowto |= RB_ASKNAME;
253 	}
254  loaded:
255 	/*
256 	 * Okay, kernel is loaded, free the extra memory at the end.
257 	 * Round to the ARM OpenFirmare page size (4k).
258 	 */
259 	cp = (char *) ((marks[MARK_END] + 0xfff) & ~0xfff);
260 	size = (u_long) (endbuf - cp);
261 	if (size)
262 		OF_release(cp, size);
263 
264 #ifdef	__notyet__
265 	OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1);
266 	cp = bootline;
267 #else
268 	strcpy(bootline, opened_name);
269 	cp = bootline + strlen(bootline);
270 	*cp++ = ' ';
271 #endif
272 	*cp = '-';
273 	if (boothowto & RB_ASKNAME)
274 		*++cp = 'a';
275 	if (boothowto & RB_SINGLE)
276 		*++cp = 's';
277 	if (boothowto & RB_KDB)
278 		*++cp = 'd';
279 	if (*cp == '-')
280 #ifdef	__notyet__
281 		*cp = 0;
282 #else
283 		*--cp = 0;
284 #endif
285 	else
286 		*++cp = 0;
287 #ifdef	__notyet__
288 	OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
289 #endif
290 
291 	entry = marks[MARK_ENTRY];
292 	ssym = (void *)marks[MARK_SYM];
293 	esym = (void *)marks[MARK_END];
294 
295 	printf(" start=0x%x\n", entry);
296 
297 	if (cache_syncI != NULL) {
298 		DPRINTF("Syncing I$...\n");
299 		(*cache_syncI)();
300 	}
301 
302 	chain((void *)entry, bootline, ssym, esym);
303 
304 	OF_exit();
305 }
306