xref: /netbsd-src/sys/arch/arm/ofw/openfirm.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: openfirm.c,v 1.8 2009/03/18 10:22:24 cegger 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.8 2009/03/18 10:22:24 cegger 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(int phandle)
92 {
93 	static struct {
94 		const char *name;
95 		int nargs;
96 		int nreturns;
97 		int phandle;
98 		int sibling;
99 	} args = {
100 		"peer",
101 		1,
102 		1,
103 	};
104 
105 	args.phandle = phandle;
106 	if (openfirmware(&args) == -1)
107 		return 0;
108 	return args.sibling;
109 }
110 
111 int
112 OF_child(int phandle)
113 {
114 	static struct {
115 		const char *name;
116 		int nargs;
117 		int nreturns;
118 		int phandle;
119 		int child;
120 	} args = {
121 		"child",
122 		1,
123 		1,
124 	};
125 
126 	args.phandle = phandle;
127 	if (openfirmware(&args) == -1)
128 		return 0;
129 	return args.child;
130 }
131 
132 int
133 OF_parent(int phandle)
134 {
135 	static struct {
136 		const char *name;
137 		int nargs;
138 		int nreturns;
139 		int phandle;
140 		int parent;
141 	} args = {
142 		"parent",
143 		1,
144 		1,
145 	};
146 
147 	args.phandle = phandle;
148 	if (openfirmware(&args) == -1)
149 		return 0;
150 	return args.parent;
151 }
152 
153 int
154 OF_instance_to_package(int ihandle)
155 {
156 	static struct {
157 		const char *name;
158 		int nargs;
159 		int nreturns;
160 		int ihandle;
161 		int phandle;
162 	} args = {
163 		"instance-to-package",
164 		1,
165 		1,
166 	};
167 
168 	args.ihandle = ihandle;
169 	if (openfirmware(&args) == -1)
170 		return -1;
171 	return args.phandle;
172 }
173 
174 int
175 OF_nextprop(int handle, const char *prop, void *nextprop)
176 {
177 	static struct {
178 		const char *name;
179 		int nargs;
180 		int nreturns;
181 		int phandle;
182 		const char *prop;
183 		void *nextprop;
184 		int flags;
185 	} args = {
186 		"nextprop",
187 		3,
188 		1,
189 	};
190 
191 	args.phandle = handle;
192 	args.prop = prop;
193 	args.nextprop = nextprop;
194 
195 	if (openfirmware(&args) == -1)
196 		return -1;
197 	return args.flags;
198 }
199 
200 int
201 OF_getprop(int handle, const char *prop, void *buf, int buflen)
202 {
203 	static struct {
204 		const char *name;
205 		int nargs;
206 		int nreturns;
207 		int phandle;
208 		const char *prop;
209 		void *buf;
210 		int buflen;
211 		int size;
212 	} args = {
213 		"getprop",
214 		4,
215 		1,
216 	};
217 
218 	args.phandle = handle;
219 	args.prop = prop;
220 	args.buf = buf;
221 	args.buflen = buflen;
222 
223 
224 	if (openfirmware(&args) == -1)
225 		return -1;
226 	return args.size;
227 }
228 
229 int
230 OF_setprop(int handle, const char *prop, const void *buf, int buflen)
231 {
232 	static struct {
233 		const char *name;
234 		int nargs;
235 		int nreturns;
236 		int phandle;
237 		const char *prop;
238 		const void *buf;
239 		int buflen;
240 		int size;
241 	} args = {
242 		"setprop",
243 		4,
244 		1,
245 	};
246 
247 	args.phandle = handle;
248 	args.prop = prop;
249 	args.buf = buf;
250 	args.buflen = buflen;
251 
252 
253 	if (openfirmware(&args) == -1)
254 		return -1;
255 	return args.size;
256 }
257 
258 int
259 OF_getproplen(int handle, const char *prop)
260 {
261 	static struct {
262 		const char *name;
263 		int nargs;
264 		int nreturns;
265 		int phandle;
266 		const char *prop;
267 		int size;
268 	} args = {
269 		"getproplen",
270 		2,
271 		1,
272 	};
273 
274 	args.phandle = handle;
275 	args.prop = prop;
276 	if (openfirmware(&args) == -1)
277 		return -1;
278 	return args.size;
279 }
280 
281 int
282 OF_finddevice(const char *name)
283 {
284 	static struct {
285 		const char *name;
286 		int nargs;
287 		int nreturns;
288 		const char *device;
289 		int phandle;
290 	} args = {
291 		"finddevice",
292 		1,
293 		1,
294 	};
295 
296 	args.device = name;
297 	if (openfirmware(&args) == -1)
298 		return -1;
299 	return args.phandle;
300 }
301 
302 int
303 OF_instance_to_path(int ihandle, char *buf, int buflen)
304 {
305 	static struct {
306 		const char *name;
307 		int nargs;
308 		int nreturns;
309 		int ihandle;
310 		char *buf;
311 		int buflen;
312 		int length;
313 	} args = {
314 		"instance-to-path",
315 		3,
316 		1,
317 	};
318 
319 	args.ihandle = ihandle;
320 	args.buf = buf;
321 	args.buflen = buflen;
322 	if (openfirmware(&args) < 0)
323 		return -1;
324 	return args.length;
325 }
326 
327 int
328 OF_package_to_path(int phandle, char *buf, int buflen)
329 {
330 	static struct {
331 		const char *name;
332 		int nargs;
333 		int nreturns;
334 		int phandle;
335 		char *buf;
336 		int buflen;
337 		int length;
338 	} args = {
339 		"package-to-path",
340 		3,
341 		1,
342 	};
343 
344 	args.phandle = phandle;
345 	args.buf = buf;
346 	args.buflen = buflen;
347 	if (openfirmware(&args) < 0)
348 		return -1;
349 	return args.length;
350 }
351 
352 int
353 #ifdef	__STDC__
354 OF_call_method(const char *method, int ihandle, int nargs, int nreturns, ...)
355 #else
356 OF_call_method(method, ihandle, nargs, nreturns, va_alist)
357 	const char *method;
358 	int ihandle;
359 	int nargs;
360 	int nreturns;
361 	va_dcl
362 #endif
363 {
364 	va_list ap;
365 	static struct {
366 		const char *name;
367 		int nargs;
368 		int nreturns;
369 		const char *method;
370 		int ihandle;
371 		int args_n_results[12];
372 	} args = {
373 		"call-method",
374 		2,
375 		1,
376 	};
377 	int *ip, n;
378 
379 	if (nargs > 6)
380 		return -1;
381 	args.nargs = nargs + 2;
382 	args.nreturns = nreturns + 1;
383 	args.method = method;
384 	args.ihandle = ihandle;
385 	va_start(ap, nreturns);
386 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
387 		*--ip = va_arg(ap, int);
388 	if (openfirmware(&args) == -1) {
389 		va_end(ap);
390 		return -1;
391 	}
392 /*
393 	{
394 	    int i, res;
395 
396 	    printf("call_method(%s): ihandle = %x, nargs = %d, nreturns = %d -- ",
397 		   method, ihandle, nargs, nreturns);
398 	    res = openfirmware(&args);
399 	    printf("res = %x\n", res);
400 	    printf("\targs_n_results = ");
401 	    for (i = 0; i < nargs + nreturns + 1; i++)
402 		printf("%x ", args.args_n_results[i]);
403 	    printf("\n");
404 	    if (res == -1) return -1;
405 	}
406 */
407 	if (args.args_n_results[nargs]) {
408 		va_end(ap);
409 		return args.args_n_results[nargs];
410 	}
411 	for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
412 		*va_arg(ap, int *) = *--ip;
413 	va_end(ap);
414 	return 0;
415 }
416 
417 int
418 #ifdef	__STDC__
419 OF_call_method_1(const char *method, int ihandle, int nargs, ...)
420 #else
421 OF_call_method_1(method, ihandle, nargs, va_alist)
422 	const char *method;
423 	int ihandle;
424 	int nargs;
425 	va_dcl
426 #endif
427 {
428 	va_list ap;
429 	static struct {
430 		const char *name;
431 		int nargs;
432 		int nreturns;
433 		const char *method;
434 		int ihandle;
435 		int args_n_results[8];
436 	} args = {
437 		"call-method",
438 		2,
439 		2,
440 	};
441 	int *ip, n;
442 
443 	if (nargs > 6)
444 		return -1;
445 	args.nargs = nargs + 2;
446 	args.method = method;
447 	args.ihandle = ihandle;
448 	va_start(ap, nargs);
449 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
450 		*--ip = va_arg(ap, int);
451 	va_end(ap);
452 	if (openfirmware(&args) == -1)
453 		return -1;
454 /*
455 	{
456 	    int i, res;
457 
458 	    printf("call_method_1(%s): ihandle = %x, nargs = %d -- ",
459 		   method, ihandle, nargs);
460 	    res = openfirmware(&args);
461 	    printf("res = %x\n", res);
462 	    printf("\targs_n_results = ");
463 	    for (i = 0; i < nargs + 2; i++)
464 		printf("%x ", args.args_n_results[i]);
465 	    printf("\n");
466 	    if (res == -1) return -1;
467 	}
468 */
469 	if (args.args_n_results[nargs])
470 		return -1;
471 	return args.args_n_results[nargs + 1];
472 }
473 
474 int
475 OF_open(const char *dname)
476 {
477 	static struct {
478 		const char *name;
479 		int nargs;
480 		int nreturns;
481 		const char *dname;
482 		int handle;
483 	} args = {
484 		"open",
485 		1,
486 		1,
487 	};
488 
489 	args.dname = dname;
490 	if (openfirmware(&args) == -1)
491 		return -1;
492 	return args.handle;
493 }
494 
495 void
496 OF_close(int handle)
497 {
498 	static struct {
499 		const char *name;
500 		int nargs;
501 		int nreturns;
502 		int handle;
503 	} args = {
504 		"close",
505 		1,
506 		0,
507 	};
508 
509 	args.handle = handle;
510 	openfirmware(&args);
511 }
512 
513 int
514 OF_read(int handle, void *addr, int len)
515 {
516 	static struct {
517 		const char *name;
518 		int nargs;
519 		int nreturns;
520 		int ihandle;
521 		void *addr;
522 		int len;
523 		int actual;
524 	} args = {
525 		"read",
526 		3,
527 		1,
528 	};
529 
530 	args.ihandle = handle;
531 	args.addr = addr;
532 	args.len = len;
533 	if (openfirmware(&args) == -1)
534 		return -1;
535 	return args.actual;
536 }
537 
538 int
539 OF_write(int handle, const void *addr, int len)
540 {
541 	static struct {
542 		const char *name;
543 		int nargs;
544 		int nreturns;
545 		int ihandle;
546 		const void *addr;
547 		int len;
548 		int actual;
549 	} args = {
550 		"write",
551 		3,
552 		1,
553 	};
554 
555 	args.ihandle = handle;
556 	args.addr = addr;
557 	args.len = len;
558 	if (openfirmware(&args) == -1)
559 		return -1;
560 	return args.actual;
561 }
562 
563 int
564 OF_seek(int handle, u_quad_t pos)
565 {
566 	static struct {
567 		const char *name;
568 		int nargs;
569 		int nreturns;
570 		int handle;
571 		int poshi;
572 		int poslo;
573 		int status;
574 	} args = {
575 		"seek",
576 		3,
577 		1,
578 	};
579 
580 	args.handle = handle;
581 	args.poshi = (int)(pos >> 32);
582 	args.poslo = (int)pos;
583 	if (openfirmware(&args) == -1)
584 		return -1;
585 	return args.status;
586 }
587 
588 void *
589 OF_claim(void *virt, u_int size, u_int align)
590 {
591         static struct {
592                 const char *name;
593                 int nargs;
594                 int nreturns;
595                 void *virt;
596                 u_int size;
597                 u_int align;
598                 void *baseaddr;
599         } args = {
600                 "claim",
601                 3,
602                 1,
603         };
604 
605         args.virt = virt;
606         args.size = size;
607         args.align = align;
608         if (openfirmware(&args) == -1)
609                 return (void *)-1;
610         return args.baseaddr;
611 }
612 
613 void
614 OF_release(void *virt, u_int size)
615 {
616         static struct {
617                 const char *name;
618                 int nargs;
619                 int nreturns;
620                 void *virt;
621                 u_int size;
622         } args = {
623                 "release",
624                 2,
625                 0,
626         };
627 
628         args.virt = virt;
629         args.size = size;
630         openfirmware(&args);
631 }
632 
633 int
634 OF_milliseconds(void)
635 {
636         static struct {
637                 const char *name;
638                 int nargs;
639                 int nreturns;
640                 int ms;
641         } args = {
642                 "milliseconds",
643                 0,
644                 1,
645         };
646 
647         openfirmware(&args);
648         return args.ms;
649 }
650 
651 void
652 OF_boot(const char *bootspec)
653 {
654 	static struct {
655 		const char *name;
656 		int nargs;
657 		int nreturns;
658 		const char *bootspec;
659 	} args = {
660 		"boot",
661 		1,
662 		0,
663 	};
664 
665 	args.bootspec = bootspec;
666 	openfirmware(&args);
667 	while (1);			/* just in case */
668 }
669 
670 void
671 OF_enter(void)
672 {
673 	static struct {
674 		const char *name;
675 		int nargs;
676 		int nreturns;
677 	} args = {
678 		"enter",
679 		0,
680 		0,
681 	};
682 
683 	openfirmware(&args);
684 }
685 
686 void
687 OF_exit(void)
688 {
689 	static struct {
690 		const char *name;
691 		int nargs;
692 		int nreturns;
693 	} args = {
694 		"exit",
695 		0,
696 		0,
697 	};
698 
699 	openfirmware(&args);
700 	while (1);			/* just in case */
701 }
702 
703 void
704 (*OF_set_callback(newfunc))(void *)
705 	void (*newfunc)(void *);
706 {
707 	static struct {
708 		const char *name;
709 		int nargs;
710 		int nreturns;
711 		void (*newfunc)(void *);
712 		void (*oldfunc)(void *);
713 	} args = {
714 		"set-callback",
715 		1,
716 		1,
717 	};
718 
719 	args.newfunc = newfunc;
720 	if (openfirmware(&args) == -1)
721 		return 0;
722 	return args.oldfunc;
723 }
724