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