openfirm.c revision 1.2.8.2 1 /* $NetBSD: openfirm.c,v 1.2.8.2 2004/09/18 14:32:38 skrll 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.2.8.2 2004/09/18 14:32:38 skrll 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 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 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 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 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 char *prop;
182 void *nextprop;
183 {
184 static struct {
185 char *name;
186 int nargs;
187 int nreturns;
188 int phandle;
189 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 char *prop;
211 void *buf;
212 int buflen;
213 {
214 static struct {
215 char *name;
216 int nargs;
217 int nreturns;
218 int phandle;
219 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 char *prop;
244 {
245 static struct {
246 char *name;
247 int nargs;
248 int nreturns;
249 int phandle;
250 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 char *name;
268 {
269 static struct {
270 char *name;
271 int nargs;
272 int nreturns;
273 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 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 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(char *method, int ihandle, int nargs, int nreturns, ...)
346 #else
347 OF_call_method(method, ihandle, nargs, nreturns, va_alist)
348 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 char *name;
358 int nargs;
359 int nreturns;
360 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(char *method, int ihandle, int nargs, ...)
411 #else
412 OF_call_method_1(method, ihandle, nargs, va_alist)
413 char *method;
414 int ihandle;
415 int nargs;
416 va_dcl
417 #endif
418 {
419 va_list ap;
420 static struct {
421 char *name;
422 int nargs;
423 int nreturns;
424 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 char *dname;
468 {
469 static struct {
470 char *name;
471 int nargs;
472 int nreturns;
473 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 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 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 void *addr;
538 int len;
539 {
540 static struct {
541 char *name;
542 int nargs;
543 int nreturns;
544 int ihandle;
545 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 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 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 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 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 char *bootspec;
660 {
661 static struct {
662 char *name;
663 int nargs;
664 int nreturns;
665 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 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 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 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