xref: /netbsd-src/sys/arch/arm/ofw/openfirm.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /*	$NetBSD: openfirm.c,v 1.6 2007/02/28 20:31:40 macallan 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.6 2007/02/28 20:31:40 macallan 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_setprop(handle, prop, buf, buflen)
242 	int handle;
243 	const char *prop;
244 	const void *buf;
245 	int buflen;
246 {
247 	static struct {
248 		const char *name;
249 		int nargs;
250 		int nreturns;
251 		int phandle;
252 		const char *prop;
253 		const void *buf;
254 		int buflen;
255 		int size;
256 	} args = {
257 		"setprop",
258 		4,
259 		1,
260 	};
261 
262 	args.phandle = handle;
263 	args.prop = prop;
264 	args.buf = buf;
265 	args.buflen = buflen;
266 
267 
268 	if (openfirmware(&args) == -1)
269 		return -1;
270 	return args.size;
271 }
272 
273 int
274 OF_getproplen(handle, prop)
275 	int handle;
276 	const char *prop;
277 {
278 	static struct {
279 		const char *name;
280 		int nargs;
281 		int nreturns;
282 		int phandle;
283 		const char *prop;
284 		int size;
285 	} args = {
286 		"getproplen",
287 		2,
288 		1,
289 	};
290 
291 	args.phandle = handle;
292 	args.prop = prop;
293 	if (openfirmware(&args) == -1)
294 		return -1;
295 	return args.size;
296 }
297 
298 int
299 OF_finddevice(name)
300 	const char *name;
301 {
302 	static struct {
303 		const char *name;
304 		int nargs;
305 		int nreturns;
306 		const char *device;
307 		int phandle;
308 	} args = {
309 		"finddevice",
310 		1,
311 		1,
312 	};
313 
314 	args.device = name;
315 	if (openfirmware(&args) == -1)
316 		return -1;
317 	return args.phandle;
318 }
319 
320 int
321 OF_instance_to_path(ihandle, buf, buflen)
322 	int ihandle;
323 	char *buf;
324 	int buflen;
325 {
326 	static struct {
327 		const char *name;
328 		int nargs;
329 		int nreturns;
330 		int ihandle;
331 		char *buf;
332 		int buflen;
333 		int length;
334 	} args = {
335 		"instance-to-path",
336 		3,
337 		1,
338 	};
339 
340 	args.ihandle = ihandle;
341 	args.buf = buf;
342 	args.buflen = buflen;
343 	if (openfirmware(&args) < 0)
344 		return -1;
345 	return args.length;
346 }
347 
348 int
349 OF_package_to_path(phandle, buf, buflen)
350 	int phandle;
351 	char *buf;
352 	int buflen;
353 {
354 	static struct {
355 		const char *name;
356 		int nargs;
357 		int nreturns;
358 		int phandle;
359 		char *buf;
360 		int buflen;
361 		int length;
362 	} args = {
363 		"package-to-path",
364 		3,
365 		1,
366 	};
367 
368 	args.phandle = phandle;
369 	args.buf = buf;
370 	args.buflen = buflen;
371 	if (openfirmware(&args) < 0)
372 		return -1;
373 	return args.length;
374 }
375 
376 int
377 #ifdef	__STDC__
378 OF_call_method(const char *method, int ihandle, int nargs, int nreturns, ...)
379 #else
380 OF_call_method(method, ihandle, nargs, nreturns, va_alist)
381 	const char *method;
382 	int ihandle;
383 	int nargs;
384 	int nreturns;
385 	va_dcl
386 #endif
387 {
388 	va_list ap;
389 	static struct {
390 		const char *name;
391 		int nargs;
392 		int nreturns;
393 		const char *method;
394 		int ihandle;
395 		int args_n_results[12];
396 	} args = {
397 		"call-method",
398 		2,
399 		1,
400 	};
401 	int *ip, n;
402 
403 	if (nargs > 6)
404 		return -1;
405 	args.nargs = nargs + 2;
406 	args.nreturns = nreturns + 1;
407 	args.method = method;
408 	args.ihandle = ihandle;
409 	va_start(ap, nreturns);
410 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
411 		*--ip = va_arg(ap, int);
412 	if (openfirmware(&args) == -1) {
413 		va_end(ap);
414 		return -1;
415 	}
416 /*
417 	{
418 	    int i, res;
419 
420 	    printf("call_method(%s): ihandle = %x, nargs = %d, nreturns = %d -- ",
421 		   method, ihandle, nargs, nreturns);
422 	    res = openfirmware(&args);
423 	    printf("res = %x\n", res);
424 	    printf("\targs_n_results = ");
425 	    for (i = 0; i < nargs + nreturns + 1; i++)
426 		printf("%x ", args.args_n_results[i]);
427 	    printf("\n");
428 	    if (res == -1) return -1;
429 	}
430 */
431 	if (args.args_n_results[nargs]) {
432 		va_end(ap);
433 		return args.args_n_results[nargs];
434 	}
435 	for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
436 		*va_arg(ap, int *) = *--ip;
437 	va_end(ap);
438 	return 0;
439 }
440 
441 int
442 #ifdef	__STDC__
443 OF_call_method_1(const char *method, int ihandle, int nargs, ...)
444 #else
445 OF_call_method_1(method, ihandle, nargs, va_alist)
446 	const char *method;
447 	int ihandle;
448 	int nargs;
449 	va_dcl
450 #endif
451 {
452 	va_list ap;
453 	static struct {
454 		const char *name;
455 		int nargs;
456 		int nreturns;
457 		const char *method;
458 		int ihandle;
459 		int args_n_results[8];
460 	} args = {
461 		"call-method",
462 		2,
463 		2,
464 	};
465 	int *ip, n;
466 
467 	if (nargs > 6)
468 		return -1;
469 	args.nargs = nargs + 2;
470 	args.method = method;
471 	args.ihandle = ihandle;
472 	va_start(ap, nargs);
473 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
474 		*--ip = va_arg(ap, int);
475 	va_end(ap);
476 	if (openfirmware(&args) == -1)
477 		return -1;
478 /*
479 	{
480 	    int i, res;
481 
482 	    printf("call_method_1(%s): ihandle = %x, nargs = %d -- ",
483 		   method, ihandle, nargs);
484 	    res = openfirmware(&args);
485 	    printf("res = %x\n", res);
486 	    printf("\targs_n_results = ");
487 	    for (i = 0; i < nargs + 2; i++)
488 		printf("%x ", args.args_n_results[i]);
489 	    printf("\n");
490 	    if (res == -1) return -1;
491 	}
492 */
493 	if (args.args_n_results[nargs])
494 		return -1;
495 	return args.args_n_results[nargs + 1];
496 }
497 
498 int
499 OF_open(dname)
500 	const char *dname;
501 {
502 	static struct {
503 		const char *name;
504 		int nargs;
505 		int nreturns;
506 		const char *dname;
507 		int handle;
508 	} args = {
509 		"open",
510 		1,
511 		1,
512 	};
513 
514 	args.dname = dname;
515 	if (openfirmware(&args) == -1)
516 		return -1;
517 	return args.handle;
518 }
519 
520 void
521 OF_close(handle)
522 	int handle;
523 {
524 	static struct {
525 		const char *name;
526 		int nargs;
527 		int nreturns;
528 		int handle;
529 	} args = {
530 		"close",
531 		1,
532 		0,
533 	};
534 
535 	args.handle = handle;
536 	openfirmware(&args);
537 }
538 
539 int
540 OF_read(handle, addr, len)
541 	int handle;
542 	void *addr;
543 	int len;
544 {
545 	static struct {
546 		const char *name;
547 		int nargs;
548 		int nreturns;
549 		int ihandle;
550 		void *addr;
551 		int len;
552 		int actual;
553 	} args = {
554 		"read",
555 		3,
556 		1,
557 	};
558 
559 	args.ihandle = handle;
560 	args.addr = addr;
561 	args.len = len;
562 	if (openfirmware(&args) == -1)
563 		return -1;
564 	return args.actual;
565 }
566 
567 int
568 OF_write(handle, addr, len)
569 	int handle;
570 	const void *addr;
571 	int len;
572 {
573 	static struct {
574 		const char *name;
575 		int nargs;
576 		int nreturns;
577 		int ihandle;
578 		const void *addr;
579 		int len;
580 		int actual;
581 	} args = {
582 		"write",
583 		3,
584 		1,
585 	};
586 
587 	args.ihandle = handle;
588 	args.addr = addr;
589 	args.len = len;
590 	if (openfirmware(&args) == -1)
591 		return -1;
592 	return args.actual;
593 }
594 
595 int
596 OF_seek(handle, pos)
597 	int handle;
598 	u_quad_t pos;
599 {
600 	static struct {
601 		const char *name;
602 		int nargs;
603 		int nreturns;
604 		int handle;
605 		int poshi;
606 		int poslo;
607 		int status;
608 	} args = {
609 		"seek",
610 		3,
611 		1,
612 	};
613 
614 	args.handle = handle;
615 	args.poshi = (int)(pos >> 32);
616 	args.poslo = (int)pos;
617 	if (openfirmware(&args) == -1)
618 		return -1;
619 	return args.status;
620 }
621 
622 void *
623 OF_claim(virt, size, align)
624         void *virt;
625         u_int size;
626         u_int align;
627 {
628         static struct {
629                 const char *name;
630                 int nargs;
631                 int nreturns;
632                 void *virt;
633                 u_int size;
634                 u_int align;
635                 void *baseaddr;
636         } args = {
637                 "claim",
638                 3,
639                 1,
640         };
641 
642         args.virt = virt;
643         args.size = size;
644         args.align = align;
645         if (openfirmware(&args) == -1)
646                 return (void *)-1;
647         return args.baseaddr;
648 }
649 
650 void
651 OF_release(virt, size)
652         void *virt;
653         u_int size;
654 {
655         static struct {
656                 const char *name;
657                 int nargs;
658                 int nreturns;
659                 void *virt;
660                 u_int size;
661         } args = {
662                 "release",
663                 2,
664                 0,
665         };
666 
667         args.virt = virt;
668         args.size = size;
669         openfirmware(&args);
670 }
671 
672 int
673 OF_milliseconds()
674 {
675         static struct {
676                 const char *name;
677                 int nargs;
678                 int nreturns;
679                 int ms;
680         } args = {
681                 "milliseconds",
682                 0,
683                 1,
684         };
685 
686         openfirmware(&args);
687         return args.ms;
688 }
689 
690 void
691 OF_boot(bootspec)
692 	const char *bootspec;
693 {
694 	static struct {
695 		const char *name;
696 		int nargs;
697 		int nreturns;
698 		const char *bootspec;
699 	} args = {
700 		"boot",
701 		1,
702 		0,
703 	};
704 
705 	args.bootspec = bootspec;
706 	openfirmware(&args);
707 	while (1);			/* just in case */
708 }
709 
710 void
711 OF_enter()
712 {
713 	static struct {
714 		const char *name;
715 		int nargs;
716 		int nreturns;
717 	} args = {
718 		"enter",
719 		0,
720 		0,
721 	};
722 
723 	openfirmware(&args);
724 }
725 
726 void
727 OF_exit()
728 {
729 	static struct {
730 		const char *name;
731 		int nargs;
732 		int nreturns;
733 	} args = {
734 		"exit",
735 		0,
736 		0,
737 	};
738 
739 	openfirmware(&args);
740 	while (1);			/* just in case */
741 }
742 
743 void
744 (*OF_set_callback(newfunc))(void *)
745 	void (*newfunc)(void *);
746 {
747 	static struct {
748 		const char *name;
749 		int nargs;
750 		int nreturns;
751 		void (*newfunc)(void *);
752 		void (*oldfunc)(void *);
753 	} args = {
754 		"set-callback",
755 		1,
756 		1,
757 	};
758 
759 	args.newfunc = newfunc;
760 	if (openfirmware(&args) == -1)
761 		return 0;
762 	return args.oldfunc;
763 }
764