1 /* $NetBSD: openfirm.c,v 1.11 2021/02/07 13:59:36 martin 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.11 2021/02/07 13:59:36 martin 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 *btspec) 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 = btspec; 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