xref: /netbsd/sys/arch/ofppc/stand/ofwboot/Locore.c (revision bf9ec67e)
1 /*	$NetBSD: Locore.c,v 1.6 2001/10/23 03:31:25 thorpej 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[1024];
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+4096-16@ha
64 	addi	1,1,stack+4096-16@l
65 	b	startup
66 ");
67 
68 static int
69 openfirmware(arg)
70 	void *arg;
71 {
72 
73 	asm volatile ("sync; isync");
74 	openfirmware_entry(arg);
75 	asm volatile ("sync; isync");
76 }
77 
78 static void
79 startup(vpd, res, openfirm, arg, argl)
80 	void *vpd;
81 	int res;
82 	int (*openfirm)(void *);
83 	char *arg;
84 	int argl;
85 {
86 	extern char etext[], _end[], _edata[];
87 
88 	memset(_edata, 0, (_end - _edata));
89 	openfirmware_entry = openfirm;
90 	setup();
91 	main();
92 	OF_exit();
93 }
94 
95 __dead void
96 OF_exit()
97 {
98 	static struct {
99 		char *name;
100 		int nargs;
101 		int nreturns;
102 	} args = {
103 		"exit",
104 		0,
105 		0
106 	};
107 
108 	openfirmware(&args);
109 	for (;;);			/* just in case */
110 }
111 
112 int
113 OF_finddevice(name)
114 	char *name;
115 {
116 	static struct {
117 		char *name;
118 		int nargs;
119 		int nreturns;
120 		char *device;
121 		int phandle;
122 	} args = {
123 		"finddevice",
124 		1,
125 		1,
126 	};
127 
128 	args.device = name;
129 	if (openfirmware(&args) == -1)
130 		return -1;
131 	return args.phandle;
132 }
133 
134 int
135 OF_instance_to_package(ihandle)
136 	int ihandle;
137 {
138 	static struct {
139 		char *name;
140 		int nargs;
141 		int nreturns;
142 		int ihandle;
143 		int phandle;
144 	} args = {
145 		"instance-to-package",
146 		1,
147 		1,
148 	};
149 
150 	args.ihandle = ihandle;
151 	if (openfirmware(&args) == -1)
152 		return -1;
153 	return args.phandle;
154 }
155 
156 int
157 OF_getprop(handle, prop, buf, buflen)
158 	int handle;
159 	char *prop;
160 	void *buf;
161 	int buflen;
162 {
163 	static struct {
164 		char *name;
165 		int nargs;
166 		int nreturns;
167 		int phandle;
168 		char *prop;
169 		void *buf;
170 		int buflen;
171 		int size;
172 	} args = {
173 		"getprop",
174 		4,
175 		1,
176 	};
177 
178 	args.phandle = handle;
179 	args.prop = prop;
180 	args.buf = buf;
181 	args.buflen = buflen;
182 	if (openfirmware(&args) == -1)
183 		return -1;
184 	return args.size;
185 }
186 
187 #ifdef	__notyet__	/* Has a bug on FirePower */
188 int
189 OF_setprop(handle, prop, buf, len)
190 	int handle;
191 	char *prop;
192 	void *buf;
193 	int len;
194 {
195 	static struct {
196 		char *name;
197 		int nargs;
198 		int nreturns;
199 		int phandle;
200 		char *prop;
201 		void *buf;
202 		int len;
203 		int size;
204 	} args = {
205 		"setprop",
206 		4,
207 		1,
208 	};
209 
210 	args.phandle = handle;
211 	args.prop = prop;
212 	args.buf = buf;
213 	args.len = len;
214 	if (openfirmware(&args) == -1)
215 		return -1;
216 	return args.size;
217 }
218 #endif
219 
220 int
221 OF_open(dname)
222 	char *dname;
223 {
224 	static struct {
225 		char *name;
226 		int nargs;
227 		int nreturns;
228 		char *dname;
229 		int handle;
230 	} args = {
231 		"open",
232 		1,
233 		1,
234 	};
235 
236 #ifdef OFW_DEBUG
237 	printf("OF_open(%s) -> ", dname);
238 #endif
239 	args.dname = dname;
240 	if (openfirmware(&args) == -1 ||
241 	    args.handle == 0) {
242 #ifdef OFW_DEBUG
243 		printf("lose\n");
244 #endif
245 		return -1;
246 	}
247 #ifdef OFW_DEBUG
248 	printf("%d\n", args.handle);
249 #endif
250 	return args.handle;
251 }
252 
253 void
254 OF_close(handle)
255 	int handle;
256 {
257 	static struct {
258 		char *name;
259 		int nargs;
260 		int nreturns;
261 		int handle;
262 	} args = {
263 		"close",
264 		1,
265 		0,
266 	};
267 
268 #ifdef OFW_DEBUG
269 	printf("OF_close(%d)\n", handle);
270 #endif
271 	args.handle = handle;
272 	openfirmware(&args);
273 }
274 
275 int
276 OF_write(handle, addr, len)
277 	int handle;
278 	void *addr;
279 	int len;
280 {
281 	static struct {
282 		char *name;
283 		int nargs;
284 		int nreturns;
285 		int ihandle;
286 		void *addr;
287 		int len;
288 		int actual;
289 	} args = {
290 		"write",
291 		3,
292 		1,
293 	};
294 
295 #ifdef OFW_DEBUG
296 	if (len != 1)
297 		printf("OF_write(%d, %x, %x) -> ", handle, addr, len);
298 #endif
299 	args.ihandle = handle;
300 	args.addr = addr;
301 	args.len = len;
302 	if (openfirmware(&args) == -1) {
303 #ifdef OFW_DEBUG
304 		printf("lose\n");
305 #endif
306 		return -1;
307 	}
308 #ifdef OFW_DEBUG
309 	if (len != 1)
310 		printf("%x\n", args.actual);
311 #endif
312 	return args.actual;
313 }
314 
315 int
316 OF_read(handle, addr, len)
317 	int handle;
318 	void *addr;
319 	int len;
320 {
321 	static struct {
322 		char *name;
323 		int nargs;
324 		int nreturns;
325 		int ihandle;
326 		void *addr;
327 		int len;
328 		int actual;
329 	} args = {
330 		"read",
331 		3,
332 		1,
333 	};
334 
335 #ifdef OFW_DEBUG
336 	if (len != 1)
337 		printf("OF_read(%d, %x, %x) -> ", handle, addr, len);
338 #endif
339 	args.ihandle = handle;
340 	args.addr = addr;
341 	args.len = len;
342 	if (openfirmware(&args) == -1) {
343 #ifdef OFW_DEBUG
344 		printf("lose\n");
345 #endif
346 		return -1;
347 	}
348 #ifdef OFW_DEBUG
349 	if (len != 1)
350 		printf("%x\n", args.actual);
351 #endif
352 	return args.actual;
353 }
354 
355 int
356 OF_seek(handle, pos)
357 	int handle;
358 	u_quad_t pos;
359 {
360 	static struct {
361 		char *name;
362 		int nargs;
363 		int nreturns;
364 		int handle;
365 		int poshi;
366 		int poslo;
367 		int status;
368 	} args = {
369 		"seek",
370 		3,
371 		1,
372 	};
373 
374 #ifdef OFW_DEBUG
375 	printf("OF_seek(%d, %x, %x) -> ", handle, (int)(pos >> 32), (int)pos);
376 #endif
377 	args.handle = handle;
378 	args.poshi = (int)(pos >> 32);
379 	args.poslo = (int)pos;
380 	if (openfirmware(&args) == -1) {
381 #ifdef OFW_DEBUG
382 		printf("lose\n");
383 #endif
384 		return -1;
385 	}
386 #ifdef OFW_DEBUG
387 	printf("%d\n", args.status);
388 #endif
389 	return args.status;
390 }
391 
392 void *
393 OF_claim(virt, size, align)
394 	void *virt;
395 	u_int size;
396 	u_int align;
397 {
398 	static struct {
399 		char *name;
400 		int nargs;
401 		int nreturns;
402 		void *virt;
403 		u_int size;
404 		u_int align;
405 		void *baseaddr;
406 	} args = {
407 		"claim",
408 		3,
409 		1,
410 	};
411 
412 #ifdef OFW_DEBUG
413 	printf("OF_claim(%x, %x, %x) -> ", virt, size, align);
414 #endif
415 	args.virt = virt;
416 	args.size = size;
417 	args.align = align;
418 	if (openfirmware(&args) == -1) {
419 #ifdef OFW_DEBUG
420 		printf("lose\n");
421 #endif
422 		return (void *)-1;
423 	}
424 #ifdef OFW_DEBUG
425 	printf("%x\n", args.baseaddr);
426 #endif
427 	return args.baseaddr;
428 }
429 
430 void
431 OF_release(virt, size)
432 	void *virt;
433 	u_int size;
434 {
435 	static struct {
436 		char *name;
437 		int nargs;
438 		int nreturns;
439 		void *virt;
440 		u_int size;
441 	} args = {
442 		"release",
443 		2,
444 		0,
445 	};
446 
447 #ifdef OFW_DEBUG
448 	printf("OF_release(%x, %x)\n", virt, size);
449 #endif
450 	args.virt = virt;
451 	args.size = size;
452 	openfirmware(&args);
453 }
454 
455 int
456 OF_milliseconds()
457 {
458 	static struct {
459 		char *name;
460 		int nargs;
461 		int nreturns;
462 		int ms;
463 	} args = {
464 		"milliseconds",
465 		0,
466 		1,
467 	};
468 
469 	openfirmware(&args);
470 	return args.ms;
471 }
472 
473 #ifdef	__notyet__
474 void
475 OF_chain(virt, size, entry, arg, len)
476 	void *virt;
477 	u_int size;
478 	void (*entry)();
479 	void *arg;
480 	u_int len;
481 {
482 	static struct {
483 		char *name;
484 		int nargs;
485 		int nreturns;
486 		void *virt;
487 		u_int size;
488 		void (*entry)();
489 		void *arg;
490 		u_int len;
491 	} args = {
492 		"chain",
493 		5,
494 		0,
495 	};
496 
497 	args.virt = virt;
498 	args.size = size;
499 	args.entry = entry;
500 	args.arg = arg;
501 	args.len = len;
502 	openfirmware(&args);
503 }
504 #else
505 void
506 OF_chain(virt, size, entry, arg, len)
507 	void *virt;
508 	u_int size;
509 	void (*entry)();
510 	void *arg;
511 	u_int len;
512 {
513 	/*
514 	 * This is a REALLY dirty hack till the firmware gets this going
515 	 */
516 #if 1
517 	OF_release(virt, size);
518 #endif
519 	entry(0, 0, openfirmware_entry, arg, len);
520 }
521 #endif
522 
523 static int stdin;
524 static int stdout;
525 
526 static void
527 setup()
528 {
529 	int chosen;
530 
531 	if ((chosen = OF_finddevice("/chosen")) == -1)
532 		OF_exit();
533 	if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) !=
534 	    sizeof(stdin) ||
535 	    OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) !=
536 	    sizeof(stdout))
537 		OF_exit();
538 }
539 
540 void
541 putchar(c)
542 	int c;
543 {
544 	char ch = c;
545 
546 	if (c == '\n')
547 		putchar('\r');
548 	OF_write(stdout, &ch, 1);
549 }
550 
551 int
552 getchar()
553 {
554 	unsigned char ch = '\0';
555 	int l;
556 
557 	while ((l = OF_read(stdin, &ch, 1)) != 1)
558 		if (l != -2 && l != 0)
559 			return -1;
560 	return ch;
561 }
562