openfirm.c revision 1.4.2.1 1 /* $NetBSD: openfirm.c,v 1.4.2.1 2007/09/03 14:23:23 yamt 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.4.2.1 2007/09/03 14:23:23 yamt 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