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