1 /* $NetBSD: openfirm.c,v 1.5 2005/12/11 12:16:51 christos 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.5 2005/12/11 12:16:51 christos 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_getproplen(handle, prop) 242 int handle; 243 const char *prop; 244 { 245 static struct { 246 const char *name; 247 int nargs; 248 int nreturns; 249 int phandle; 250 const char *prop; 251 int size; 252 } args = { 253 "getproplen", 254 2, 255 1, 256 }; 257 258 args.phandle = handle; 259 args.prop = prop; 260 if (openfirmware(&args) == -1) 261 return -1; 262 return args.size; 263 } 264 265 int 266 OF_finddevice(name) 267 const char *name; 268 { 269 static struct { 270 const char *name; 271 int nargs; 272 int nreturns; 273 const char *device; 274 int phandle; 275 } args = { 276 "finddevice", 277 1, 278 1, 279 }; 280 281 args.device = name; 282 if (openfirmware(&args) == -1) 283 return -1; 284 return args.phandle; 285 } 286 287 int 288 OF_instance_to_path(ihandle, buf, buflen) 289 int ihandle; 290 char *buf; 291 int buflen; 292 { 293 static struct { 294 const char *name; 295 int nargs; 296 int nreturns; 297 int ihandle; 298 char *buf; 299 int buflen; 300 int length; 301 } args = { 302 "instance-to-path", 303 3, 304 1, 305 }; 306 307 args.ihandle = ihandle; 308 args.buf = buf; 309 args.buflen = buflen; 310 if (openfirmware(&args) < 0) 311 return -1; 312 return args.length; 313 } 314 315 int 316 OF_package_to_path(phandle, buf, buflen) 317 int phandle; 318 char *buf; 319 int buflen; 320 { 321 static struct { 322 const char *name; 323 int nargs; 324 int nreturns; 325 int phandle; 326 char *buf; 327 int buflen; 328 int length; 329 } args = { 330 "package-to-path", 331 3, 332 1, 333 }; 334 335 args.phandle = phandle; 336 args.buf = buf; 337 args.buflen = buflen; 338 if (openfirmware(&args) < 0) 339 return -1; 340 return args.length; 341 } 342 343 int 344 #ifdef __STDC__ 345 OF_call_method(const char *method, int ihandle, int nargs, int nreturns, ...) 346 #else 347 OF_call_method(method, ihandle, nargs, nreturns, va_alist) 348 const char *method; 349 int ihandle; 350 int nargs; 351 int nreturns; 352 va_dcl 353 #endif 354 { 355 va_list ap; 356 static struct { 357 const char *name; 358 int nargs; 359 int nreturns; 360 const char *method; 361 int ihandle; 362 int args_n_results[12]; 363 } args = { 364 "call-method", 365 2, 366 1, 367 }; 368 int *ip, n; 369 370 if (nargs > 6) 371 return -1; 372 args.nargs = nargs + 2; 373 args.nreturns = nreturns + 1; 374 args.method = method; 375 args.ihandle = ihandle; 376 va_start(ap, nreturns); 377 for (ip = args.args_n_results + (n = nargs); --n >= 0;) 378 *--ip = va_arg(ap, int); 379 if (openfirmware(&args) == -1) { 380 va_end(ap); 381 return -1; 382 } 383 /* 384 { 385 int i, res; 386 387 printf("call_method(%s): ihandle = %x, nargs = %d, nreturns = %d -- ", 388 method, ihandle, nargs, nreturns); 389 res = openfirmware(&args); 390 printf("res = %x\n", res); 391 printf("\targs_n_results = "); 392 for (i = 0; i < nargs + nreturns + 1; i++) 393 printf("%x ", args.args_n_results[i]); 394 printf("\n"); 395 if (res == -1) return -1; 396 } 397 */ 398 if (args.args_n_results[nargs]) { 399 va_end(ap); 400 return args.args_n_results[nargs]; 401 } 402 for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) 403 *va_arg(ap, int *) = *--ip; 404 va_end(ap); 405 return 0; 406 } 407 408 int 409 #ifdef __STDC__ 410 OF_call_method_1(const char *method, int ihandle, int nargs, ...) 411 #else 412 OF_call_method_1(method, ihandle, nargs, va_alist) 413 const char *method; 414 int ihandle; 415 int nargs; 416 va_dcl 417 #endif 418 { 419 va_list ap; 420 static struct { 421 const char *name; 422 int nargs; 423 int nreturns; 424 const char *method; 425 int ihandle; 426 int args_n_results[8]; 427 } args = { 428 "call-method", 429 2, 430 2, 431 }; 432 int *ip, n; 433 434 if (nargs > 6) 435 return -1; 436 args.nargs = nargs + 2; 437 args.method = method; 438 args.ihandle = ihandle; 439 va_start(ap, nargs); 440 for (ip = args.args_n_results + (n = nargs); --n >= 0;) 441 *--ip = va_arg(ap, int); 442 va_end(ap); 443 if (openfirmware(&args) == -1) 444 return -1; 445 /* 446 { 447 int i, res; 448 449 printf("call_method_1(%s): ihandle = %x, nargs = %d -- ", 450 method, ihandle, nargs); 451 res = openfirmware(&args); 452 printf("res = %x\n", res); 453 printf("\targs_n_results = "); 454 for (i = 0; i < nargs + 2; i++) 455 printf("%x ", args.args_n_results[i]); 456 printf("\n"); 457 if (res == -1) return -1; 458 } 459 */ 460 if (args.args_n_results[nargs]) 461 return -1; 462 return args.args_n_results[nargs + 1]; 463 } 464 465 int 466 OF_open(dname) 467 const char *dname; 468 { 469 static struct { 470 const char *name; 471 int nargs; 472 int nreturns; 473 const char *dname; 474 int handle; 475 } args = { 476 "open", 477 1, 478 1, 479 }; 480 481 args.dname = dname; 482 if (openfirmware(&args) == -1) 483 return -1; 484 return args.handle; 485 } 486 487 void 488 OF_close(handle) 489 int handle; 490 { 491 static struct { 492 const char *name; 493 int nargs; 494 int nreturns; 495 int handle; 496 } args = { 497 "close", 498 1, 499 0, 500 }; 501 502 args.handle = handle; 503 openfirmware(&args); 504 } 505 506 int 507 OF_read(handle, addr, len) 508 int handle; 509 void *addr; 510 int len; 511 { 512 static struct { 513 const char *name; 514 int nargs; 515 int nreturns; 516 int ihandle; 517 void *addr; 518 int len; 519 int actual; 520 } args = { 521 "read", 522 3, 523 1, 524 }; 525 526 args.ihandle = handle; 527 args.addr = addr; 528 args.len = len; 529 if (openfirmware(&args) == -1) 530 return -1; 531 return args.actual; 532 } 533 534 int 535 OF_write(handle, addr, len) 536 int handle; 537 const void *addr; 538 int len; 539 { 540 static struct { 541 const char *name; 542 int nargs; 543 int nreturns; 544 int ihandle; 545 const void *addr; 546 int len; 547 int actual; 548 } args = { 549 "write", 550 3, 551 1, 552 }; 553 554 args.ihandle = handle; 555 args.addr = addr; 556 args.len = len; 557 if (openfirmware(&args) == -1) 558 return -1; 559 return args.actual; 560 } 561 562 int 563 OF_seek(handle, pos) 564 int handle; 565 u_quad_t pos; 566 { 567 static struct { 568 const char *name; 569 int nargs; 570 int nreturns; 571 int handle; 572 int poshi; 573 int poslo; 574 int status; 575 } args = { 576 "seek", 577 3, 578 1, 579 }; 580 581 args.handle = handle; 582 args.poshi = (int)(pos >> 32); 583 args.poslo = (int)pos; 584 if (openfirmware(&args) == -1) 585 return -1; 586 return args.status; 587 } 588 589 void * 590 OF_claim(virt, size, align) 591 void *virt; 592 u_int size; 593 u_int align; 594 { 595 static struct { 596 const char *name; 597 int nargs; 598 int nreturns; 599 void *virt; 600 u_int size; 601 u_int align; 602 void *baseaddr; 603 } args = { 604 "claim", 605 3, 606 1, 607 }; 608 609 args.virt = virt; 610 args.size = size; 611 args.align = align; 612 if (openfirmware(&args) == -1) 613 return (void *)-1; 614 return args.baseaddr; 615 } 616 617 void 618 OF_release(virt, size) 619 void *virt; 620 u_int size; 621 { 622 static struct { 623 const char *name; 624 int nargs; 625 int nreturns; 626 void *virt; 627 u_int size; 628 } args = { 629 "release", 630 2, 631 0, 632 }; 633 634 args.virt = virt; 635 args.size = size; 636 openfirmware(&args); 637 } 638 639 int 640 OF_milliseconds() 641 { 642 static struct { 643 const char *name; 644 int nargs; 645 int nreturns; 646 int ms; 647 } args = { 648 "milliseconds", 649 0, 650 1, 651 }; 652 653 openfirmware(&args); 654 return args.ms; 655 } 656 657 void 658 OF_boot(bootspec) 659 const char *bootspec; 660 { 661 static struct { 662 const char *name; 663 int nargs; 664 int nreturns; 665 const char *bootspec; 666 } args = { 667 "boot", 668 1, 669 0, 670 }; 671 672 args.bootspec = bootspec; 673 openfirmware(&args); 674 while (1); /* just in case */ 675 } 676 677 void 678 OF_enter() 679 { 680 static struct { 681 const char *name; 682 int nargs; 683 int nreturns; 684 } args = { 685 "enter", 686 0, 687 0, 688 }; 689 690 openfirmware(&args); 691 } 692 693 void 694 OF_exit() 695 { 696 static struct { 697 const char *name; 698 int nargs; 699 int nreturns; 700 } args = { 701 "exit", 702 0, 703 0, 704 }; 705 706 openfirmware(&args); 707 while (1); /* just in case */ 708 } 709 710 void 711 (*OF_set_callback(newfunc))(void *) 712 void (*newfunc)(void *); 713 { 714 static struct { 715 const char *name; 716 int nargs; 717 int nreturns; 718 void (*newfunc)(void *); 719 void (*oldfunc)(void *); 720 } args = { 721 "set-callback", 722 1, 723 1, 724 }; 725 726 args.newfunc = newfunc; 727 if (openfirmware(&args) == -1) 728 return 0; 729 return args.oldfunc; 730 } 731