Home | History | Annotate | Line # | Download | only in ofw
openfirm.c revision 1.4.2.1
      1 /*	$NetBSD: openfirm.c,v 1.4.2.1 2007/09/03 14:23:23 yamt 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.4.2.1 2007/09/03 14:23:23 yamt Exp $");
     69 
     70 #include <sys/param.h>
     71 
     72 #include <machine/stdarg.h>
     73 
     74 #include <dev/ofw/openfirm.h>
     75 
     76 
     77 /*
     78  *  Wrapper routines for OFW client services.
     79  *
     80  *  This code was adapted from the PowerPC version done by
     81  *  Wolfgang Solfrank.  The main difference is that we don't
     82  *  do the silly "ofw_stack" dance to convert the OS's real-
     83  *  mode view of OFW to virtual-mode.  We don't need to do
     84  *  that because our NetBSD port assumes virtual-mode OFW.
     85  *
     86  *  We should work with Wolfgang to turn this into a MI file. -JJK
     87  */
     88 
     89 
     90 int
     91 OF_peer(phandle)
     92 	int phandle;
     93 {
     94 	static struct {
     95 		const char *name;
     96 		int nargs;
     97 		int nreturns;
     98 		int phandle;
     99 		int sibling;
    100 	} args = {
    101 		"peer",
    102 		1,
    103 		1,
    104 	};
    105 
    106 	args.phandle = phandle;
    107 	if (openfirmware(&args) == -1)
    108 		return 0;
    109 	return args.sibling;
    110 }
    111 
    112 int
    113 OF_child(phandle)
    114 	int phandle;
    115 {
    116 	static struct {
    117 		const char *name;
    118 		int nargs;
    119 		int nreturns;
    120 		int phandle;
    121 		int child;
    122 	} args = {
    123 		"child",
    124 		1,
    125 		1,
    126 	};
    127 
    128 	args.phandle = phandle;
    129 	if (openfirmware(&args) == -1)
    130 		return 0;
    131 	return args.child;
    132 }
    133 
    134 int
    135 OF_parent(phandle)
    136 	int phandle;
    137 {
    138 	static struct {
    139 		const char *name;
    140 		int nargs;
    141 		int nreturns;
    142 		int phandle;
    143 		int parent;
    144 	} args = {
    145 		"parent",
    146 		1,
    147 		1,
    148 	};
    149 
    150 	args.phandle = phandle;
    151 	if (openfirmware(&args) == -1)
    152 		return 0;
    153 	return args.parent;
    154 }
    155 
    156 int
    157 OF_instance_to_package(ihandle)
    158 	int ihandle;
    159 {
    160 	static struct {
    161 		const char *name;
    162 		int nargs;
    163 		int nreturns;
    164 		int ihandle;
    165 		int phandle;
    166 	} args = {
    167 		"instance-to-package",
    168 		1,
    169 		1,
    170 	};
    171 
    172 	args.ihandle = ihandle;
    173 	if (openfirmware(&args) == -1)
    174 		return -1;
    175 	return args.phandle;
    176 }
    177 
    178 int
    179 OF_nextprop(handle, prop, nextprop)
    180 	int handle;
    181 	const char *prop;
    182 	void *nextprop;
    183 {
    184 	static struct {
    185 		const char *name;
    186 		int nargs;
    187 		int nreturns;
    188 		int phandle;
    189 		const char *prop;
    190 		void *nextprop;
    191 		int flags;
    192 	} args = {
    193 		"nextprop",
    194 		3,
    195 		1,
    196 	};
    197 
    198 	args.phandle = handle;
    199 	args.prop = prop;
    200 	args.nextprop = nextprop;
    201 
    202 	if (openfirmware(&args) == -1)
    203 		return -1;
    204 	return args.flags;
    205 }
    206 
    207 int
    208 OF_getprop(handle, prop, buf, buflen)
    209 	int handle;
    210 	const char *prop;
    211 	void *buf;
    212 	int buflen;
    213 {
    214 	static struct {
    215 		const char *name;
    216 		int nargs;
    217 		int nreturns;
    218 		int phandle;
    219 		const char *prop;
    220 		void *buf;
    221 		int buflen;
    222 		int size;
    223 	} args = {
    224 		"getprop",
    225 		4,
    226 		1,
    227 	};
    228 
    229 	args.phandle = handle;
    230 	args.prop = prop;
    231 	args.buf = buf;
    232 	args.buflen = buflen;
    233 
    234 
    235 	if (openfirmware(&args) == -1)
    236 		return -1;
    237 	return args.size;
    238 }
    239 
    240 int
    241 OF_setprop(handle, prop, buf, buflen)
    242 	int handle;
    243 	const char *prop;
    244 	const void *buf;
    245 	int buflen;
    246 {
    247 	static struct {
    248 		const char *name;
    249 		int nargs;
    250 		int nreturns;
    251 		int phandle;
    252 		const char *prop;
    253 		const void *buf;
    254 		int buflen;
    255 		int size;
    256 	} args = {
    257 		"setprop",
    258 		4,
    259 		1,
    260 	};
    261 
    262 	args.phandle = handle;
    263 	args.prop = prop;
    264 	args.buf = buf;
    265 	args.buflen = buflen;
    266 
    267 
    268 	if (openfirmware(&args) == -1)
    269 		return -1;
    270 	return args.size;
    271 }
    272 
    273 int
    274 OF_getproplen(handle, prop)
    275 	int handle;
    276 	const char *prop;
    277 {
    278 	static struct {
    279 		const char *name;
    280 		int nargs;
    281 		int nreturns;
    282 		int phandle;
    283 		const char *prop;
    284 		int size;
    285 	} args = {
    286 		"getproplen",
    287 		2,
    288 		1,
    289 	};
    290 
    291 	args.phandle = handle;
    292 	args.prop = prop;
    293 	if (openfirmware(&args) == -1)
    294 		return -1;
    295 	return args.size;
    296 }
    297 
    298 int
    299 OF_finddevice(name)
    300 	const char *name;
    301 {
    302 	static struct {
    303 		const char *name;
    304 		int nargs;
    305 		int nreturns;
    306 		const char *device;
    307 		int phandle;
    308 	} args = {
    309 		"finddevice",
    310 		1,
    311 		1,
    312 	};
    313 
    314 	args.device = name;
    315 	if (openfirmware(&args) == -1)
    316 		return -1;
    317 	return args.phandle;
    318 }
    319 
    320 int
    321 OF_instance_to_path(ihandle, buf, buflen)
    322 	int ihandle;
    323 	char *buf;
    324 	int buflen;
    325 {
    326 	static struct {
    327 		const char *name;
    328 		int nargs;
    329 		int nreturns;
    330 		int ihandle;
    331 		char *buf;
    332 		int buflen;
    333 		int length;
    334 	} args = {
    335 		"instance-to-path",
    336 		3,
    337 		1,
    338 	};
    339 
    340 	args.ihandle = ihandle;
    341 	args.buf = buf;
    342 	args.buflen = buflen;
    343 	if (openfirmware(&args) < 0)
    344 		return -1;
    345 	return args.length;
    346 }
    347 
    348 int
    349 OF_package_to_path(phandle, buf, buflen)
    350 	int phandle;
    351 	char *buf;
    352 	int buflen;
    353 {
    354 	static struct {
    355 		const char *name;
    356 		int nargs;
    357 		int nreturns;
    358 		int phandle;
    359 		char *buf;
    360 		int buflen;
    361 		int length;
    362 	} args = {
    363 		"package-to-path",
    364 		3,
    365 		1,
    366 	};
    367 
    368 	args.phandle = phandle;
    369 	args.buf = buf;
    370 	args.buflen = buflen;
    371 	if (openfirmware(&args) < 0)
    372 		return -1;
    373 	return args.length;
    374 }
    375 
    376 int
    377 #ifdef	__STDC__
    378 OF_call_method(const char *method, int ihandle, int nargs, int nreturns, ...)
    379 #else
    380 OF_call_method(method, ihandle, nargs, nreturns, va_alist)
    381 	const char *method;
    382 	int ihandle;
    383 	int nargs;
    384 	int nreturns;
    385 	va_dcl
    386 #endif
    387 {
    388 	va_list ap;
    389 	static struct {
    390 		const char *name;
    391 		int nargs;
    392 		int nreturns;
    393 		const char *method;
    394 		int ihandle;
    395 		int args_n_results[12];
    396 	} args = {
    397 		"call-method",
    398 		2,
    399 		1,
    400 	};
    401 	int *ip, n;
    402 
    403 	if (nargs > 6)
    404 		return -1;
    405 	args.nargs = nargs + 2;
    406 	args.nreturns = nreturns + 1;
    407 	args.method = method;
    408 	args.ihandle = ihandle;
    409 	va_start(ap, nreturns);
    410 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
    411 		*--ip = va_arg(ap, int);
    412 	if (openfirmware(&args) == -1) {
    413 		va_end(ap);
    414 		return -1;
    415 	}
    416 /*
    417 	{
    418 	    int i, res;
    419 
    420 	    printf("call_method(%s): ihandle = %x, nargs = %d, nreturns = %d -- ",
    421 		   method, ihandle, nargs, nreturns);
    422 	    res = openfirmware(&args);
    423 	    printf("res = %x\n", res);
    424 	    printf("\targs_n_results = ");
    425 	    for (i = 0; i < nargs + nreturns + 1; i++)
    426 		printf("%x ", args.args_n_results[i]);
    427 	    printf("\n");
    428 	    if (res == -1) return -1;
    429 	}
    430 */
    431 	if (args.args_n_results[nargs]) {
    432 		va_end(ap);
    433 		return args.args_n_results[nargs];
    434 	}
    435 	for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
    436 		*va_arg(ap, int *) = *--ip;
    437 	va_end(ap);
    438 	return 0;
    439 }
    440 
    441 int
    442 #ifdef	__STDC__
    443 OF_call_method_1(const char *method, int ihandle, int nargs, ...)
    444 #else
    445 OF_call_method_1(method, ihandle, nargs, va_alist)
    446 	const char *method;
    447 	int ihandle;
    448 	int nargs;
    449 	va_dcl
    450 #endif
    451 {
    452 	va_list ap;
    453 	static struct {
    454 		const char *name;
    455 		int nargs;
    456 		int nreturns;
    457 		const char *method;
    458 		int ihandle;
    459 		int args_n_results[8];
    460 	} args = {
    461 		"call-method",
    462 		2,
    463 		2,
    464 	};
    465 	int *ip, n;
    466 
    467 	if (nargs > 6)
    468 		return -1;
    469 	args.nargs = nargs + 2;
    470 	args.method = method;
    471 	args.ihandle = ihandle;
    472 	va_start(ap, nargs);
    473 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
    474 		*--ip = va_arg(ap, int);
    475 	va_end(ap);
    476 	if (openfirmware(&args) == -1)
    477 		return -1;
    478 /*
    479 	{
    480 	    int i, res;
    481 
    482 	    printf("call_method_1(%s): ihandle = %x, nargs = %d -- ",
    483 		   method, ihandle, nargs);
    484 	    res = openfirmware(&args);
    485 	    printf("res = %x\n", res);
    486 	    printf("\targs_n_results = ");
    487 	    for (i = 0; i < nargs + 2; i++)
    488 		printf("%x ", args.args_n_results[i]);
    489 	    printf("\n");
    490 	    if (res == -1) return -1;
    491 	}
    492 */
    493 	if (args.args_n_results[nargs])
    494 		return -1;
    495 	return args.args_n_results[nargs + 1];
    496 }
    497 
    498 int
    499 OF_open(dname)
    500 	const char *dname;
    501 {
    502 	static struct {
    503 		const char *name;
    504 		int nargs;
    505 		int nreturns;
    506 		const char *dname;
    507 		int handle;
    508 	} args = {
    509 		"open",
    510 		1,
    511 		1,
    512 	};
    513 
    514 	args.dname = dname;
    515 	if (openfirmware(&args) == -1)
    516 		return -1;
    517 	return args.handle;
    518 }
    519 
    520 void
    521 OF_close(handle)
    522 	int handle;
    523 {
    524 	static struct {
    525 		const char *name;
    526 		int nargs;
    527 		int nreturns;
    528 		int handle;
    529 	} args = {
    530 		"close",
    531 		1,
    532 		0,
    533 	};
    534 
    535 	args.handle = handle;
    536 	openfirmware(&args);
    537 }
    538 
    539 int
    540 OF_read(handle, addr, len)
    541 	int handle;
    542 	void *addr;
    543 	int len;
    544 {
    545 	static struct {
    546 		const char *name;
    547 		int nargs;
    548 		int nreturns;
    549 		int ihandle;
    550 		void *addr;
    551 		int len;
    552 		int actual;
    553 	} args = {
    554 		"read",
    555 		3,
    556 		1,
    557 	};
    558 
    559 	args.ihandle = handle;
    560 	args.addr = addr;
    561 	args.len = len;
    562 	if (openfirmware(&args) == -1)
    563 		return -1;
    564 	return args.actual;
    565 }
    566 
    567 int
    568 OF_write(handle, addr, len)
    569 	int handle;
    570 	const void *addr;
    571 	int len;
    572 {
    573 	static struct {
    574 		const char *name;
    575 		int nargs;
    576 		int nreturns;
    577 		int ihandle;
    578 		const void *addr;
    579 		int len;
    580 		int actual;
    581 	} args = {
    582 		"write",
    583 		3,
    584 		1,
    585 	};
    586 
    587 	args.ihandle = handle;
    588 	args.addr = addr;
    589 	args.len = len;
    590 	if (openfirmware(&args) == -1)
    591 		return -1;
    592 	return args.actual;
    593 }
    594 
    595 int
    596 OF_seek(handle, pos)
    597 	int handle;
    598 	u_quad_t pos;
    599 {
    600 	static struct {
    601 		const char *name;
    602 		int nargs;
    603 		int nreturns;
    604 		int handle;
    605 		int poshi;
    606 		int poslo;
    607 		int status;
    608 	} args = {
    609 		"seek",
    610 		3,
    611 		1,
    612 	};
    613 
    614 	args.handle = handle;
    615 	args.poshi = (int)(pos >> 32);
    616 	args.poslo = (int)pos;
    617 	if (openfirmware(&args) == -1)
    618 		return -1;
    619 	return args.status;
    620 }
    621 
    622 void *
    623 OF_claim(virt, size, align)
    624         void *virt;
    625         u_int size;
    626         u_int align;
    627 {
    628         static struct {
    629                 const char *name;
    630                 int nargs;
    631                 int nreturns;
    632                 void *virt;
    633                 u_int size;
    634                 u_int align;
    635                 void *baseaddr;
    636         } args = {
    637                 "claim",
    638                 3,
    639                 1,
    640         };
    641 
    642         args.virt = virt;
    643         args.size = size;
    644         args.align = align;
    645         if (openfirmware(&args) == -1)
    646                 return (void *)-1;
    647         return args.baseaddr;
    648 }
    649 
    650 void
    651 OF_release(virt, size)
    652         void *virt;
    653         u_int size;
    654 {
    655         static struct {
    656                 const char *name;
    657                 int nargs;
    658                 int nreturns;
    659                 void *virt;
    660                 u_int size;
    661         } args = {
    662                 "release",
    663                 2,
    664                 0,
    665         };
    666 
    667         args.virt = virt;
    668         args.size = size;
    669         openfirmware(&args);
    670 }
    671 
    672 int
    673 OF_milliseconds()
    674 {
    675         static struct {
    676                 const char *name;
    677                 int nargs;
    678                 int nreturns;
    679                 int ms;
    680         } args = {
    681                 "milliseconds",
    682                 0,
    683                 1,
    684         };
    685 
    686         openfirmware(&args);
    687         return args.ms;
    688 }
    689 
    690 void
    691 OF_boot(bootspec)
    692 	const char *bootspec;
    693 {
    694 	static struct {
    695 		const char *name;
    696 		int nargs;
    697 		int nreturns;
    698 		const char *bootspec;
    699 	} args = {
    700 		"boot",
    701 		1,
    702 		0,
    703 	};
    704 
    705 	args.bootspec = bootspec;
    706 	openfirmware(&args);
    707 	while (1);			/* just in case */
    708 }
    709 
    710 void
    711 OF_enter()
    712 {
    713 	static struct {
    714 		const char *name;
    715 		int nargs;
    716 		int nreturns;
    717 	} args = {
    718 		"enter",
    719 		0,
    720 		0,
    721 	};
    722 
    723 	openfirmware(&args);
    724 }
    725 
    726 void
    727 OF_exit()
    728 {
    729 	static struct {
    730 		const char *name;
    731 		int nargs;
    732 		int nreturns;
    733 	} args = {
    734 		"exit",
    735 		0,
    736 		0,
    737 	};
    738 
    739 	openfirmware(&args);
    740 	while (1);			/* just in case */
    741 }
    742 
    743 void
    744 (*OF_set_callback(newfunc))(void *)
    745 	void (*newfunc)(void *);
    746 {
    747 	static struct {
    748 		const char *name;
    749 		int nargs;
    750 		int nreturns;
    751 		void (*newfunc)(void *);
    752 		void (*oldfunc)(void *);
    753 	} args = {
    754 		"set-callback",
    755 		1,
    756 		1,
    757 	};
    758 
    759 	args.newfunc = newfunc;
    760 	if (openfirmware(&args) == -1)
    761 		return 0;
    762 	return args.oldfunc;
    763 }
    764