1 /* $NetBSD: openfirm.c,v 1.8 2009/03/18 10:22:24 cegger 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.8 2009/03/18 10:22:24 cegger 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