1 /* $NetBSD: openfirm.c,v 1.6 2007/02/28 20:31:40 macallan 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 2007/02/28 20:31:40 macallan 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