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