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