xref: /netbsd-src/sys/arch/arm/ofw/openfirm.c (revision 5e8df8ea63b3447553e259ce4f033882953ad69a)
1 /*	$NetBSD: openfirm.c,v 1.11 2021/02/07 13:59:36 martin Exp $	*/
2 
3 /*
4  * Copyright 1997
5  * Digital Equipment Corporation. All rights reserved.
6  *
7  * This software is furnished under license and may be used and
8  * copied only in accordance with the following terms and conditions.
9  * Subject to these conditions, you may download, copy, install,
10  * use, modify and distribute this software in source and/or binary
11  * form. No title or ownership is transferred hereby.
12  *
13  * 1) Any source code used, modified or distributed must reproduce
14  *    and retain this copyright notice and list of conditions as
15  *    they appear in the source file.
16  *
17  * 2) No right is granted to use any trade name, trademark, or logo of
18  *    Digital Equipment Corporation. Neither the "Digital Equipment
19  *    Corporation" name nor any trademark or logo of Digital Equipment
20  *    Corporation may be used to endorse or promote products derived
21  *    from this software without the prior written permission of
22  *    Digital Equipment Corporation.
23  *
24  * 3) This software is provided "AS-IS" and any express or implied
25  *    warranties, including but not limited to, any implied warranties
26  *    of merchantability, fitness for a particular purpose, or
27  *    non-infringement are disclaimed. In no event shall DIGITAL be
28  *    liable for any damages whatsoever, and in particular, DIGITAL
29  *    shall not be liable for special, indirect, consequential, or
30  *    incidental damages or damages for lost profits, loss of
31  *    revenue or loss of use, whether such damages arise in contract,
32  *    negligence, tort, under statute, in equity, at law or otherwise,
33  *    even if advised of the possibility of such damage.
34  */
35 
36 /*
37  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
38  * Copyright (C) 1995, 1996 TooLs GmbH.
39  * All rights reserved.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. All advertising materials mentioning features or use of this software
50  *    must display the following acknowledgement:
51  *	This product includes software developed by TooLs GmbH.
52  * 4. The name of TooLs GmbH may not be used to endorse or promote products
53  *    derived from this software without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
56  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
57  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
58  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
60  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
61  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
62  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
63  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
64  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65  */
66 
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.11 2021/02/07 13:59:36 martin Exp $");
69 
70 #include <sys/param.h>
71 
72 #include <dev/ofw/openfirm.h>
73 
74 
75 /*
76  *  Wrapper routines for OFW client services.
77  *
78  *  This code was adapted from the PowerPC version done by
79  *  Wolfgang Solfrank.  The main difference is that we don't
80  *  do the silly "ofw_stack" dance to convert the OS's real-
81  *  mode view of OFW to virtual-mode.  We don't need to do
82  *  that because our NetBSD port assumes virtual-mode OFW.
83  *
84  *  We should work with Wolfgang to turn this into a MI file. -JJK
85  */
86 
87 
88 int
OF_peer(int phandle)89 OF_peer(int phandle)
90 {
91 	static struct {
92 		const char *name;
93 		int nargs;
94 		int nreturns;
95 		int phandle;
96 		int sibling;
97 	} args = {
98 		"peer",
99 		1,
100 		1,
101 	};
102 
103 	args.phandle = phandle;
104 	if (openfirmware(&args) == -1)
105 		return 0;
106 	return args.sibling;
107 }
108 
109 int
OF_child(int phandle)110 OF_child(int phandle)
111 {
112 	static struct {
113 		const char *name;
114 		int nargs;
115 		int nreturns;
116 		int phandle;
117 		int child;
118 	} args = {
119 		"child",
120 		1,
121 		1,
122 	};
123 
124 	args.phandle = phandle;
125 	if (openfirmware(&args) == -1)
126 		return 0;
127 	return args.child;
128 }
129 
130 int
OF_parent(int phandle)131 OF_parent(int phandle)
132 {
133 	static struct {
134 		const char *name;
135 		int nargs;
136 		int nreturns;
137 		int phandle;
138 		int parent;
139 	} args = {
140 		"parent",
141 		1,
142 		1,
143 	};
144 
145 	args.phandle = phandle;
146 	if (openfirmware(&args) == -1)
147 		return 0;
148 	return args.parent;
149 }
150 
151 int
OF_instance_to_package(int ihandle)152 OF_instance_to_package(int ihandle)
153 {
154 	static struct {
155 		const char *name;
156 		int nargs;
157 		int nreturns;
158 		int ihandle;
159 		int phandle;
160 	} args = {
161 		"instance-to-package",
162 		1,
163 		1,
164 	};
165 
166 	args.ihandle = ihandle;
167 	if (openfirmware(&args) == -1)
168 		return -1;
169 	return args.phandle;
170 }
171 
172 int
OF_nextprop(int handle,const char * prop,void * nextprop)173 OF_nextprop(int handle, const char *prop, void *nextprop)
174 {
175 	static struct {
176 		const char *name;
177 		int nargs;
178 		int nreturns;
179 		int phandle;
180 		const char *prop;
181 		void *nextprop;
182 		int flags;
183 	} args = {
184 		"nextprop",
185 		3,
186 		1,
187 	};
188 
189 	args.phandle = handle;
190 	args.prop = prop;
191 	args.nextprop = nextprop;
192 
193 	if (openfirmware(&args) == -1)
194 		return -1;
195 	return args.flags;
196 }
197 
198 int
OF_getprop(int handle,const char * prop,void * buf,int buflen)199 OF_getprop(int handle, const char *prop, void *buf, int buflen)
200 {
201 	static struct {
202 		const char *name;
203 		int nargs;
204 		int nreturns;
205 		int phandle;
206 		const char *prop;
207 		void *buf;
208 		int buflen;
209 		int size;
210 	} args = {
211 		"getprop",
212 		4,
213 		1,
214 	};
215 
216 	args.phandle = handle;
217 	args.prop = prop;
218 	args.buf = buf;
219 	args.buflen = buflen;
220 
221 
222 	if (openfirmware(&args) == -1)
223 		return -1;
224 	return args.size;
225 }
226 
227 int
OF_setprop(int handle,const char * prop,const void * buf,int buflen)228 OF_setprop(int handle, const char *prop, const void *buf, int buflen)
229 {
230 	static struct {
231 		const char *name;
232 		int nargs;
233 		int nreturns;
234 		int phandle;
235 		const char *prop;
236 		const void *buf;
237 		int buflen;
238 		int size;
239 	} args = {
240 		"setprop",
241 		4,
242 		1,
243 	};
244 
245 	args.phandle = handle;
246 	args.prop = prop;
247 	args.buf = buf;
248 	args.buflen = buflen;
249 
250 
251 	if (openfirmware(&args) == -1)
252 		return -1;
253 	return args.size;
254 }
255 
256 int
OF_getproplen(int handle,const char * prop)257 OF_getproplen(int handle, const char *prop)
258 {
259 	static struct {
260 		const char *name;
261 		int nargs;
262 		int nreturns;
263 		int phandle;
264 		const char *prop;
265 		int size;
266 	} args = {
267 		"getproplen",
268 		2,
269 		1,
270 	};
271 
272 	args.phandle = handle;
273 	args.prop = prop;
274 	if (openfirmware(&args) == -1)
275 		return -1;
276 	return args.size;
277 }
278 
279 int
OF_finddevice(const char * name)280 OF_finddevice(const char *name)
281 {
282 	static struct {
283 		const char *name;
284 		int nargs;
285 		int nreturns;
286 		const char *device;
287 		int phandle;
288 	} args = {
289 		"finddevice",
290 		1,
291 		1,
292 	};
293 
294 	args.device = name;
295 	if (openfirmware(&args) == -1)
296 		return -1;
297 	return args.phandle;
298 }
299 
300 int
OF_instance_to_path(int ihandle,char * buf,int buflen)301 OF_instance_to_path(int ihandle, char *buf, int buflen)
302 {
303 	static struct {
304 		const char *name;
305 		int nargs;
306 		int nreturns;
307 		int ihandle;
308 		char *buf;
309 		int buflen;
310 		int length;
311 	} args = {
312 		"instance-to-path",
313 		3,
314 		1,
315 	};
316 
317 	args.ihandle = ihandle;
318 	args.buf = buf;
319 	args.buflen = buflen;
320 	if (openfirmware(&args) < 0)
321 		return -1;
322 	return args.length;
323 }
324 
325 int
OF_package_to_path(int phandle,char * buf,int buflen)326 OF_package_to_path(int phandle, char *buf, int buflen)
327 {
328 	static struct {
329 		const char *name;
330 		int nargs;
331 		int nreturns;
332 		int phandle;
333 		char *buf;
334 		int buflen;
335 		int length;
336 	} args = {
337 		"package-to-path",
338 		3,
339 		1,
340 	};
341 
342 	args.phandle = phandle;
343 	args.buf = buf;
344 	args.buflen = buflen;
345 	if (openfirmware(&args) < 0)
346 		return -1;
347 	return args.length;
348 }
349 
350 int
351 #ifdef	__STDC__
OF_call_method(const char * method,int ihandle,int nargs,int nreturns,...)352 OF_call_method(const char *method, int ihandle, int nargs, int nreturns, ...)
353 #else
354 OF_call_method(method, ihandle, nargs, nreturns, va_alist)
355 	const char *method;
356 	int ihandle;
357 	int nargs;
358 	int nreturns;
359 	va_dcl
360 #endif
361 {
362 	va_list ap;
363 	static struct {
364 		const char *name;
365 		int nargs;
366 		int nreturns;
367 		const char *method;
368 		int ihandle;
369 		int args_n_results[12];
370 	} args = {
371 		"call-method",
372 		2,
373 		1,
374 	};
375 	int *ip, n;
376 
377 	if (nargs > 6)
378 		return -1;
379 	args.nargs = nargs + 2;
380 	args.nreturns = nreturns + 1;
381 	args.method = method;
382 	args.ihandle = ihandle;
383 	va_start(ap, nreturns);
384 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
385 		*--ip = va_arg(ap, int);
386 	if (openfirmware(&args) == -1) {
387 		va_end(ap);
388 		return -1;
389 	}
390 /*
391 	{
392 	    int i, res;
393 
394 	    printf("call_method(%s): ihandle = %x, nargs = %d, nreturns = %d -- ",
395 		   method, ihandle, nargs, nreturns);
396 	    res = openfirmware(&args);
397 	    printf("res = %x\n", res);
398 	    printf("\targs_n_results = ");
399 	    for (i = 0; i < nargs + nreturns + 1; i++)
400 		printf("%x ", args.args_n_results[i]);
401 	    printf("\n");
402 	    if (res == -1) return -1;
403 	}
404 */
405 	if (args.args_n_results[nargs]) {
406 		va_end(ap);
407 		return args.args_n_results[nargs];
408 	}
409 	for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
410 		*va_arg(ap, int *) = *--ip;
411 	va_end(ap);
412 	return 0;
413 }
414 
415 int
416 #ifdef	__STDC__
OF_call_method_1(const char * method,int ihandle,int nargs,...)417 OF_call_method_1(const char *method, int ihandle, int nargs, ...)
418 #else
419 OF_call_method_1(method, ihandle, nargs, va_alist)
420 	const char *method;
421 	int ihandle;
422 	int nargs;
423 	va_dcl
424 #endif
425 {
426 	va_list ap;
427 	static struct {
428 		const char *name;
429 		int nargs;
430 		int nreturns;
431 		const char *method;
432 		int ihandle;
433 		int args_n_results[8];
434 	} args = {
435 		"call-method",
436 		2,
437 		2,
438 	};
439 	int *ip, n;
440 
441 	if (nargs > 6)
442 		return -1;
443 	args.nargs = nargs + 2;
444 	args.method = method;
445 	args.ihandle = ihandle;
446 	va_start(ap, nargs);
447 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
448 		*--ip = va_arg(ap, int);
449 	va_end(ap);
450 	if (openfirmware(&args) == -1)
451 		return -1;
452 /*
453 	{
454 	    int i, res;
455 
456 	    printf("call_method_1(%s): ihandle = %x, nargs = %d -- ",
457 		   method, ihandle, nargs);
458 	    res = openfirmware(&args);
459 	    printf("res = %x\n", res);
460 	    printf("\targs_n_results = ");
461 	    for (i = 0; i < nargs + 2; i++)
462 		printf("%x ", args.args_n_results[i]);
463 	    printf("\n");
464 	    if (res == -1) return -1;
465 	}
466 */
467 	if (args.args_n_results[nargs])
468 		return -1;
469 	return args.args_n_results[nargs + 1];
470 }
471 
472 int
OF_open(const char * dname)473 OF_open(const char *dname)
474 {
475 	static struct {
476 		const char *name;
477 		int nargs;
478 		int nreturns;
479 		const char *dname;
480 		int handle;
481 	} args = {
482 		"open",
483 		1,
484 		1,
485 	};
486 
487 	args.dname = dname;
488 	if (openfirmware(&args) == -1)
489 		return -1;
490 	return args.handle;
491 }
492 
493 void
OF_close(int handle)494 OF_close(int handle)
495 {
496 	static struct {
497 		const char *name;
498 		int nargs;
499 		int nreturns;
500 		int handle;
501 	} args = {
502 		"close",
503 		1,
504 		0,
505 	};
506 
507 	args.handle = handle;
508 	openfirmware(&args);
509 }
510 
511 int
OF_read(int handle,void * addr,int len)512 OF_read(int handle, void *addr, int len)
513 {
514 	static struct {
515 		const char *name;
516 		int nargs;
517 		int nreturns;
518 		int ihandle;
519 		void *addr;
520 		int len;
521 		int actual;
522 	} args = {
523 		"read",
524 		3,
525 		1,
526 	};
527 
528 	args.ihandle = handle;
529 	args.addr = addr;
530 	args.len = len;
531 	if (openfirmware(&args) == -1)
532 		return -1;
533 	return args.actual;
534 }
535 
536 int
OF_write(int handle,const void * addr,int len)537 OF_write(int handle, const void *addr, int len)
538 {
539 	static struct {
540 		const char *name;
541 		int nargs;
542 		int nreturns;
543 		int ihandle;
544 		const void *addr;
545 		int len;
546 		int actual;
547 	} args = {
548 		"write",
549 		3,
550 		1,
551 	};
552 
553 	args.ihandle = handle;
554 	args.addr = addr;
555 	args.len = len;
556 	if (openfirmware(&args) == -1)
557 		return -1;
558 	return args.actual;
559 }
560 
561 int
OF_seek(int handle,u_quad_t pos)562 OF_seek(int handle, u_quad_t pos)
563 {
564 	static struct {
565 		const char *name;
566 		int nargs;
567 		int nreturns;
568 		int handle;
569 		int poshi;
570 		int poslo;
571 		int status;
572 	} args = {
573 		"seek",
574 		3,
575 		1,
576 	};
577 
578 	args.handle = handle;
579 	args.poshi = (int)(pos >> 32);
580 	args.poslo = (int)pos;
581 	if (openfirmware(&args) == -1)
582 		return -1;
583 	return args.status;
584 }
585 
586 void *
OF_claim(void * virt,u_int size,u_int align)587 OF_claim(void *virt, u_int size, u_int align)
588 {
589         static struct {
590                 const char *name;
591                 int nargs;
592                 int nreturns;
593                 void *virt;
594                 u_int size;
595                 u_int align;
596                 void *baseaddr;
597         } args = {
598                 "claim",
599                 3,
600                 1,
601         };
602 
603         args.virt = virt;
604         args.size = size;
605         args.align = align;
606         if (openfirmware(&args) == -1)
607                 return (void *)-1;
608         return args.baseaddr;
609 }
610 
611 void
OF_release(void * virt,u_int size)612 OF_release(void *virt, u_int size)
613 {
614         static struct {
615                 const char *name;
616                 int nargs;
617                 int nreturns;
618                 void *virt;
619                 u_int size;
620         } args = {
621                 "release",
622                 2,
623                 0,
624         };
625 
626         args.virt = virt;
627         args.size = size;
628         openfirmware(&args);
629 }
630 
631 int
OF_milliseconds(void)632 OF_milliseconds(void)
633 {
634         static struct {
635                 const char *name;
636                 int nargs;
637                 int nreturns;
638                 int ms;
639         } args = {
640                 "milliseconds",
641                 0,
642                 1,
643         };
644 
645         openfirmware(&args);
646         return args.ms;
647 }
648 
649 void
OF_boot(const char * btspec)650 OF_boot(const char *btspec)
651 {
652 	static struct {
653 		const char *name;
654 		int nargs;
655 		int nreturns;
656 		const char *bootspec;
657 	} args = {
658 		"boot",
659 		1,
660 		0,
661 	};
662 
663 	args.bootspec = btspec;
664 	openfirmware(&args);
665 	while (1);			/* just in case */
666 }
667 
668 void
OF_enter(void)669 OF_enter(void)
670 {
671 	static struct {
672 		const char *name;
673 		int nargs;
674 		int nreturns;
675 	} args = {
676 		"enter",
677 		0,
678 		0,
679 	};
680 
681 	openfirmware(&args);
682 }
683 
684 void
OF_exit(void)685 OF_exit(void)
686 {
687 	static struct {
688 		const char *name;
689 		int nargs;
690 		int nreturns;
691 	} args = {
692 		"exit",
693 		0,
694 		0,
695 	};
696 
697 	openfirmware(&args);
698 	while (1);			/* just in case */
699 }
700 
701 typedef void (*of_callback_t)(void *);
702 
703 of_callback_t
OF_set_callback(of_callback_t newfunc)704 OF_set_callback(of_callback_t newfunc)
705 {
706 	static struct {
707 		const char *name;
708 		int nargs;
709 		int nreturns;
710 		of_callback_t newfunc;
711 		of_callback_t oldfunc;
712 	} args = {
713 		"set-callback",
714 		1,
715 		1,
716 	};
717 
718 	args.newfunc = newfunc;
719 	if (openfirmware(&args) == -1)
720 		return 0;
721 	return args.oldfunc;
722 }
723