xref: /netbsd-src/sys/arch/arm/ofw/openfirm.c (revision e5548b402ae4c44fb816de42c7bba9581ce23ef5)
1 /*	$NetBSD: openfirm.c,v 1.5 2005/12/11 12:16:51 christos Exp $	*/
2 
3 /*
4  * Copyright 1997
5  * Digital Equipment Corporation. All rights reserved.
6  *
7  * This software is furnished under license and may be used and
8  * copied only in accordance with the following terms and conditions.
9  * Subject to these conditions, you may download, copy, install,
10  * use, modify and distribute this software in source and/or binary
11  * form. No title or ownership is transferred hereby.
12  *
13  * 1) Any source code used, modified or distributed must reproduce
14  *    and retain this copyright notice and list of conditions as
15  *    they appear in the source file.
16  *
17  * 2) No right is granted to use any trade name, trademark, or logo of
18  *    Digital Equipment Corporation. Neither the "Digital Equipment
19  *    Corporation" name nor any trademark or logo of Digital Equipment
20  *    Corporation may be used to endorse or promote products derived
21  *    from this software without the prior written permission of
22  *    Digital Equipment Corporation.
23  *
24  * 3) This software is provided "AS-IS" and any express or implied
25  *    warranties, including but not limited to, any implied warranties
26  *    of merchantability, fitness for a particular purpose, or
27  *    non-infringement are disclaimed. In no event shall DIGITAL be
28  *    liable for any damages whatsoever, and in particular, DIGITAL
29  *    shall not be liable for special, indirect, consequential, or
30  *    incidental damages or damages for lost profits, loss of
31  *    revenue or loss of use, whether such damages arise in contract,
32  *    negligence, tort, under statute, in equity, at law or otherwise,
33  *    even if advised of the possibility of such damage.
34  */
35 
36 /*
37  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
38  * Copyright (C) 1995, 1996 TooLs GmbH.
39  * All rights reserved.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. All advertising materials mentioning features or use of this software
50  *    must display the following acknowledgement:
51  *	This product includes software developed by TooLs GmbH.
52  * 4. The name of TooLs GmbH may not be used to endorse or promote products
53  *    derived from this software without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
56  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
57  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
58  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
60  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
61  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
62  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
63  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
64  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65  */
66 
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.5 2005/12/11 12:16:51 christos Exp $");
69 
70 #include <sys/param.h>
71 
72 #include <machine/stdarg.h>
73 
74 #include <dev/ofw/openfirm.h>
75 
76 
77 /*
78  *  Wrapper routines for OFW client services.
79  *
80  *  This code was adapted from the PowerPC version done by
81  *  Wolfgang Solfrank.  The main difference is that we don't
82  *  do the silly "ofw_stack" dance to convert the OS's real-
83  *  mode view of OFW to virtual-mode.  We don't need to do
84  *  that because our NetBSD port assumes virtual-mode OFW.
85  *
86  *  We should work with Wolfgang to turn this into a MI file. -JJK
87  */
88 
89 
90 int
91 OF_peer(phandle)
92 	int phandle;
93 {
94 	static struct {
95 		const char *name;
96 		int nargs;
97 		int nreturns;
98 		int phandle;
99 		int sibling;
100 	} args = {
101 		"peer",
102 		1,
103 		1,
104 	};
105 
106 	args.phandle = phandle;
107 	if (openfirmware(&args) == -1)
108 		return 0;
109 	return args.sibling;
110 }
111 
112 int
113 OF_child(phandle)
114 	int phandle;
115 {
116 	static struct {
117 		const char *name;
118 		int nargs;
119 		int nreturns;
120 		int phandle;
121 		int child;
122 	} args = {
123 		"child",
124 		1,
125 		1,
126 	};
127 
128 	args.phandle = phandle;
129 	if (openfirmware(&args) == -1)
130 		return 0;
131 	return args.child;
132 }
133 
134 int
135 OF_parent(phandle)
136 	int phandle;
137 {
138 	static struct {
139 		const char *name;
140 		int nargs;
141 		int nreturns;
142 		int phandle;
143 		int parent;
144 	} args = {
145 		"parent",
146 		1,
147 		1,
148 	};
149 
150 	args.phandle = phandle;
151 	if (openfirmware(&args) == -1)
152 		return 0;
153 	return args.parent;
154 }
155 
156 int
157 OF_instance_to_package(ihandle)
158 	int ihandle;
159 {
160 	static struct {
161 		const char *name;
162 		int nargs;
163 		int nreturns;
164 		int ihandle;
165 		int phandle;
166 	} args = {
167 		"instance-to-package",
168 		1,
169 		1,
170 	};
171 
172 	args.ihandle = ihandle;
173 	if (openfirmware(&args) == -1)
174 		return -1;
175 	return args.phandle;
176 }
177 
178 int
179 OF_nextprop(handle, prop, nextprop)
180 	int handle;
181 	const char *prop;
182 	void *nextprop;
183 {
184 	static struct {
185 		const char *name;
186 		int nargs;
187 		int nreturns;
188 		int phandle;
189 		const char *prop;
190 		void *nextprop;
191 		int flags;
192 	} args = {
193 		"nextprop",
194 		3,
195 		1,
196 	};
197 
198 	args.phandle = handle;
199 	args.prop = prop;
200 	args.nextprop = nextprop;
201 
202 	if (openfirmware(&args) == -1)
203 		return -1;
204 	return args.flags;
205 }
206 
207 int
208 OF_getprop(handle, prop, buf, buflen)
209 	int handle;
210 	const char *prop;
211 	void *buf;
212 	int buflen;
213 {
214 	static struct {
215 		const char *name;
216 		int nargs;
217 		int nreturns;
218 		int phandle;
219 		const char *prop;
220 		void *buf;
221 		int buflen;
222 		int size;
223 	} args = {
224 		"getprop",
225 		4,
226 		1,
227 	};
228 
229 	args.phandle = handle;
230 	args.prop = prop;
231 	args.buf = buf;
232 	args.buflen = buflen;
233 
234 
235 	if (openfirmware(&args) == -1)
236 		return -1;
237 	return args.size;
238 }
239 
240 int
241 OF_getproplen(handle, prop)
242 	int handle;
243 	const char *prop;
244 {
245 	static struct {
246 		const char *name;
247 		int nargs;
248 		int nreturns;
249 		int phandle;
250 		const char *prop;
251 		int size;
252 	} args = {
253 		"getproplen",
254 		2,
255 		1,
256 	};
257 
258 	args.phandle = handle;
259 	args.prop = prop;
260 	if (openfirmware(&args) == -1)
261 		return -1;
262 	return args.size;
263 }
264 
265 int
266 OF_finddevice(name)
267 	const char *name;
268 {
269 	static struct {
270 		const char *name;
271 		int nargs;
272 		int nreturns;
273 		const char *device;
274 		int phandle;
275 	} args = {
276 		"finddevice",
277 		1,
278 		1,
279 	};
280 
281 	args.device = name;
282 	if (openfirmware(&args) == -1)
283 		return -1;
284 	return args.phandle;
285 }
286 
287 int
288 OF_instance_to_path(ihandle, buf, buflen)
289 	int ihandle;
290 	char *buf;
291 	int buflen;
292 {
293 	static struct {
294 		const char *name;
295 		int nargs;
296 		int nreturns;
297 		int ihandle;
298 		char *buf;
299 		int buflen;
300 		int length;
301 	} args = {
302 		"instance-to-path",
303 		3,
304 		1,
305 	};
306 
307 	args.ihandle = ihandle;
308 	args.buf = buf;
309 	args.buflen = buflen;
310 	if (openfirmware(&args) < 0)
311 		return -1;
312 	return args.length;
313 }
314 
315 int
316 OF_package_to_path(phandle, buf, buflen)
317 	int phandle;
318 	char *buf;
319 	int buflen;
320 {
321 	static struct {
322 		const char *name;
323 		int nargs;
324 		int nreturns;
325 		int phandle;
326 		char *buf;
327 		int buflen;
328 		int length;
329 	} args = {
330 		"package-to-path",
331 		3,
332 		1,
333 	};
334 
335 	args.phandle = phandle;
336 	args.buf = buf;
337 	args.buflen = buflen;
338 	if (openfirmware(&args) < 0)
339 		return -1;
340 	return args.length;
341 }
342 
343 int
344 #ifdef	__STDC__
345 OF_call_method(const char *method, int ihandle, int nargs, int nreturns, ...)
346 #else
347 OF_call_method(method, ihandle, nargs, nreturns, va_alist)
348 	const char *method;
349 	int ihandle;
350 	int nargs;
351 	int nreturns;
352 	va_dcl
353 #endif
354 {
355 	va_list ap;
356 	static struct {
357 		const char *name;
358 		int nargs;
359 		int nreturns;
360 		const char *method;
361 		int ihandle;
362 		int args_n_results[12];
363 	} args = {
364 		"call-method",
365 		2,
366 		1,
367 	};
368 	int *ip, n;
369 
370 	if (nargs > 6)
371 		return -1;
372 	args.nargs = nargs + 2;
373 	args.nreturns = nreturns + 1;
374 	args.method = method;
375 	args.ihandle = ihandle;
376 	va_start(ap, nreturns);
377 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
378 		*--ip = va_arg(ap, int);
379 	if (openfirmware(&args) == -1) {
380 		va_end(ap);
381 		return -1;
382 	}
383 /*
384 	{
385 	    int i, res;
386 
387 	    printf("call_method(%s): ihandle = %x, nargs = %d, nreturns = %d -- ",
388 		   method, ihandle, nargs, nreturns);
389 	    res = openfirmware(&args);
390 	    printf("res = %x\n", res);
391 	    printf("\targs_n_results = ");
392 	    for (i = 0; i < nargs + nreturns + 1; i++)
393 		printf("%x ", args.args_n_results[i]);
394 	    printf("\n");
395 	    if (res == -1) return -1;
396 	}
397 */
398 	if (args.args_n_results[nargs]) {
399 		va_end(ap);
400 		return args.args_n_results[nargs];
401 	}
402 	for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
403 		*va_arg(ap, int *) = *--ip;
404 	va_end(ap);
405 	return 0;
406 }
407 
408 int
409 #ifdef	__STDC__
410 OF_call_method_1(const char *method, int ihandle, int nargs, ...)
411 #else
412 OF_call_method_1(method, ihandle, nargs, va_alist)
413 	const char *method;
414 	int ihandle;
415 	int nargs;
416 	va_dcl
417 #endif
418 {
419 	va_list ap;
420 	static struct {
421 		const char *name;
422 		int nargs;
423 		int nreturns;
424 		const char *method;
425 		int ihandle;
426 		int args_n_results[8];
427 	} args = {
428 		"call-method",
429 		2,
430 		2,
431 	};
432 	int *ip, n;
433 
434 	if (nargs > 6)
435 		return -1;
436 	args.nargs = nargs + 2;
437 	args.method = method;
438 	args.ihandle = ihandle;
439 	va_start(ap, nargs);
440 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
441 		*--ip = va_arg(ap, int);
442 	va_end(ap);
443 	if (openfirmware(&args) == -1)
444 		return -1;
445 /*
446 	{
447 	    int i, res;
448 
449 	    printf("call_method_1(%s): ihandle = %x, nargs = %d -- ",
450 		   method, ihandle, nargs);
451 	    res = openfirmware(&args);
452 	    printf("res = %x\n", res);
453 	    printf("\targs_n_results = ");
454 	    for (i = 0; i < nargs + 2; i++)
455 		printf("%x ", args.args_n_results[i]);
456 	    printf("\n");
457 	    if (res == -1) return -1;
458 	}
459 */
460 	if (args.args_n_results[nargs])
461 		return -1;
462 	return args.args_n_results[nargs + 1];
463 }
464 
465 int
466 OF_open(dname)
467 	const char *dname;
468 {
469 	static struct {
470 		const char *name;
471 		int nargs;
472 		int nreturns;
473 		const char *dname;
474 		int handle;
475 	} args = {
476 		"open",
477 		1,
478 		1,
479 	};
480 
481 	args.dname = dname;
482 	if (openfirmware(&args) == -1)
483 		return -1;
484 	return args.handle;
485 }
486 
487 void
488 OF_close(handle)
489 	int handle;
490 {
491 	static struct {
492 		const char *name;
493 		int nargs;
494 		int nreturns;
495 		int handle;
496 	} args = {
497 		"close",
498 		1,
499 		0,
500 	};
501 
502 	args.handle = handle;
503 	openfirmware(&args);
504 }
505 
506 int
507 OF_read(handle, addr, len)
508 	int handle;
509 	void *addr;
510 	int len;
511 {
512 	static struct {
513 		const char *name;
514 		int nargs;
515 		int nreturns;
516 		int ihandle;
517 		void *addr;
518 		int len;
519 		int actual;
520 	} args = {
521 		"read",
522 		3,
523 		1,
524 	};
525 
526 	args.ihandle = handle;
527 	args.addr = addr;
528 	args.len = len;
529 	if (openfirmware(&args) == -1)
530 		return -1;
531 	return args.actual;
532 }
533 
534 int
535 OF_write(handle, addr, len)
536 	int handle;
537 	const void *addr;
538 	int len;
539 {
540 	static struct {
541 		const char *name;
542 		int nargs;
543 		int nreturns;
544 		int ihandle;
545 		const void *addr;
546 		int len;
547 		int actual;
548 	} args = {
549 		"write",
550 		3,
551 		1,
552 	};
553 
554 	args.ihandle = handle;
555 	args.addr = addr;
556 	args.len = len;
557 	if (openfirmware(&args) == -1)
558 		return -1;
559 	return args.actual;
560 }
561 
562 int
563 OF_seek(handle, pos)
564 	int handle;
565 	u_quad_t pos;
566 {
567 	static struct {
568 		const char *name;
569 		int nargs;
570 		int nreturns;
571 		int handle;
572 		int poshi;
573 		int poslo;
574 		int status;
575 	} args = {
576 		"seek",
577 		3,
578 		1,
579 	};
580 
581 	args.handle = handle;
582 	args.poshi = (int)(pos >> 32);
583 	args.poslo = (int)pos;
584 	if (openfirmware(&args) == -1)
585 		return -1;
586 	return args.status;
587 }
588 
589 void *
590 OF_claim(virt, size, align)
591         void *virt;
592         u_int size;
593         u_int align;
594 {
595         static struct {
596                 const char *name;
597                 int nargs;
598                 int nreturns;
599                 void *virt;
600                 u_int size;
601                 u_int align;
602                 void *baseaddr;
603         } args = {
604                 "claim",
605                 3,
606                 1,
607         };
608 
609         args.virt = virt;
610         args.size = size;
611         args.align = align;
612         if (openfirmware(&args) == -1)
613                 return (void *)-1;
614         return args.baseaddr;
615 }
616 
617 void
618 OF_release(virt, size)
619         void *virt;
620         u_int size;
621 {
622         static struct {
623                 const char *name;
624                 int nargs;
625                 int nreturns;
626                 void *virt;
627                 u_int size;
628         } args = {
629                 "release",
630                 2,
631                 0,
632         };
633 
634         args.virt = virt;
635         args.size = size;
636         openfirmware(&args);
637 }
638 
639 int
640 OF_milliseconds()
641 {
642         static struct {
643                 const char *name;
644                 int nargs;
645                 int nreturns;
646                 int ms;
647         } args = {
648                 "milliseconds",
649                 0,
650                 1,
651         };
652 
653         openfirmware(&args);
654         return args.ms;
655 }
656 
657 void
658 OF_boot(bootspec)
659 	const char *bootspec;
660 {
661 	static struct {
662 		const char *name;
663 		int nargs;
664 		int nreturns;
665 		const char *bootspec;
666 	} args = {
667 		"boot",
668 		1,
669 		0,
670 	};
671 
672 	args.bootspec = bootspec;
673 	openfirmware(&args);
674 	while (1);			/* just in case */
675 }
676 
677 void
678 OF_enter()
679 {
680 	static struct {
681 		const char *name;
682 		int nargs;
683 		int nreturns;
684 	} args = {
685 		"enter",
686 		0,
687 		0,
688 	};
689 
690 	openfirmware(&args);
691 }
692 
693 void
694 OF_exit()
695 {
696 	static struct {
697 		const char *name;
698 		int nargs;
699 		int nreturns;
700 	} args = {
701 		"exit",
702 		0,
703 		0,
704 	};
705 
706 	openfirmware(&args);
707 	while (1);			/* just in case */
708 }
709 
710 void
711 (*OF_set_callback(newfunc))(void *)
712 	void (*newfunc)(void *);
713 {
714 	static struct {
715 		const char *name;
716 		int nargs;
717 		int nreturns;
718 		void (*newfunc)(void *);
719 		void (*oldfunc)(void *);
720 	} args = {
721 		"set-callback",
722 		1,
723 		1,
724 	};
725 
726 	args.newfunc = newfunc;
727 	if (openfirmware(&args) == -1)
728 		return 0;
729 	return args.oldfunc;
730 }
731