Home | History | Annotate | Line # | Download | only in ofw
openfirm.c revision 1.9.6.1
      1 /*	$NetBSD: openfirm.c,v 1.9.6.1 2012/02/18 07:31:29 mrg 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.9.6.1 2012/02/18 07:31:29 mrg 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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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__
    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__
    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
    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
    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
    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
    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
    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 *
    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
    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
    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
    650 OF_boot(const char *bootspec)
    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 = bootspec;
    664 	openfirmware(&args);
    665 	while (1);			/* just in case */
    666 }
    667 
    668 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
    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
    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