1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <stddef.h> 32 #include <string.h> 33 34 #include <fcode/private.h> 35 #include <fcode/log.h> 36 37 #include <fcdriver/fcdriver.h> 38 39 #define MIN_VALUES 100 40 41 static void 42 check_my_self(fcode_env_t *env, char *fn) 43 { 44 if (!MYSELF) 45 forth_abort(env, "%s: MYSELF is NULL", fn); 46 } 47 48 uint_t 49 get_number_of_parent_address_cells(fcode_env_t *env) 50 { 51 uint_t ncells; 52 device_t *d; 53 static char func_name[] = "get_number_of_parent_address_cells"; 54 55 if (MYSELF == NULL) /* Kludge for testing */ 56 return (2); 57 d = MYSELF->device; 58 ncells = d->parent_adr_cells; 59 if (ncells == 0) { 60 ncells = get_default_intprop(env, "#address-cells", d->parent, 61 2); 62 if (ncells > MAX_MY_ADDR) { 63 log_message(MSG_ERROR, "%s: %s:" 64 " ncells (%d) > MAX_MY_ADDR (%d)\n", func_name, 65 get_path(env, d->parent), ncells, MAX_MY_ADDR); 66 ncells = MAX_MY_ADDR; 67 } 68 d->parent_adr_cells = ncells; 69 } 70 return (ncells); 71 } 72 73 instance_t * 74 create_ihandle(fcode_env_t *env, device_t *phandle, instance_t *parent) 75 { 76 instance_t *ihandle; 77 int i; 78 79 ihandle = MALLOC(sizeof (instance_t)); 80 81 i = max(phandle->data_size[INIT_DATA], MIN_VALUES); 82 ihandle->data[INIT_DATA] = MALLOC(sizeof (fstack_t) * i); 83 memcpy(ihandle->data[INIT_DATA], phandle->init_data, 84 (size_t) (sizeof (fstack_t) * i)); 85 86 i = max(phandle->data_size[UINIT_DATA], MIN_VALUES); 87 ihandle->data[UINIT_DATA] = MALLOC(sizeof (fstack_t) * i); 88 89 ihandle->my_space = phandle->my_space; 90 memcpy(ihandle->my_addr, phandle->my_addr, sizeof (ihandle->my_addr)); 91 ihandle->parent = parent; 92 ihandle->device = phandle; 93 return (ihandle); 94 } 95 96 device_t * 97 create_phandle(fcode_env_t *env, device_t *parent) 98 { 99 device_t *phandle; 100 101 phandle = MALLOC(sizeof (device_t)); 102 phandle->init_data = MALLOC(sizeof (fstack_t) * MIN_VALUES); 103 phandle->data_size[INIT_DATA] = 0; 104 phandle->data_size[UINIT_DATA] = 0; 105 phandle->parent = parent; 106 return (phandle); 107 } 108 109 110 static void 111 do_push_package(fcode_env_t *env, device_t *d) 112 { 113 do_previous(env); 114 do_also(env); 115 if (d != NULL) { 116 CONTEXT = (token_t *)(&d->vocabulary); 117 debug_msg(DEBUG_CONTEXT, "CONTEXT:push_package: %s%d/%p/%p\n", 118 get_path(env, d), env->order_depth, CONTEXT, env->current); 119 } 120 } 121 122 static void 123 push_package(fcode_env_t *env) 124 { 125 device_t *d; 126 phandle_t ph; 127 128 CHECK_DEPTH(env, 1, "push-package"); 129 ph = POP(DS); 130 CONVERT_PHANDLE(env, d, ph); 131 do_push_package(env, d); 132 } 133 134 static void 135 pop_package(fcode_env_t *env) 136 { 137 do_previous(env); 138 do_definitions(env); 139 } 140 141 static void 142 interpose(fcode_env_t *env) 143 { 144 TODO; /* interpose - not yet implemented */ 145 } 146 147 void 148 activate_device(fcode_env_t *env, device_t *d) 149 { 150 env->current_device = d; 151 do_push_package(env, d); 152 do_definitions(env); 153 } 154 155 void 156 deactivate_device(fcode_env_t *env, device_t *d) 157 { 158 env->current_device = d; 159 do_previous(env); 160 if (d != NULL) { 161 CONTEXT = (token_t *)(&d->vocabulary); 162 debug_msg(DEBUG_CONTEXT, "CONTEXT:deactivate_device:" 163 " %s%d/%p/%p\n", get_path(env, d), env->order_depth, 164 CONTEXT, env->current); 165 } 166 do_definitions(env); 167 } 168 169 /* 170 * Starfire hack to set '/' device_type to 'upa' 171 */ 172 #include <sys/systeminfo.h> 173 static void 174 starfire_hack(fcode_env_t *env) 175 { 176 char platform[100]; 177 178 sysinfo(SI_PLATFORM, platform, sizeof (platform)); 179 if (strcmp(platform, "SUNW,Ultra-Enterprise-10000") == 0 && 180 find_property(env->root_node, "device_type") == NULL) { 181 create_string_prop(env, "device_type", "upa"); 182 } 183 } 184 185 void 186 root_node(fcode_env_t *env) 187 { 188 do_also(env); 189 activate_device(env, env->root_node); 190 starfire_hack(env); 191 } 192 193 void 194 child_node(fcode_env_t *env) 195 { 196 device_t *d; 197 198 CHECK_DEPTH(env, 1, "child"); 199 CONVERT_PHANDLE(env, d, TOS); 200 TOS = (fstack_t)d->child; 201 REVERT_PHANDLE(env, TOS, d->child); 202 } 203 204 void 205 peer_node(fcode_env_t *env) 206 { 207 device_t *d; 208 209 CHECK_DEPTH(env, 1, "peer"); 210 CONVERT_PHANDLE(env, d, TOS); 211 REVERT_PHANDLE(env, TOS, d->peer); 212 } 213 214 void 215 new_device(fcode_env_t *env) 216 { 217 device_t *phandle, *parent; 218 device_t *peer; 219 220 check_my_self(env, "new-device"); 221 222 parent = MYSELF->device; 223 phandle = create_phandle(env, parent); 224 MYSELF = create_ihandle(env, phandle, MYSELF); 225 activate_device(env, phandle); 226 if (parent->child) { 227 /* Insert new child at end of peer list */ 228 for (peer = parent->child; peer->peer; peer = peer->peer) 229 ; 230 peer->peer = phandle; 231 } else 232 parent->child = phandle; /* First child */ 233 ALLOCATE_PHANDLE(env); 234 } 235 236 void 237 finish_device(fcode_env_t *env) 238 { 239 fstack_t *mem; 240 device_t *my_dev, *parent_dev; 241 instance_t *parent, *myself = MYSELF; 242 int n; 243 244 check_my_self(env, "finish-device"); 245 ASSERT(myself->device); 246 ASSERT(env->current_device); 247 n = myself->device->data_size[INIT_DATA]; 248 249 /* 250 * Paranoia.. reserve a little more instance data than we need 251 */ 252 mem = MALLOC(sizeof (fstack_t) * (n+8)); 253 memcpy(mem, MYSELF->device->init_data, sizeof (fstack_t) * n); 254 FREE(myself->device->init_data); 255 my_dev = myself->device; 256 my_dev->init_data = mem; 257 parent = MYSELF->parent; 258 parent_dev = env->current_device->parent; 259 FREE(MYSELF); 260 MYSELF = parent; 261 activate_device(env, parent_dev); 262 } 263 264 static void 265 create_internal_value(fcode_env_t *env, char *name, int offset, int token) 266 { 267 header(env, name, strlen(name), 0); 268 COMPILE_TOKEN(&noop); 269 EXPOSE_ACF; 270 if (token) { 271 SET_TOKEN(token, 0, name, LINK_TO_ACF(env->lastlink)); 272 } 273 PUSH(DS, offset); 274 lcomma(env); 275 set_internal_value_actions(env); 276 } 277 278 static void 279 create_my_self(fcode_env_t *env) 280 { 281 int offset = offsetof(fcode_env_t, my_self); 282 283 create_internal_value(env, "my-self", offset, 0x203); 284 } 285 286 static void 287 create_my_space(fcode_env_t *env) 288 { 289 int offset = offsetof(instance_t, my_space); 290 291 create_internal_value(env, "my-space", -offset, 0x103); 292 } 293 294 void 295 my_address(fcode_env_t *env) 296 { 297 fstack_t *adr_ptr; 298 uint_t ncells; 299 300 check_my_self(env, "my-address"); 301 ncells = get_number_of_parent_address_cells(env); 302 adr_ptr = MYSELF->my_addr; 303 while (--ncells) { 304 PUSH(DS, *adr_ptr); 305 adr_ptr++; 306 } 307 } 308 309 void 310 my_unit(fcode_env_t *env) 311 { 312 check_my_self(env, "my-unit"); 313 my_address(env); 314 PUSH(DS, MYSELF->my_space); 315 } 316 317 static void 318 my_args(fcode_env_t *env) 319 { 320 check_my_self(env, "my-args"); 321 PUSH(DS, (fstack_t)MYSELF->my_args); 322 PUSH(DS, (fstack_t)MYSELF->my_args_len); 323 } 324 325 int 326 call_my_parent(fcode_env_t *env, char *method) 327 { 328 push_a_string(env, method); 329 dollar_call_parent(env); 330 return (env->last_error); 331 } 332 333 void 334 set_args(fcode_env_t *env) 335 { 336 int args_len; 337 common_data_t *cdp; 338 uint_t ncells; 339 fstack_t *adr_ptr, *adr_ptr1, space; 340 341 CHECK_DEPTH(env, 4, "set-args"); 342 343 check_my_self(env, "set-args"); 344 345 /* 346 * Handle args argument of set-args. 347 */ 348 if (MYSELF->my_args) { 349 FREE(MYSELF->my_args); 350 MYSELF->my_args = NULL; 351 } 352 two_swap(env); 353 MYSELF->my_args = pop_a_duped_string(env, &args_len); 354 MYSELF->my_args_len = args_len; 355 356 if (call_my_parent(env, "decode-unit")) 357 forth_abort(env, "set-args: decode-unit failed"); 358 359 ncells = get_number_of_parent_address_cells(env); 360 361 /* 362 * Kludge: For GP2, my-space comes from decode-unit hi.address. 363 * for PCI, my-space from decode-unit won't have the bus#, so we need 364 * to get it from config_address. Unfortunately, there is no easy 365 * way to figure out here which one we're looking at. We take the 366 * expediant of or'ing the two values together. 367 */ 368 space = POP(DS); /* pop phys.hi */ 369 if ((cdp = (common_data_t *)env->private) != NULL) 370 space |= cdp->fc.config_address; 371 372 MYSELF->device->my_space = MYSELF->my_space = space; 373 374 adr_ptr = MYSELF->my_addr; 375 adr_ptr1 = MYSELF->device->my_addr; 376 while (--ncells) { 377 *adr_ptr++ = *adr_ptr1++ = POP(DS); 378 } 379 } 380 381 void 382 my_parent(fcode_env_t *env) 383 { 384 check_my_self(env, "my-parent"); 385 PUSH(DS, (fstack_t)MYSELF->parent); 386 } 387 388 instance_t * 389 open_instance_chain(fcode_env_t *env, device_t *phandle, int exec) 390 { 391 instance_t *parent; 392 393 if (!phandle) 394 return (NULL); 395 parent = open_instance_chain(env, phandle->parent, exec); 396 return (create_ihandle(env, phandle, parent)); 397 } 398 399 void 400 close_instance_chain(fcode_env_t *env, instance_t *ihandle, int exec) 401 { 402 instance_t *parent; 403 404 if (ihandle) { 405 parent = ihandle->parent; 406 close_instance_chain(env, parent, exec); 407 if (ihandle->my_args) 408 FREE(ihandle->my_args); 409 FREE(ihandle); 410 } 411 } 412 413 void 414 begin_package(fcode_env_t *env) 415 { 416 fstack_t ok; 417 char *name; 418 419 CHECK_DEPTH(env, 6, "begin-package"); 420 two_dup(env); 421 name = pop_a_string(env, NULL); 422 find_package(env); 423 ok = POP(DS); 424 if (ok) { 425 PUSH(DS, 0); 426 PUSH(DS, 0); 427 rot(env); 428 open_package(env); 429 MYSELF = (instance_t *)POP(DS); 430 check_my_self(env, "begin-package"); 431 new_device(env); 432 set_args(env); 433 } else { 434 log_message(MSG_INFO, "Package '%s' not found\n", name); 435 } 436 } 437 438 void 439 open_package(fcode_env_t *env) 440 { 441 device_t *phandle; 442 instance_t *ihandle; 443 int len; 444 445 CHECK_DEPTH(env, 3, "open-package"); 446 CONVERT_PHANDLE(env, phandle, POP(DS)); 447 ihandle = open_instance_chain(env, phandle, 1); 448 ihandle->my_args = pop_a_duped_string(env, &len); 449 ihandle->my_args_len = len; 450 PUSH(DS, (fstack_t)ihandle); 451 } 452 453 void 454 dollar_open_package(fcode_env_t *env) 455 { 456 fstack_t ok; 457 458 CHECK_DEPTH(env, 4, "$open-package"); 459 find_package(env); 460 ok = POP(DS); 461 if (ok) { 462 open_package(env); 463 } else { 464 PUSH(DS, 0); 465 } 466 } 467 468 void 469 close_package(fcode_env_t *env) 470 { 471 instance_t *ihandle; 472 473 CHECK_DEPTH(env, 1, "close-package"); 474 ihandle = (instance_t *)POP(DS); 475 close_instance_chain(env, ihandle, 1); 476 } 477 478 static void (*find_method_hook)(fcode_env_t *); 479 480 void 481 set_find_method_hook(fcode_env_t *env, void (*hook)(fcode_env_t *)) 482 { 483 find_method_hook = hook; 484 } 485 486 void 487 find_method(fcode_env_t *env) 488 { 489 fstack_t d; 490 device_t *device; 491 acf_t acf = 0; 492 493 CHECK_DEPTH(env, 3, "find-method"); 494 if (find_method_hook) { 495 (*find_method_hook)(env); 496 if (TOS) /* Found it */ 497 return; 498 POP(DS); 499 } 500 501 d = POP(DS); 502 CONVERT_PHANDLE(env, device, d); 503 PUSH(DS, (fstack_t)&device->vocabulary); 504 acf = voc_find(env); 505 PUSH(DS, (fstack_t)acf); 506 if (acf) { 507 PUSH(DS, TRUE); 508 } 509 } 510 511 /* 512 * 'call-package' Fcode 513 */ 514 void 515 call_package(fcode_env_t *env) 516 { 517 instance_t *ihandle, *saved_myself; 518 519 CHECK_DEPTH(env, 2, "call-package"); 520 ihandle = (instance_t *)POP(DS); 521 saved_myself = MYSELF; 522 MYSELF = ihandle; 523 execute(env); 524 MYSELF = saved_myself; 525 } 526 527 void 528 ihandle_to_phandle(fcode_env_t *env) 529 { 530 instance_t *i; 531 532 CHECK_DEPTH(env, 1, "ihandle>phandle"); 533 i = (instance_t *)TOS; 534 REVERT_PHANDLE(env, TOS, i->device); 535 } 536 537 char * 538 get_package_name(fcode_env_t *env, device_t *d) 539 { 540 char *name; 541 prop_t *prop; 542 543 prop = lookup_package_property(env, "name", d); 544 if (prop == NULL) { 545 name = "<Unnamed>"; 546 } else { 547 name = (char *)prop->data; 548 } 549 return (name); 550 } 551 552 static char *package_search_path = "/packages:/openprom"; 553 554 device_t * 555 match_package_path(fcode_env_t *env, char *path) 556 { 557 device_t *d; 558 char *name; 559 int len; 560 561 if (*path == '/') { 562 d = env->root_node->child; 563 path++; 564 } else 565 d = env->current_device; 566 while (*path != '\0' && d != NULL) { 567 name = get_package_name(env, d); 568 len = strlen(name); 569 if (strncmp(name, path, len) == 0) { 570 path += len; 571 if (*path == '\0') { 572 return (d); 573 } 574 /* skip the '/' */ 575 if (*path++ != '/') 576 break; 577 d = d->child; 578 } else { 579 d = d->peer; 580 } 581 } 582 return (NULL); 583 } 584 585 device_t * 586 locate_package(fcode_env_t *env, char *start) 587 { 588 device_t *d; 589 char *p, *next_p; 590 char *tpath, *fpath; 591 592 if ((d = match_package_path(env, start)) != NULL) 593 return (d); 594 595 /* 596 * ignore starting '/' 597 */ 598 if (*start == '/') 599 *start++; 600 601 fpath = STRDUP(package_search_path); 602 for (p = fpath; p != NULL; p = next_p) { 603 if ((next_p = strchr(p, ':')) != NULL) 604 *next_p++ = '\0'; 605 tpath = MALLOC(strlen(p) + strlen(start) + 2); 606 sprintf(tpath, "%s/%s", p, start); 607 if ((d = match_package_path(env, tpath)) != NULL) { 608 FREE(fpath); 609 FREE(tpath); 610 return (d); 611 } 612 FREE(tpath); 613 } 614 FREE(fpath); 615 return (NULL); 616 } 617 618 void 619 find_package(fcode_env_t *env) 620 { 621 char *path; 622 device_t *package; 623 fstack_t ph = 0; 624 625 CHECK_DEPTH(env, 2, "find-package"); 626 if ((path = pop_a_duped_string(env, NULL)) != NULL) { 627 if (strcmp(path, "/") == 0) 628 package = env->root_node; 629 else 630 package = locate_package(env, path); 631 FREE(path); 632 REVERT_PHANDLE(env, ph, package); 633 } 634 PUSH(DS, ph); 635 if (package) 636 PUSH(DS, TRUE); 637 } 638 639 static void 640 encode_unit_hack(fcode_env_t *env) 641 { 642 int hi, i; 643 uint_t ncells = get_number_of_parent_address_cells(env); 644 645 for (i = 0; i < ncells; i++) 646 POP(DS); 647 push_a_string(env, NULL); 648 } 649 650 void 651 dollar_call_method(fcode_env_t *env) 652 { 653 instance_t *old_myself; 654 instance_t *myself; 655 device_t *device; 656 char *method; 657 658 CHECK_DEPTH(env, 3, "$call-method"); 659 check_my_self(env, "$call-method"); 660 old_myself = MYSELF; 661 myself = (instance_t *)POP(DS); 662 663 method = (char *)DS[-1]; 664 debug_msg(DEBUG_CALL_METHOD, "$call_method %s\n", method); 665 666 if (old_myself && !myself) { 667 /* We hit the root of our tree */ 668 device = old_myself->device; 669 return; 670 } 671 672 MYSELF = myself; 673 check_my_self(env, "$call-method"); 674 device = MYSELF->device; 675 do_push_package(env, device); 676 PUSH(DS, (fstack_t)device); 677 REVERT_PHANDLE(env, TOS, device); 678 find_method(env); 679 if (TOS) { 680 (void) POP(DS); 681 execute(env); 682 } else if (strcmp(method, "encode-unit") == 0) { 683 encode_unit_hack(env); 684 } else { 685 throw_from_fclib(env, 1, "Unimplemented package method: %s%s", 686 get_path(env, device), method); 687 } 688 MYSELF = old_myself; 689 do_push_package(env, MYSELF->device); 690 } 691 692 void 693 dollar_call_parent(fcode_env_t *env) 694 { 695 CHECK_DEPTH(env, 2, "$call-parent"); 696 697 check_my_self(env, "$call-parent"); 698 699 PUSH(DS, (fstack_t)MYSELF->parent); 700 dollar_call_method(env); 701 } 702 703 #ifdef DEBUG 704 void 705 current_device(fcode_env_t *env) 706 { 707 PUSH(DS, (fstack_t)&env->current_device); 708 } 709 710 char * 711 get_path(fcode_env_t *env, device_t *d) 712 { 713 char *pre_path, *name, *path; 714 int n; 715 716 if (d->parent) 717 pre_path = get_path(env, d->parent); 718 else 719 pre_path = STRDUP(""); 720 721 name = get_package_name(env, d); 722 n = strlen(pre_path) + strlen(name) + 1; 723 path = MALLOC(n); 724 strcpy(path, pre_path); 725 strcat(path, name); 726 if (d->child && d->parent) 727 strcat(path, "/"); 728 FREE(pre_path); 729 return (path); 730 } 731 732 static void 733 pwd_dollar(fcode_env_t *env) 734 { 735 if (env->current_device) 736 push_a_string(env, get_path(env, env->current_device)); 737 else 738 push_a_string(env, NULL); 739 } 740 741 void 742 pwd(fcode_env_t *env) 743 { 744 if (env->current_device) { 745 log_message(MSG_INFO, "%s\n", 746 get_path(env, env->current_device)); 747 } else { 748 log_message(MSG_INFO, "No device context\n"); 749 } 750 } 751 752 void 753 do_ls(fcode_env_t *env) 754 { 755 device_t *d; 756 757 if (env->current_device == NULL) { 758 log_message(MSG_INFO, "No device context\n"); 759 return; 760 } 761 762 d = env->current_device->child; 763 while (d) { 764 char *name; 765 fstack_t ph; 766 name = get_package_name(env, d); 767 REVERT_PHANDLE(env, ph, d); 768 log_message(MSG_INFO, "%llx %s\n", (uint64_t)ph, name); 769 d = d->peer; 770 } 771 } 772 773 void 774 paren_cd(fcode_env_t *env) 775 { 776 char *str; 777 device_t *p; 778 779 str = pop_a_string(env, NULL); 780 if (strcmp(str, "/") == 0) { 781 root_node(env); 782 return; 783 } 784 785 if (env->current_device == NULL) { 786 log_message(MSG_INFO, "No device context\n"); 787 return; 788 } 789 790 if (strcmp(str, "..") == 0) 791 p = env->current_device->parent; 792 else { 793 device_t *n = env->current_device->child; 794 795 p = NULL; 796 while (n) { 797 char *name; 798 799 name = get_package_name(env, n); 800 if (strcmp(name, str) == 0) { 801 p = n; 802 break; 803 } 804 n = n->peer; 805 } 806 } 807 808 if (p) { 809 activate_device(env, p); 810 } else { 811 log_message(MSG_INFO, "No such node: %s\n", str); 812 } 813 } 814 815 void 816 do_cd(fcode_env_t *env) 817 { 818 parse_word(env); 819 paren_cd(env); 820 } 821 822 void 823 do_unselect_dev(fcode_env_t *env) 824 { 825 check_my_self(env, "unselect-dev"); 826 PUSH(DS, (fstack_t)MYSELF); 827 close_package(env); 828 deactivate_device(env, NULL); 829 } 830 831 void 832 do_select_dev(fcode_env_t *env) 833 { 834 PUSH(DS, 0); 835 PUSH(DS, 0); 836 two_swap(env); 837 dollar_open_package(env); 838 if (TOS) { 839 MYSELF = (instance_t *)POP(DS); 840 check_my_self(env, "select-dev"); 841 activate_device(env, MYSELF->device); 842 } else { 843 drop(env); 844 log_message(MSG_INFO, "Can't open package\n"); 845 } 846 } 847 848 void 849 device_end(fcode_env_t *env) 850 { 851 if (env->current_device) { 852 deactivate_device(env, NULL); 853 } 854 } 855 856 void 857 end_package(fcode_env_t *env) 858 { 859 finish_device(env); 860 close_instance_chain(env, MYSELF, 0); 861 device_end(env); 862 MYSELF = NULL; 863 } 864 865 void 866 exec_parent_method(fcode_env_t *env) 867 { 868 instance_t *old_myself; 869 instance_t *myself; 870 device_t *device; 871 char *method; 872 fstack_t d; 873 874 check_my_self(env, "exec-parent-method"); 875 old_myself = MYSELF; 876 MYSELF = MYSELF->parent; 877 878 method = (char *)DS[-1]; 879 debug_msg(DEBUG_FIND_FCODE, "exec_parent_method: '%s'\n", method); 880 881 check_my_self(env, "exec-parent-method"); 882 device = MYSELF->device; 883 do_push_package(env, device); 884 PUSH(DS, (fstack_t)device); 885 REVERT_PHANDLE(env, TOS, device); 886 find_method(env); 887 d = POP(DS); 888 if (d) { 889 debug_msg(DEBUG_FIND_FCODE, "exec-parent-method: '%s'/%x" 890 " execute\n", method, (int)TOS); 891 execute(env); 892 PUSH(DS, TRUE); 893 } else { 894 debug_msg(DEBUG_FIND_FCODE, "exec-parent-method: '%s'" 895 " not found\n", method); 896 PUSH(DS, FALSE); 897 } 898 MYSELF = old_myself; 899 do_push_package(env, MYSELF->device); 900 } 901 902 void 903 dump_device(fcode_env_t *env) 904 { 905 device_t *phandle; 906 int i; 907 908 CONVERT_PHANDLE(env, phandle, POP(DS)); 909 log_message(MSG_DEBUG, "Node: %p\n", phandle); 910 log_message(MSG_DEBUG, " Parent: (%8p) %p\n", 911 &phandle->parent, phandle->parent); 912 log_message(MSG_DEBUG, " Child: (%8p) %p\n", 913 &phandle->child, phandle->child); 914 log_message(MSG_DEBUG, " Peer: (%8p) %p\n", 915 &phandle->peer, phandle->peer); 916 log_message(MSG_DEBUG, " Private: (%8p) %p\n", 917 &phandle->private, phandle->private); 918 log_message(MSG_DEBUG, " Props: (%8p) %p\n", 919 &phandle->properties, phandle->properties); 920 log_message(MSG_DEBUG, " Voc: (%8p) %p\n", 921 &phandle->vocabulary, phandle->vocabulary); 922 log_message(MSG_DEBUG, " sizes: (%8p) %d %d\n", 923 &phandle->data_size, 924 phandle->data_size[INIT_DATA], 925 phandle->data_size[UINIT_DATA]); 926 log_message(MSG_DEBUG, " my_space: %x\n", phandle->my_space); 927 log_message(MSG_DEBUG, " my_addr :"); 928 for (i = 0; i < MAX_MY_ADDR; i++) 929 log_message(MSG_DEBUG, " %x", (int)phandle->my_addr[i]); 930 log_message(MSG_DEBUG, "\n"); 931 log_message(MSG_DEBUG, " data: (%8p)\n", phandle->init_data); 932 for (i = 0; i < phandle->data_size[INIT_DATA]; i++) { 933 log_message(MSG_DEBUG, " %3d -> (%8p) %x\n", i, 934 &phandle->init_data[i], phandle->init_data[i]); 935 } 936 } 937 938 void 939 dump_instance(fcode_env_t *env) 940 { 941 int i; 942 instance_t *ihandle; 943 944 ihandle = (instance_t *)POP(DS); 945 log_message(MSG_DEBUG, "Ihandle: %p\n", ihandle); 946 log_message(MSG_DEBUG, " Parent: (%8p) %p\n", 947 &ihandle->parent, ihandle->parent); 948 log_message(MSG_DEBUG, " Device: (%8p) %p\n", 949 &ihandle->device, ihandle->device); 950 log_message(MSG_DEBUG, " args: '%s'\n", 951 ((ihandle->my_args) ? ihandle->my_args : "")); 952 log_message(MSG_DEBUG, " my-space: %x\n", ihandle->my_space); 953 log_message(MSG_DEBUG, " my_addr :"); 954 for (i = 0; i < MAX_MY_ADDR; i++) 955 log_message(MSG_DEBUG, " %x", (int)ihandle->my_addr[i]); 956 log_message(MSG_DEBUG, "\n"); 957 log_message(MSG_DEBUG, " sizes: %d %d\n", 958 ihandle->device->data_size[INIT_DATA], 959 ihandle->device->data_size[UINIT_DATA]); 960 log_message(MSG_DEBUG, " data: (%8p) %x %x\n", 961 ihandle->data, ihandle->data[0], ihandle->data[1]); 962 if (ihandle->device->data_size[INIT_DATA]) { 963 log_message(MSG_DEBUG, " Initialised:\n"); 964 for (i = 0; i < ihandle->device->data_size[INIT_DATA]; i++) { 965 log_message(MSG_DEBUG, " %3d -> (%8p) %x\n", i, 966 &ihandle->data[INIT_DATA][i], 967 ihandle->data[INIT_DATA][i]); 968 } 969 } 970 if (ihandle->device->data_size[INIT_DATA]) { 971 log_message(MSG_DEBUG, " UnInitialised:\n"); 972 for (i = 0; i < ihandle->device->data_size[UINIT_DATA]; i++) { 973 log_message(MSG_DEBUG, " %3d -> (%8p) %x\n", i, 974 &ihandle->data[UINIT_DATA][i], 975 ihandle->data[UINIT_DATA][i]); 976 } 977 } 978 } 979 980 #endif 981 982 #pragma init(_init) 983 984 #ifdef CONVERT_HANDLES 985 static device_t * 986 safe_convert_phandle(fcode_env_t *env, fstack_t d) 987 { 988 return ((device_t *)d); 989 } 990 991 static fstack_t 992 safe_revert_phandle(fcode_env_t *env, device_t *d) 993 { 994 return ((fstack_t)d); 995 } 996 997 static void 998 safe_allocate_phandle(fcode_env_t *env) 999 { 1000 } 1001 1002 #endif 1003 1004 static void 1005 _init(void) 1006 { 1007 fcode_env_t *env = initial_env; 1008 char *name = "/"; 1009 device_t *d; 1010 1011 ASSERT(env); 1012 NOTICE; 1013 1014 #ifdef CONVERT_HANDLES 1015 env->convert_phandle = safe_convert_phandle; 1016 env->revert_phandle = safe_revert_phandle; 1017 env->allocate_phandle = safe_allocate_phandle; 1018 #endif 1019 1020 /* build the root node */ 1021 d = create_phandle(env, NULL); 1022 env->current_device = d; 1023 env->root_node = d; 1024 push_a_string(env, name); 1025 device_name(env); 1026 env->current_device = NULL; 1027 1028 create_my_self(env); 1029 create_my_space(env); 1030 1031 P1275(0x102, 0, "my-address", my_address); 1032 /* Fcode 0x103 "my-space" is created using create_internal_value */ 1033 1034 P1275(0x11f, 0, "new-device", new_device); 1035 1036 P1275(0x127, 0, "finish-device", finish_device); 1037 1038 FCODE(0x129, 0, "push-package", push_package); 1039 FCODE(0x12a, 0, "pop-package", pop_package); 1040 FCODE(0x12b, 0, "interpose", interpose); 1041 1042 P1275(0x202, 0, "my-args", my_args); 1043 /* Fcode 0x203 "my-self" is created using create_internal_value */ 1044 P1275(0x204, 0, "find-package", find_package); 1045 P1275(0x205, 0, "open-package", open_package); 1046 P1275(0x206, 0, "close-package", close_package); 1047 P1275(0x207, 0, "find-method", find_method); 1048 P1275(0x208, 0, "call-package", call_package); 1049 P1275(0x209, 0, "$call-parent", dollar_call_parent); 1050 P1275(0x20a, 0, "my-parent", my_parent); 1051 P1275(0x20b, 0, "ihandle>phandle", ihandle_to_phandle); 1052 1053 P1275(0x20d, 0, "my-unit", my_unit); 1054 P1275(0x20e, 0, "$call-method", dollar_call_method); 1055 P1275(0x20f, 0, "$open-package", dollar_open_package); 1056 1057 P1275(0x23b, 0, "child", child_node); 1058 P1275(0x23c, 0, "peer", peer_node); 1059 1060 P1275(0x23f, 0, "set-args", set_args); 1061 1062 FORTH(IMMEDIATE, "root-node", root_node); 1063 FORTH(0, "current-device", current_device); 1064 FORTH(0, "pwd$", pwd_dollar); 1065 FORTH(IMMEDIATE, "pwd", pwd); 1066 FORTH(IMMEDIATE, "ls", do_ls); 1067 FORTH(IMMEDIATE, "(cd)", paren_cd); 1068 FORTH(IMMEDIATE, "cd", do_cd); 1069 FORTH(IMMEDIATE, "device-end", device_end); 1070 FORTH(0, "select-dev", do_select_dev); 1071 FORTH(0, "unselect-dev", do_unselect_dev); 1072 FORTH(0, "begin-package", begin_package); 1073 FORTH(0, "end-package", end_package); 1074 FORTH(IMMEDIATE, "dump-device", dump_device); 1075 FORTH(IMMEDIATE, "dump-instance", dump_instance); 1076 FORTH(0, "exec-parent-method", exec_parent_method); 1077 } 1078