xref: /netbsd/sys/arch/sparc/sparc/openfirm.c (revision dafde1b8)
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