xref: /netbsd/sys/arch/ofppc/stand/ofwboot/Locore.c (revision c4a72b64)
1 /*	$NetBSD: Locore.c,v 1.8 2002/10/25 18:19:43 briggs Exp $	*/
2 
3 /*
4  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5  * Copyright (C) 1995, 1996 TooLs GmbH.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by TooLs GmbH.
19  * 4. The name of TooLs GmbH may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <lib/libsa/stand.h>
35 
36 #include <machine/cpu.h>
37 
38 #include "openfirm.h"
39 
40 static int (*openfirmware_entry) __P((void *));
41 static int openfirmware __P((void *));
42 
43 static void startup __P((void *, int, int (*)(void *), char *, int));
44 static void setup __P((void));
45 
46 static int stack[8192/4 + 4];
47 
48 asm("
49 	.text
50 	.globl	_start
51 _start:
52 	li	8,0
53 	li	9,0x100
54 	mtctr	9
55 1:
56 	dcbf	0,8
57 	icbi	0,8
58 	addi	8,8,0x20
59 	bdnz	1b
60 	sync
61 	isync
62 
63 	lis	1,stack@ha
64 	addi	1,1,stack@l
65 	addi	1,1,8192
66 	b	startup
67 ");
68 
69 static int
70 openfirmware(arg)
71 	void *arg;
72 {
73 
74 	asm volatile ("sync; isync");
75 	openfirmware_entry(arg);
76 	asm volatile ("sync; isync");
77 }
78 
79 static void
80 startup(vpd, res, openfirm, arg, argl)
81 	void *vpd;
82 	int res;
83 	int (*openfirm)(void *);
84 	char *arg;
85 	int argl;
86 {
87 	extern char etext[], _end[], _edata[];
88 
89 	memset(_edata, 0, (_end - _edata));
90 	openfirmware_entry = openfirm;
91 	setup();
92 	main();
93 	OF_exit();
94 }
95 
96 __dead void
97 OF_exit()
98 {
99 	static struct {
100 		char *name;
101 		int nargs;
102 		int nreturns;
103 	} args = {
104 		"exit",
105 		0,
106 		0
107 	};
108 
109 	openfirmware(&args);
110 	for (;;);			/* just in case */
111 }
112 
113 __dead void
114 OF_boot(bootspec)
115         char *bootspec;
116 {
117 	static struct {
118 		char *name;
119 		int nargs;
120 		int nreturns;
121 		char *bootspec;
122 	} args = {
123 		"boot",
124 		1,
125 		0,
126 	};
127 
128 	args.bootspec = bootspec;
129 	openfirmware(&args);
130 	for (;;);			/* just is case */
131 }
132 
133 int
134 OF_finddevice(name)
135 	char *name;
136 {
137 	static struct {
138 		char *name;
139 		int nargs;
140 		int nreturns;
141 		char *device;
142 		int phandle;
143 	} args = {
144 		"finddevice",
145 		1,
146 		1,
147 	};
148 
149 	args.device = name;
150 	if (openfirmware(&args) == -1)
151 		return -1;
152 	return args.phandle;
153 }
154 
155 int
156 OF_instance_to_package(ihandle)
157 	int ihandle;
158 {
159 	static struct {
160 		char *name;
161 		int nargs;
162 		int nreturns;
163 		int ihandle;
164 		int phandle;
165 	} args = {
166 		"instance-to-package",
167 		1,
168 		1,
169 	};
170 
171 	args.ihandle = ihandle;
172 	if (openfirmware(&args) == -1)
173 		return -1;
174 	return args.phandle;
175 }
176 
177 int
178 OF_getprop(handle, prop, buf, buflen)
179 	int handle;
180 	char *prop;
181 	void *buf;
182 	int buflen;
183 {
184 	static struct {
185 		char *name;
186 		int nargs;
187 		int nreturns;
188 		int phandle;
189 		char *prop;
190 		void *buf;
191 		int buflen;
192 		int size;
193 	} args = {
194 		"getprop",
195 		4,
196 		1,
197 	};
198 
199 	args.phandle = handle;
200 	args.prop = prop;
201 	args.buf = buf;
202 	args.buflen = buflen;
203 	if (openfirmware(&args) == -1)
204 		return -1;
205 	return args.size;
206 }
207 
208 #ifdef	__notyet__	/* Has a bug on FirePower */
209 int
210 OF_setprop(handle, prop, buf, len)
211 	int handle;
212 	char *prop;
213 	void *buf;
214 	int len;
215 {
216 	static struct {
217 		char *name;
218 		int nargs;
219 		int nreturns;
220 		int phandle;
221 		char *prop;
222 		void *buf;
223 		int len;
224 		int size;
225 	} args = {
226 		"setprop",
227 		4,
228 		1,
229 	};
230 
231 	args.phandle = handle;
232 	args.prop = prop;
233 	args.buf = buf;
234 	args.len = len;
235 	if (openfirmware(&args) == -1)
236 		return -1;
237 	return args.size;
238 }
239 #endif
240 
241 int
242 OF_open(dname)
243 	char *dname;
244 {
245 	static struct {
246 		char *name;
247 		int nargs;
248 		int nreturns;
249 		char *dname;
250 		int handle;
251 	} args = {
252 		"open",
253 		1,
254 		1,
255 	};
256 
257 #ifdef OFW_DEBUG
258 	printf("OF_open(%s) -> ", dname);
259 #endif
260 	args.dname = dname;
261 	if (openfirmware(&args) == -1 ||
262 	    args.handle == 0) {
263 #ifdef OFW_DEBUG
264 		printf("lose\n");
265 #endif
266 		return -1;
267 	}
268 #ifdef OFW_DEBUG
269 	printf("%d\n", args.handle);
270 #endif
271 	return args.handle;
272 }
273 
274 void
275 OF_close(handle)
276 	int handle;
277 {
278 	static struct {
279 		char *name;
280 		int nargs;
281 		int nreturns;
282 		int handle;
283 	} args = {
284 		"close",
285 		1,
286 		0,
287 	};
288 
289 #ifdef OFW_DEBUG
290 	printf("OF_close(%d)\n", handle);
291 #endif
292 	args.handle = handle;
293 	openfirmware(&args);
294 }
295 
296 int
297 OF_write(handle, addr, len)
298 	int handle;
299 	void *addr;
300 	int len;
301 {
302 	static struct {
303 		char *name;
304 		int nargs;
305 		int nreturns;
306 		int ihandle;
307 		void *addr;
308 		int len;
309 		int actual;
310 	} args = {
311 		"write",
312 		3,
313 		1,
314 	};
315 
316 #ifdef OFW_DEBUG
317 	if (len != 1)
318 		printf("OF_write(%d, %x, %x) -> ", handle, addr, len);
319 #endif
320 	args.ihandle = handle;
321 	args.addr = addr;
322 	args.len = len;
323 	if (openfirmware(&args) == -1) {
324 #ifdef OFW_DEBUG
325 		printf("lose\n");
326 #endif
327 		return -1;
328 	}
329 #ifdef OFW_DEBUG
330 	if (len != 1)
331 		printf("%x\n", args.actual);
332 #endif
333 	return args.actual;
334 }
335 
336 int
337 OF_read(handle, addr, len)
338 	int handle;
339 	void *addr;
340 	int len;
341 {
342 	static struct {
343 		char *name;
344 		int nargs;
345 		int nreturns;
346 		int ihandle;
347 		void *addr;
348 		int len;
349 		int actual;
350 	} args = {
351 		"read",
352 		3,
353 		1,
354 	};
355 
356 #ifdef OFW_DEBUG
357 	if (len != 1)
358 		printf("OF_read(%d, %x, %x) -> ", handle, addr, len);
359 #endif
360 	args.ihandle = handle;
361 	args.addr = addr;
362 	args.len = len;
363 	if (openfirmware(&args) == -1) {
364 #ifdef OFW_DEBUG
365 		printf("lose\n");
366 #endif
367 		return -1;
368 	}
369 #ifdef OFW_DEBUG
370 	if (len != 1)
371 		printf("%x\n", args.actual);
372 #endif
373 	return args.actual;
374 }
375 
376 int
377 OF_seek(handle, pos)
378 	int handle;
379 	u_quad_t pos;
380 {
381 	static struct {
382 		char *name;
383 		int nargs;
384 		int nreturns;
385 		int handle;
386 		int poshi;
387 		int poslo;
388 		int status;
389 	} args = {
390 		"seek",
391 		3,
392 		1,
393 	};
394 
395 #ifdef OFW_DEBUG
396 	printf("OF_seek(%d, %x, %x) -> ", handle, (int)(pos >> 32), (int)pos);
397 #endif
398 	args.handle = handle;
399 	args.poshi = (int)(pos >> 32);
400 	args.poslo = (int)pos;
401 	if (openfirmware(&args) == -1) {
402 #ifdef OFW_DEBUG
403 		printf("lose\n");
404 #endif
405 		return -1;
406 	}
407 #ifdef OFW_DEBUG
408 	printf("%d\n", args.status);
409 #endif
410 	return args.status;
411 }
412 
413 void *
414 OF_claim(virt, size, align)
415 	void *virt;
416 	u_int size;
417 	u_int align;
418 {
419 	static struct {
420 		char *name;
421 		int nargs;
422 		int nreturns;
423 		void *virt;
424 		u_int size;
425 		u_int align;
426 		void *baseaddr;
427 	} args = {
428 		"claim",
429 		3,
430 		1,
431 	};
432 
433 #ifdef OFW_DEBUG
434 	printf("OF_claim(%x, %x, %x) -> ", virt, size, align);
435 #endif
436 	args.virt = virt;
437 	args.size = size;
438 	args.align = align;
439 	if (openfirmware(&args) == -1) {
440 #ifdef OFW_DEBUG
441 		printf("lose\n");
442 #endif
443 		return (void *)-1;
444 	}
445 #ifdef OFW_DEBUG
446 	printf("%x\n", args.baseaddr);
447 #endif
448 	return args.baseaddr;
449 }
450 
451 void
452 OF_release(virt, size)
453 	void *virt;
454 	u_int size;
455 {
456 	static struct {
457 		char *name;
458 		int nargs;
459 		int nreturns;
460 		void *virt;
461 		u_int size;
462 	} args = {
463 		"release",
464 		2,
465 		0,
466 	};
467 
468 #ifdef OFW_DEBUG
469 	printf("OF_release(%x, %x)\n", virt, size);
470 #endif
471 	args.virt = virt;
472 	args.size = size;
473 	openfirmware(&args);
474 }
475 
476 int
477 OF_milliseconds()
478 {
479 	static struct {
480 		char *name;
481 		int nargs;
482 		int nreturns;
483 		int ms;
484 	} args = {
485 		"milliseconds",
486 		0,
487 		1,
488 	};
489 
490 	openfirmware(&args);
491 	return args.ms;
492 }
493 
494 #ifdef	__notyet__
495 void
496 OF_chain(virt, size, entry, arg, len)
497 	void *virt;
498 	u_int size;
499 	void (*entry)();
500 	void *arg;
501 	u_int len;
502 {
503 	static struct {
504 		char *name;
505 		int nargs;
506 		int nreturns;
507 		void *virt;
508 		u_int size;
509 		void (*entry)();
510 		void *arg;
511 		u_int len;
512 	} args = {
513 		"chain",
514 		5,
515 		0,
516 	};
517 
518 	args.virt = virt;
519 	args.size = size;
520 	args.entry = entry;
521 	args.arg = arg;
522 	args.len = len;
523 	openfirmware(&args);
524 }
525 #else
526 void
527 OF_chain(virt, size, entry, arg, len)
528 	void *virt;
529 	u_int size;
530 	void (*entry)();
531 	void *arg;
532 	u_int len;
533 {
534 	/*
535 	 * This is a REALLY dirty hack till the firmware gets this going
536 	 */
537 #if 1
538 	OF_release(virt, size);
539 #endif
540 	entry(0, 0, openfirmware_entry, arg, len);
541 }
542 #endif
543 
544 static int stdin;
545 static int stdout;
546 
547 static void
548 setup()
549 {
550 	int chosen;
551 
552 	if ((chosen = OF_finddevice("/chosen")) == -1)
553 		OF_exit();
554 	if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) !=
555 	    sizeof(stdin) ||
556 	    OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) !=
557 	    sizeof(stdout))
558 		OF_exit();
559 }
560 
561 void
562 putchar(c)
563 	int c;
564 {
565 	char ch = c;
566 
567 	if (c == '\n')
568 		putchar('\r');
569 	OF_write(stdout, &ch, 1);
570 }
571 
572 int
573 getchar()
574 {
575 	unsigned char ch = '\0';
576 	int l;
577 
578 	while ((l = OF_read(stdin, &ch, 1)) != 1)
579 		if (l != -2 && l != 0)
580 			return -1;
581 	return ch;
582 }
583