1 /* $NetBSD: openfirm.c,v 1.24 2021/02/27 18:10:46 palle Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.24 2021/02/27 18:10:46 palle Exp $");
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <machine/lock.h>
40 #include <machine/psl.h>
41 #include <machine/promlib.h>
42 #include <lib/libkern/libkern.h>
43
44 #ifndef _KERNEL
45 #include <sys/stdarg.h>
46 #endif
47
48 #ifdef SUN4V
49 #ifdef __arch64__
50 #define OFBOUNCE_MAXSIZE 1024
51 /*
52 * Sun4v OpenBoot is not always happy with 64-bit addresses - an example is the
53 * addr parameter in the OF_write() call which can be truncated to a 32-bit
54 * value.
55 * Avoid this behaviour by using a static buffer which is assumed to be mapped
56 * in on a 32-bit address.
57 * Use a mutex to protect access to the buffer from multiple threads.
58 *
59 */
60 static __cpu_simple_lock_t ofcall_lock;
61 static char ofbounce[OFBOUNCE_MAXSIZE];
62 #endif
63 #endif
64
65 void
OF_init(void)66 OF_init(void)
67 {
68 #ifdef SUN4V
69 #ifdef __arch64__
70 KASSERT(((uint64_t)&ofbounce & 0xffffffffUL)==(uint64_t)&ofbounce);
71 __cpu_simple_lock_init(&ofcall_lock);
72 #endif
73 #endif
74 }
75
76 int
OF_peer(int phandle)77 OF_peer(int phandle)
78 {
79 struct {
80 cell_t name;
81 cell_t nargs;
82 cell_t nreturns;
83 cell_t phandle;
84 cell_t sibling;
85 } args;
86
87 args.name = ADR2CELL("peer");
88 args.nargs = 1;
89 args.nreturns = 1;
90 args.phandle = HDL2CELL(phandle);
91 if (openfirmware(&args) == -1)
92 return 0;
93 return args.sibling;
94 }
95
96 int
OF_child(int phandle)97 OF_child(int phandle)
98 {
99 struct {
100 cell_t name;
101 cell_t nargs;
102 cell_t nreturns;
103 cell_t phandle;
104 cell_t child;
105 } args;
106
107 args.name = ADR2CELL("child");
108 args.nargs = 1;
109 args.nreturns = 1;
110 args.phandle = HDL2CELL(phandle);
111 if (openfirmware(&args) == -1)
112 return 0;
113 return args.child;
114 }
115
116 int
OF_parent(int phandle)117 OF_parent(int phandle)
118 {
119 struct {
120 cell_t name;
121 cell_t nargs;
122 cell_t nreturns;
123 cell_t phandle;
124 cell_t parent;
125 } args;
126
127 args.name = ADR2CELL("parent");
128 args.nargs = 1;
129 args.nreturns = 1;
130 args.phandle = HDL2CELL(phandle);
131 if (openfirmware(&args) == -1)
132 return 0;
133 return args.parent;
134 }
135
136 int
OF_instance_to_package(int ihandle)137 OF_instance_to_package(int ihandle)
138 {
139 static struct {
140 cell_t name;
141 cell_t nargs;
142 cell_t nreturns;
143 cell_t ihandle;
144 cell_t phandle;
145 } args;
146
147 args.name = ADR2CELL("instance-to-package");
148 args.nargs = 1;
149 args.nreturns = 1;
150 args.ihandle = HDL2CELL(ihandle);
151 if (openfirmware(&args) == -1)
152 return -1;
153 return args.phandle;
154 }
155
156 /* Should really return a `long' */
157 int
OF_getproplen(int handle,const char * prop)158 OF_getproplen(int handle, const char *prop)
159 {
160 struct {
161 cell_t name;
162 cell_t nargs;
163 cell_t nreturns;
164 cell_t phandle;
165 cell_t prop;
166 cell_t size;
167 } args;
168
169 KASSERT(handle != 0);
170 args.name = ADR2CELL("getproplen");
171 args.nargs = 2;
172 args.nreturns = 1;
173 args.phandle = HDL2CELL(handle);
174 args.prop = ADR2CELL(prop);
175 if (openfirmware(&args) == -1)
176 return -1;
177 return args.size;
178 }
179
180 int
OF_getprop(int handle,const char * prop,void * buf,int buflen)181 OF_getprop(int handle, const char *prop, void *buf, int buflen)
182 {
183 struct {
184 cell_t name;
185 cell_t nargs;
186 cell_t nreturns;
187 cell_t phandle;
188 cell_t prop;
189 cell_t buf;
190 cell_t buflen;
191 cell_t size;
192 } args;
193
194 KASSERT(handle != 0);
195 if (buflen > NBPG)
196 return -1;
197 args.name = ADR2CELL("getprop");
198 args.nargs = 4;
199 args.nreturns = 1;
200 args.phandle = HDL2CELL(handle);
201 args.prop = ADR2CELL(prop);
202 args.buf = ADR2CELL(buf);
203 args.buflen = buflen;
204 if (openfirmware(&args) == -1)
205 return -1;
206 return args.size;
207 }
208
209 int
OF_setprop(int handle,const char * prop,const void * buf,int buflen)210 OF_setprop(int handle, const char *prop, const void *buf, int buflen)
211 {
212 struct {
213 cell_t name;
214 cell_t nargs;
215 cell_t nreturns;
216 cell_t phandle;
217 cell_t prop;
218 cell_t buf;
219 cell_t buflen;
220 cell_t size;
221 } args;
222
223 if (buflen > NBPG)
224 return -1;
225 args.name = ADR2CELL("setprop");
226 args.nargs = 4;
227 args.nreturns = 1;
228 args.phandle = HDL2CELL(handle);
229 args.prop = ADR2CELL(prop);
230 args.buf = ADR2CELL(buf);
231 args.buflen = buflen;
232 if (openfirmware(&args) == -1)
233 return -1;
234 return args.size;
235 }
236
237 int
OF_nextprop(int handle,const char * prop,void * buf)238 OF_nextprop(int handle, const char *prop, void *buf)
239 {
240 struct {
241 cell_t name;
242 cell_t nargs;
243 cell_t nreturns;
244 cell_t phandle;
245 cell_t prev;
246 cell_t buf;
247 cell_t next;
248 } args;
249
250 args.name = ADR2CELL("nextprop");
251 args.nargs = 3;
252 args.nreturns = 1;
253 args.phandle = HDL2CELL(handle);
254 args.prev = ADR2CELL(prop);
255 args.buf = ADR2CELL(buf);
256 if (openfirmware(&args) == -1)
257 return -1;
258 return args.next;
259 }
260
261 int
OF_finddevice(const char * name)262 OF_finddevice(const char *name)
263 {
264 struct {
265 cell_t name;
266 cell_t nargs;
267 cell_t nreturns;
268 cell_t device;
269 cell_t phandle;
270 } args;
271
272 args.name = ADR2CELL("finddevice");
273 args.nargs = 1;
274 args.nreturns = 1;
275 args.device = ADR2CELL(name);
276 if (openfirmware(&args) == -1)
277 return -1;
278 return args.phandle;
279 }
280
281 int
OF_instance_to_path(int ihandle,char * buf,int buflen)282 OF_instance_to_path(int ihandle, char *buf, int buflen)
283 {
284 struct {
285 cell_t name;
286 cell_t nargs;
287 cell_t nreturns;
288 cell_t ihandle;
289 cell_t buf;
290 cell_t buflen;
291 cell_t length;
292 } args;
293
294 if (buflen > NBPG)
295 return -1;
296 args.name = ADR2CELL("instance-to-path");
297 args.nargs = 3;
298 args.nreturns = 1;
299 args.ihandle = HDL2CELL(ihandle);
300 args.buf = ADR2CELL(buf);
301 args.buflen = buflen;
302 if (openfirmware(&args) < 0)
303 return -1;
304 return args.length;
305 }
306
307 int
OF_package_to_path(int phandle,char * buf,int buflen)308 OF_package_to_path(int phandle, char *buf, int buflen)
309 {
310 struct {
311 cell_t name;
312 cell_t nargs;
313 cell_t nreturns;
314 cell_t phandle;
315 cell_t buf;
316 cell_t buflen;
317 cell_t length;
318 } args;
319
320 if (buflen > NBPG)
321 return -1;
322 args.name = ADR2CELL("package-to-path");
323 args.nargs = 3;
324 args.nreturns = 1;
325 args.phandle = HDL2CELL(phandle);
326 args.buf = ADR2CELL(buf);
327 args.buflen = buflen;
328 if (openfirmware(&args) < 0)
329 return -1;
330 return args.length;
331 }
332
333 /*
334 * The following two functions may need to be re-worked to be 64-bit clean.
335 */
336 int
OF_call_method(const char * method,int ihandle,int nargs,int nreturns,...)337 OF_call_method(const char *method, int ihandle, int nargs, int nreturns, ...)
338 {
339 va_list ap;
340 struct {
341 cell_t name;
342 cell_t nargs;
343 cell_t nreturns;
344 cell_t method;
345 cell_t ihandle;
346 cell_t args_n_results[12];
347 } args;
348 long *ip, n;
349
350 if (nargs > 6)
351 return -1;
352 args.name = ADR2CELL("call-method");
353 args.nargs = nargs + 2;
354 args.nreturns = nreturns + 1;
355 args.method = ADR2CELL(method);
356 args.ihandle = HDL2CELL(ihandle);
357 va_start(ap, nreturns);
358 for (ip = (long*)(args.args_n_results + (n = nargs)); --n >= 0;)
359 *--ip = va_arg(ap, unsigned long);
360 if (openfirmware(&args) == -1) {
361 va_end(ap);
362 return -1;
363 }
364 if (args.args_n_results[nargs]) {
365 va_end(ap);
366 return args.args_n_results[nargs];
367 }
368 for (ip = (long*)(args.args_n_results + nargs + (n = args.nreturns)); --n > 0;)
369 *va_arg(ap, unsigned long *) = *--ip;
370 va_end(ap);
371 return 0;
372 }
373
374 int
OF_call_method_1(const char * method,int ihandle,int nargs,...)375 OF_call_method_1(const char *method, int ihandle, int nargs, ...)
376 {
377 va_list ap;
378 struct {
379 cell_t name;
380 cell_t nargs;
381 cell_t nreturns;
382 cell_t method;
383 cell_t ihandle;
384 cell_t args_n_results[16];
385 } args;
386 long *ip, n;
387
388 if (nargs > 6)
389 return -1;
390 args.name = ADR2CELL("call-method");
391 args.nargs = nargs + 2;
392 args.nreturns = 1;
393 args.method = ADR2CELL(method);
394 args.ihandle = HDL2CELL(ihandle);
395 va_start(ap, nargs);
396 for (ip = (long*)(args.args_n_results + (n = nargs)); --n >= 0;)
397 *--ip = va_arg(ap, unsigned long);
398 va_end(ap);
399 if (openfirmware(&args) == -1)
400 return -1;
401 if (args.args_n_results[nargs])
402 return -1;
403 return args.args_n_results[nargs + 1];
404 }
405
406 int
OF_open(const char * dname)407 OF_open(const char *dname)
408 {
409 struct {
410 cell_t name;
411 cell_t nargs;
412 cell_t nreturns;
413 cell_t dname;
414 cell_t handle;
415 } args;
416 int l;
417
418 if ((l = strlen(dname)) >= NBPG)
419 return -1;
420 args.name = ADR2CELL("open");
421 args.nargs = 1;
422 args.nreturns = 1;
423 args.dname = ADR2CELL(dname);
424 if (openfirmware(&args) == -1)
425 return -1;
426 return args.handle;
427 }
428
429 void
OF_close(int handle)430 OF_close(int handle)
431 {
432 struct {
433 cell_t name;
434 cell_t nargs;
435 cell_t nreturns;
436 cell_t handle;
437 } args;
438
439 args.name = ADR2CELL("close");
440 args.nargs = 1;
441 args.nreturns = 0;
442 args.handle = HDL2CELL(handle);
443 openfirmware(&args);
444 }
445
446 int
OF_test(const char * service)447 OF_test(const char* service)
448 {
449 struct {
450 cell_t name;
451 cell_t nargs;
452 cell_t nreturns;
453 cell_t service;
454 cell_t status;
455 } args;
456
457 args.name = ADR2CELL("test");
458 args.nargs = 1;
459 args.nreturns = 1;
460 args.service = ADR2CELL(service);
461 if (openfirmware(&args) == -1)
462 return -1;
463 return args.status;
464 }
465
466 int
OF_test_method(int service,const char * method)467 OF_test_method(int service, const char* method)
468 {
469 struct {
470 cell_t name;
471 cell_t nargs;
472 cell_t nreturns;
473 cell_t service;
474 cell_t method;
475 cell_t status;
476 } args;
477
478 args.name = ADR2CELL("test-method");
479 args.nargs = 2;
480 args.nreturns = 1;
481 args.service = HDL2CELL(service);
482 args.method = ADR2CELL(method);
483 if (openfirmware(&args) == -1)
484 return -1;
485 return args.status;
486 }
487
488
489 /*
490 * This assumes that character devices don't read in multiples of NBPG.
491 */
492 int
OF_read(int handle,void * addr,int len)493 OF_read(int handle, void *addr, int len)
494 {
495 struct {
496 cell_t name;
497 cell_t nargs;
498 cell_t nreturns;
499 cell_t ihandle;
500 cell_t addr;
501 cell_t len;
502 cell_t actual;
503 } args;
504 int l, act = 0;
505
506 #ifdef SUN4V
507 #if __arch64__
508 void *oaddr = addr;
509 __cpu_simple_lock(&ofcall_lock);
510 if (len > OFBOUNCE_MAXSIZE)
511 panic("OF_read(len = %d) exceedes bounce buffer\n", len);
512 addr = ofbounce;
513 #endif
514 #endif
515 args.name = ADR2CELL("read");
516 args.nargs = 3;
517 args.nreturns = 1;
518 args.ihandle = HDL2CELL(handle);
519 args.addr = ADR2CELL(addr);
520 for (; len > 0; len -= l) {
521 l = MIN(NBPG, len);
522 args.len = l;
523 if (openfirmware(&args) == -1) {
524 act = -1;
525 goto OF_read_exit;
526 }
527 if (args.actual > 0) {
528 act += args.actual;
529 }
530 if (args.actual < l) {
531 if (act)
532 goto OF_read_exit;
533 else {
534 act = args.actual;
535 goto OF_read_exit;
536 }
537 }
538 }
539 OF_read_exit:
540 #ifdef SUN4V
541 #if __arch64__
542 if (act > 0) {
543 memcpy(oaddr, addr, act);
544 }
545 __cpu_simple_unlock(&ofcall_lock);
546 #endif
547 #endif
548 return act;
549 }
550
551 int
OF_write(int handle,const void * addr,int len)552 OF_write(int handle, const void *addr, int len)
553 {
554 struct {
555 cell_t name;
556 cell_t nargs;
557 cell_t nreturns;
558 cell_t ihandle;
559 cell_t addr;
560 cell_t len;
561 cell_t actual;
562 } args;
563 int l, act = 0;
564
565 if (len > 1024) {
566 panic("OF_write(len = %d)\n", len);
567 }
568 #ifdef SUN4V
569 #if __arch64__
570 __cpu_simple_lock(&ofcall_lock);
571 if (len > OFBOUNCE_MAXSIZE)
572 panic("OF_write(len = %d) exceedes bounce buffer\n", len);
573 memcpy(ofbounce, addr, len);
574 addr = ofbounce;
575 #endif
576 #endif
577 args.name = ADR2CELL("write");
578 args.nargs = 3;
579 args.nreturns = 1;
580 args.ihandle = HDL2CELL(handle);
581 args.addr = ADR2CELL(addr);
582 for (; len > 0; len -= l) {
583 l = MIN(NBPG, len);
584 args.len = l;
585 if (openfirmware(&args) == -1)
586 return -1;
587 l = args.actual;
588 act += l;
589 }
590 #ifdef SUN4V
591 #if __arch64__
592 __cpu_simple_unlock(&ofcall_lock);
593 #endif
594 #endif
595 return act;
596 }
597
598
599 int
OF_seek(int handle,u_quad_t pos)600 OF_seek(int handle, u_quad_t pos)
601 {
602 struct {
603 cell_t name;
604 cell_t nargs;
605 cell_t nreturns;
606 cell_t handle;
607 cell_t poshi;
608 cell_t poslo;
609 cell_t status;
610 } args;
611
612 args.name = ADR2CELL("seek");
613 args.nargs = 3;
614 args.nreturns = 1;
615 args.handle = HDL2CELL(handle);
616 args.poshi = HDQ2CELL_HI(pos);
617 args.poslo = HDQ2CELL_LO(pos);
618 if (openfirmware(&args) == -1)
619 return -1;
620 return args.status;
621 }
622
623 void
OF_boot(const char * bspec)624 OF_boot(const char *bspec)
625 {
626 struct {
627 cell_t name;
628 cell_t nargs;
629 cell_t nreturns;
630 cell_t bootspec;
631 } args;
632 int l;
633
634 if ((l = strlen(bspec)) >= NBPG)
635 panic("OF_boot");
636 args.name = ADR2CELL("boot");
637 args.nargs = 1;
638 args.nreturns = 0;
639 args.bootspec = ADR2CELL(bspec);
640 openfirmware(&args);
641 panic("OF_boot failed");
642 }
643
644 void
OF_enter(void)645 OF_enter(void)
646 {
647 struct {
648 cell_t name;
649 cell_t nargs;
650 cell_t nreturns;
651 } args;
652
653 args.name = ADR2CELL("enter");
654 args.nargs = 0;
655 args.nreturns = 0;
656 openfirmware(&args);
657 }
658
659 void
OF_exit(void)660 OF_exit(void)
661 {
662 struct {
663 cell_t name;
664 cell_t nargs;
665 cell_t nreturns;
666 } args;
667
668 args.name = ADR2CELL("exit");
669 args.nargs = 0;
670 args.nreturns = 0;
671 openfirmware(&args);
672 panic("OF_exit failed");
673 }
674
675 void
OF_poweroff(void)676 OF_poweroff(void)
677 {
678 struct {
679 cell_t name;
680 cell_t nargs;
681 cell_t nreturns;
682 } args;
683
684 args.name = ADR2CELL("SUNW,power-off");
685 args.nargs = 0;
686 args.nreturns = 0;
687 openfirmware(&args);
688 panic("OF_poweroff failed");
689 }
690
691 void
OF_set_callback(void (* newfunc)(void *))692 (*OF_set_callback(void (*newfunc)(void *)))(void *)
693 {
694 struct {
695 cell_t name;
696 cell_t nargs;
697 cell_t nreturns;
698 cell_t newfunc;
699 cell_t oldfunc;
700 } args;
701
702 args.name = ADR2CELL("set-callback");
703 args.nargs = 1;
704 args.nreturns = 1;
705 args.newfunc = ADR2CELL(newfunc);
706 if (openfirmware(&args) == -1)
707 return 0;
708 return (void*)(long)args.oldfunc;
709 }
710
711 void
OF_set_symbol_lookup(void (* s2v)(void *),void (* v2s)(void *))712 OF_set_symbol_lookup(void (*s2v)(void *), void (*v2s)(void *))
713 {
714 struct {
715 cell_t name;
716 cell_t nargs;
717 cell_t nreturns;
718 cell_t sym2val;
719 cell_t val2sym;
720 } args;
721
722 args.name = ADR2CELL("set-symbol-lookup");
723 args.nargs = 2;
724 args.nreturns = 0;
725 args.sym2val = ADR2CELL(s2v);
726 args.val2sym = ADR2CELL(v2s);
727
728 (void)openfirmware(&args);
729 }
730
731 int
OF_interpret(const char * cmd,int nargs,int nreturns,...)732 OF_interpret(const char *cmd, int nargs, int nreturns, ...)
733 {
734 va_list ap;
735 struct {
736 cell_t name;
737 cell_t nargs;
738 cell_t nreturns;
739 cell_t slot[16];
740 } args;
741 cell_t status;
742 int i = 0;
743
744 args.name = ADR2CELL("interpret");
745 args.nargs = ++nargs;
746 args.nreturns = ++nreturns;
747 args.slot[i++] = ADR2CELL(cmd);
748 va_start(ap, nreturns);
749 while (i < nargs) {
750 args.slot[i++] = va_arg(ap, cell_t);
751 }
752 if (openfirmware(&args) == -1) {
753 va_end(ap);
754 return (-1);
755 }
756 status = args.slot[i++];
757 while (i < nargs+nreturns) {
758 *va_arg(ap, cell_t *) = args.slot[i++];
759 }
760 va_end(ap);
761 return (status);
762 }
763
764 int
OF_milliseconds(void)765 OF_milliseconds(void)
766 {
767 struct {
768 cell_t name;
769 cell_t nargs;
770 cell_t nreturns;
771 cell_t ticks;
772 } args;
773
774 args.name = ADR2CELL("milliseconds");
775 args.nargs = 0;
776 args.nreturns = 1;
777 if (openfirmware(&args) == -1)
778 return -1;
779 return (args.ticks);
780 }
781
782 /* Claim an area of memory. */
783 void *
OF_claim(void * virt,u_int size,u_int align)784 OF_claim(void *virt, u_int size, u_int align)
785 {
786 static struct {
787 cell_t name;
788 cell_t nargs;
789 cell_t nreturns;
790 cell_t virt;
791 cell_t size;
792 cell_t align;
793 cell_t baseaddr;
794 } args;
795
796 args.name = ADR2CELL("claim");
797 args.nargs = 3;
798 args.nreturns = 1;
799 args.virt = ADR2CELL(virt);
800 args.size = size;
801 args.align = align;
802 if (openfirmware(&args) == -1)
803 return (void *)-1;
804 return (void *)(long)args.baseaddr;
805 }
806
807 #if defined(_KERNEL_OPT)
808 #include "opt_ddb.h"
809 #endif
810
811 #ifdef DDB
812 #include <machine/db_machdep.h>
813 #include <ddb/db_sym.h>
814 #include <ddb/db_extern.h>
815
816 int obp_symbol_debug = 0;
817
818 void
OF_sym2val(void * cells)819 OF_sym2val(void *cells)
820 {
821 struct args {
822 cell_t service;
823 cell_t nargs;
824 cell_t nreturns;
825 cell_t symbol;
826 cell_t result;
827 cell_t value;
828 } *args = (struct args*)cells;
829 char *symbol;
830 db_expr_t value;
831
832 /* Set data segment pointer */
833 __asm volatile("clr %%g4" : :);
834
835 /* No args? Nothing to do. */
836 if (args->nargs == 0 || args->nreturns == 0)
837 return;
838
839 /* Do we have a place for the value? */
840 if (args->nreturns != 2) {
841 args->nreturns = 1;
842 args->result = -1;
843 return;
844 }
845
846 symbol = (char *)(u_long)args->symbol;
847 if (obp_symbol_debug)
848 prom_printf("looking up symbol %s\n", symbol);
849 args->result = (db_value_of_name(symbol, &value) == true) ? 0 : -1;
850 if (obp_symbol_debug)
851 prom_printf("%s is %lx\n", symbol, value);
852 args->value = ADR2CELL(value);
853 }
854
855 void
OF_val2sym(void * cells)856 OF_val2sym(void *cells)
857 {
858 struct args {
859 cell_t service;
860 cell_t nargs;
861 cell_t nreturns;
862 cell_t value;
863 cell_t offset;
864 cell_t symbol;
865 } *args = (struct args*)cells;
866 db_sym_t symbol;
867 db_expr_t value;
868 db_expr_t offset;
869
870 /* Set data segment pointer */
871 __asm volatile("clr %%g4" : :);
872
873 if (obp_symbol_debug)
874 prom_printf("OF_val2sym: nargs %lx nreturns %lx\n",
875 args->nargs, args->nreturns);
876
877 /* No args? Nothing to do. */
878 if (args->nargs == 0 || args->nreturns == 0)
879 return;
880
881 /* Do we have a place for the value? */
882 if (args->nreturns != 2) {
883 args->nreturns = 1;
884 args->offset = -1;
885 return;
886 }
887
888 value = args->value;
889 if (obp_symbol_debug)
890 prom_printf("looking up value %ld\n", value);
891 symbol = db_search_symbol(value, 0, &offset);
892 if (symbol == DB_SYM_NULL) {
893 if (obp_symbol_debug)
894 prom_printf("OF_val2sym: not found\n");
895 args->nreturns = 1;
896 args->offset = -1;
897 return;
898 }
899 args->offset = offset;
900 args->symbol = ADR2CELL(symbol);
901 }
902 #endif /* DDB */
903