xref: /openbsd-src/sys/arch/macppc/stand/main.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: main.c,v 1.5 2008/05/25 16:55:31 miod Exp $	*/
2 /*	$NetBSD: boot.c,v 1.1 1997/04/16 20:29:17 thorpej Exp $	*/
3 
4 /*
5  * Copyright (c) 1997 Jason R. Thorpe.  All rights reserved.
6  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
7  * Copyright (C) 1995, 1996 TooLs GmbH.
8  * All rights reserved.
9  *
10  * ELF support derived from NetBSD/alpha's boot loader, written
11  * by Christopher G. Demetriou.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgement:
23  *	This product includes software developed by TooLs GmbH.
24  * 4. The name of TooLs GmbH may not be used to endorse or promote products
25  *    derived from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
28  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
33  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
35  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * First try for the boot code
41  *
42  * Input syntax is:
43  *	[promdev[{:|,}partition]]/[filename] [flags]
44  */
45 
46 #define	ELFSIZE		32		/* We use 32-bit ELF. */
47 
48 #include <sys/param.h>
49 #include <sys/exec.h>
50 #include <sys/exec_elf.h>
51 #include <sys/reboot.h>
52 #include <sys/disklabel.h>
53 
54 #include <lib/libkern/libkern.h>
55 #include <lib/libsa/stand.h>
56 #include <lib/libsa/loadfile.h>
57 #include <stand/boot/cmd.h>
58 
59 
60 #include <machine/cpu.h>
61 
62 #include <macppc/stand/ofdev.h>
63 #include <macppc/stand/openfirm.h>
64 
65 char bootdev[128];
66 int boothowto;
67 int debug;
68 
69 
70 void
71 get_alt_bootdev(char *, size_t, char *, size_t);
72 
73 static void
74 prom2boot(char *dev)
75 {
76 	char *cp, *lp = 0;
77 
78 	for (cp = dev; *cp; cp++)
79 		if (*cp == ':')
80 			lp = cp;
81 	if (!lp)
82 		lp = cp;
83 	*lp = 0;
84 }
85 
86 static void
87 parseargs(char *str, int *howtop)
88 {
89 	char *cp;
90 
91 	/* Allow user to drop back to the PROM. */
92 	if (strcmp(str, "exit") == 0)
93 		_rtt();
94 
95 	*howtop = 0;
96 	if (str[0] == '\0')
97 		return;
98 
99 	cp = str;
100 	while (*cp != 0) {
101 		/* check for - */
102 		if (*cp == '-')
103 			break;	/* start of options found */
104 
105 		while (*cp != 0 && *cp != ' ')
106 			cp++;	/* character in the middle of the name, skip */
107 
108 		while (*cp == ' ')
109 			*cp++ = 0;
110 	}
111 	if (!*cp)
112 		return;
113 
114 	*cp++ = 0;
115 	while (*cp) {
116 		switch (*cp++) {
117 		case 'a':
118 			*howtop |= RB_ASKNAME;
119 			break;
120 		case 'c':
121 			*howtop |= RB_CONFIG;
122 			break;
123 		case 's':
124 			*howtop |= RB_SINGLE;
125 			break;
126 		case 'd':
127 			*howtop |= RB_KDB;
128 			debug = 1;
129 			break;
130 		}
131 	}
132 }
133 
134 static void
135 chain(void (*entry)(), char *args, void *ssym, void *esym)
136 {
137 	extern char end[];
138 	int l;
139 #ifdef __notyet__
140 	int machine_tag;
141 #endif
142 
143 	freeall();
144 
145 	/*
146 	 * Stash pointer to end of symbol table after the argument
147 	 * strings.
148 	 */
149 	l = strlen(args) + 1;
150 	bcopy(&ssym, args + l, sizeof(ssym));
151 	l += sizeof(ssym);
152 	bcopy(&esym, args + l, sizeof(esym));
153 	l += sizeof(esym);
154 
155 #ifdef __notyet__
156 	/*
157 	 * Tell the kernel we're an OpenFirmware system.
158 	 */
159 	machine_tag = POWERPC_MACHINE_OPENFIRMWARE;
160 	bcopy(&machine_tag, args + l, sizeof(machine_tag));
161 	l += sizeof(machine_tag);
162 #endif
163 
164 	OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l);
165 	panic("chain");
166 }
167 
168 /*
169  * XXX This limits the maximum size of the (uncompressed) bsd.rd to a
170  * little under 11MB.
171  */
172 #define CLAIM_LIMIT	0x00c00000
173 
174 char bootline[512];
175 
176 extern char *kernelfile;
177 int
178 main()
179 {
180 	int chosen;
181 
182 	/*
183 	 * Get the boot arguments from Openfirmware
184 	 */
185 	if ((chosen = OF_finddevice("/chosen")) == -1 ||
186 	    OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 ||
187 	    OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
188 		printf("Invalid Openfirmware environment\n");
189 		exit();
190 	}
191 	prom2boot(bootdev);
192 	get_alt_bootdev(bootdev, sizeof(bootdev), bootline, sizeof(bootline));
193 	if (bootline[0] != '\0')
194 		kernelfile = bootline;
195 
196 	OF_claim((void *)0x00100000, CLAIM_LIMIT, 0); /* XXX */
197 	boot(0);
198 	return 0;
199 }
200 
201 void
202 get_alt_bootdev(char *dev, size_t devsz, char *line, size_t linesz)
203 {
204 	char *p;
205 	int len;
206 	/*
207 	 * if the kernel image specified contains a ':' it is
208 	 * [device]:[kernel], so separate the two fields.
209 	 */
210 	p = strrchr(line, ':');
211 	if (p == NULL)
212 		return;
213 	/* user specified boot device for kernel */
214 	len = p - line + 1; /* str len plus nil */
215 	strlcpy(dev, line, len > devsz ? devsz : len);
216 
217 	strlcpy(line, p+1, linesz); /* rest of string ater ':' */
218 }
219 
220 
221 void
222 devboot(dev_t dev, char *p)
223 {
224 	strlcpy(p, bootdev, BOOTDEVLEN);
225 }
226 
227 int
228 run_loadfile(u_long *marks, int howto)
229 {
230 	char bootline[512];		/* Should check size? */
231 	u_int32_t entry;
232 	char *cp;
233 	void *ssym, *esym;
234 
235 	strlcpy(bootline, opened_name, sizeof bootline);
236 	cp = bootline + strlen(bootline);
237 	*cp++ = ' ';
238         *cp = '-';
239         if (howto & RB_ASKNAME)
240                 *++cp = 'a';
241         if (howto & RB_CONFIG)
242                 *++cp = 'c';
243         if (howto & RB_SINGLE)
244                 *++cp = 's';
245         if (howto & RB_KDB)
246                 *++cp = 'd';
247         if (*cp == '-')
248 		*--cp = 0;
249 	else
250 		*++cp = 0;
251 
252 	entry = marks[MARK_ENTRY];
253 	ssym = (void *)marks[MARK_SYM];
254 	esym = (void *)marks[MARK_END];
255 	{
256 		u_int32_t lastpage;
257 		lastpage = roundup(marks[MARK_END], NBPG);
258 		OF_release((void*)lastpage, CLAIM_LIMIT - lastpage);
259 	}
260 
261 	chain((void *)entry, bootline, ssym, esym);
262 
263 	_rtt();
264 	return 0;
265 }
266 
267 int
268 cnspeed(dev_t dev, int sp)
269 {
270 	return CONSPEED;
271 }
272 
273 char ttyname_buf[8];
274 
275 char *
276 ttyname(int fd)
277 {
278         snprintf(ttyname_buf, sizeof ttyname_buf, "ofc0");
279 	return ttyname_buf;
280 }
281 
282 dev_t
283 ttydev(char *name)
284 {
285 	return makedev(0,0);
286 }
287