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