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