diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/efcode/engine/package.c | |
download | illumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/efcode/engine/package.c')
-rw-r--r-- | usr/src/lib/efcode/engine/package.c | 1077 |
1 files changed, 1077 insertions, 0 deletions
diff --git a/usr/src/lib/efcode/engine/package.c b/usr/src/lib/efcode/engine/package.c new file mode 100644 index 0000000000..b32773f45d --- /dev/null +++ b/usr/src/lib/efcode/engine/package.c @@ -0,0 +1,1077 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> + +#include <fcode/private.h> +#include <fcode/log.h> + +#include <fcdriver/fcdriver.h> + +#define MIN_VALUES 100 + +static void +check_my_self(fcode_env_t *env, char *fn) +{ + if (!MYSELF) + forth_abort(env, "%s: MYSELF is NULL", fn); +} + +uint_t +get_number_of_parent_address_cells(fcode_env_t *env) +{ + uint_t ncells; + device_t *d; + static char func_name[] = "get_number_of_parent_address_cells"; + + if (MYSELF == NULL) /* Kludge for testing */ + return (2); + d = MYSELF->device; + ncells = d->parent_adr_cells; + if (ncells == 0) { + ncells = get_default_intprop(env, "#address-cells", d->parent, + 2); + if (ncells > MAX_MY_ADDR) { + log_message(MSG_ERROR, "%s: %s:" + " ncells (%d) > MAX_MY_ADDR (%d)\n", func_name, + get_path(env, d->parent), ncells, MAX_MY_ADDR); + ncells = MAX_MY_ADDR; + } + d->parent_adr_cells = ncells; + } + return (ncells); +} + +instance_t * +create_ihandle(fcode_env_t *env, device_t *phandle, instance_t *parent) +{ + instance_t *ihandle; + int i; + + ihandle = MALLOC(sizeof (instance_t)); + + i = max(phandle->data_size[INIT_DATA], MIN_VALUES); + ihandle->data[INIT_DATA] = MALLOC(sizeof (fstack_t) * i); + memcpy(ihandle->data[INIT_DATA], phandle->init_data, + (size_t) (sizeof (fstack_t) * i)); + + i = max(phandle->data_size[UINIT_DATA], MIN_VALUES); + ihandle->data[UINIT_DATA] = MALLOC(sizeof (fstack_t) * i); + + ihandle->my_space = phandle->my_space; + memcpy(ihandle->my_addr, phandle->my_addr, sizeof (ihandle->my_addr)); + ihandle->parent = parent; + ihandle->device = phandle; + return (ihandle); +} + +device_t * +create_phandle(fcode_env_t *env, device_t *parent) +{ + device_t *phandle; + + phandle = MALLOC(sizeof (device_t)); + phandle->init_data = MALLOC(sizeof (fstack_t) * MIN_VALUES); + phandle->data_size[INIT_DATA] = 0; + phandle->data_size[UINIT_DATA] = 0; + phandle->parent = parent; + return (phandle); +} + + +static void +do_push_package(fcode_env_t *env, device_t *d) +{ + do_previous(env); + do_also(env); + if (d != NULL) { + CONTEXT = (token_t *)(&d->vocabulary); + debug_msg(DEBUG_CONTEXT, "CONTEXT:push_package: %s%d/%p/%p\n", + get_path(env, d), env->order_depth, CONTEXT, env->current); + } +} + +static void +push_package(fcode_env_t *env) +{ + device_t *d; + phandle_t ph; + + CHECK_DEPTH(env, 1, "push-package"); + ph = POP(DS); + CONVERT_PHANDLE(env, d, ph); + do_push_package(env, d); +} + +static void +pop_package(fcode_env_t *env) +{ + do_previous(env); + do_definitions(env); +} + +static void +interpose(fcode_env_t *env) +{ + TODO; /* interpose - not yet implemented */ +} + +void +activate_device(fcode_env_t *env, device_t *d) +{ + env->current_device = d; + do_push_package(env, d); + do_definitions(env); +} + +void +deactivate_device(fcode_env_t *env, device_t *d) +{ + env->current_device = d; + do_previous(env); + if (d != NULL) { + CONTEXT = (token_t *)(&d->vocabulary); + debug_msg(DEBUG_CONTEXT, "CONTEXT:deactivate_device:" + " %s%d/%p/%p\n", get_path(env, d), env->order_depth, + CONTEXT, env->current); + } + do_definitions(env); +} + +/* + * Starfire hack to set '/' device_type to 'upa' + */ +#include <sys/systeminfo.h> +static void +starfire_hack(fcode_env_t *env) +{ + char platform[100]; + + sysinfo(SI_PLATFORM, platform, sizeof (platform)); + if (strcmp(platform, "SUNW,Ultra-Enterprise-10000") == 0 && + find_property(env->root_node, "device_type") == NULL) { + create_string_prop(env, "device_type", "upa"); + } +} + +void +root_node(fcode_env_t *env) +{ + do_also(env); + activate_device(env, env->root_node); + starfire_hack(env); +} + +void +child_node(fcode_env_t *env) +{ + device_t *d; + + CHECK_DEPTH(env, 1, "child"); + CONVERT_PHANDLE(env, d, TOS); + TOS = (fstack_t)d->child; + REVERT_PHANDLE(env, TOS, d->child); +} + +void +peer_node(fcode_env_t *env) +{ + device_t *d; + + CHECK_DEPTH(env, 1, "peer"); + CONVERT_PHANDLE(env, d, TOS); + REVERT_PHANDLE(env, TOS, d->peer); +} + +void +new_device(fcode_env_t *env) +{ + device_t *phandle, *parent; + device_t *peer; + + check_my_self(env, "new-device"); + + parent = MYSELF->device; + phandle = create_phandle(env, parent); + MYSELF = create_ihandle(env, phandle, MYSELF); + activate_device(env, phandle); + if (parent->child) { + /* Insert new child at end of peer list */ + for (peer = parent->child; peer->peer; peer = peer->peer) + ; + peer->peer = phandle; + } else + parent->child = phandle; /* First child */ + ALLOCATE_PHANDLE(env); +} + +void +finish_device(fcode_env_t *env) +{ + fstack_t *mem; + device_t *my_dev, *parent_dev; + instance_t *parent, *myself = MYSELF; + int n; + + check_my_self(env, "finish-device"); + ASSERT(myself->device); + ASSERT(env->current_device); + n = myself->device->data_size[INIT_DATA]; + + /* + * Paranoia.. reserve a little more instance data than we need + */ + mem = MALLOC(sizeof (fstack_t) * (n+8)); + memcpy(mem, MYSELF->device->init_data, sizeof (fstack_t) * n); + FREE(myself->device->init_data); + my_dev = myself->device; + my_dev->init_data = mem; + parent = MYSELF->parent; + parent_dev = env->current_device->parent; + FREE(MYSELF); + MYSELF = parent; + activate_device(env, parent_dev); +} + +static void +create_internal_value(fcode_env_t *env, char *name, int offset, int token) +{ + header(env, name, strlen(name), 0); + COMPILE_TOKEN(&noop); + EXPOSE_ACF; + if (token) { + SET_TOKEN(token, 0, name, LINK_TO_ACF(env->lastlink)); + } + PUSH(DS, offset); + lcomma(env); + set_internal_value_actions(env); +} + +static void +create_my_self(fcode_env_t *env) +{ + int offset = offsetof(fcode_env_t, my_self); + + create_internal_value(env, "my-self", offset, 0x203); +} + +static void +create_my_space(fcode_env_t *env) +{ + int offset = offsetof(instance_t, my_space); + + create_internal_value(env, "my-space", -offset, 0x103); +} + +void +my_address(fcode_env_t *env) +{ + fstack_t *adr_ptr; + uint_t ncells; + + check_my_self(env, "my-address"); + ncells = get_number_of_parent_address_cells(env); + adr_ptr = MYSELF->my_addr; + while (--ncells) { + PUSH(DS, *adr_ptr); + adr_ptr++; + } +} + +void +my_unit(fcode_env_t *env) +{ + check_my_self(env, "my-unit"); + my_address(env); + PUSH(DS, MYSELF->my_space); +} + +static void +my_args(fcode_env_t *env) +{ + check_my_self(env, "my-args"); + PUSH(DS, (fstack_t)MYSELF->my_args); + PUSH(DS, (fstack_t)MYSELF->my_args_len); +} + +int +call_my_parent(fcode_env_t *env, char *method) +{ + push_a_string(env, method); + dollar_call_parent(env); + return (env->last_error); +} + +void +set_args(fcode_env_t *env) +{ + int args_len; + common_data_t *cdp; + uint_t ncells; + fstack_t *adr_ptr, *adr_ptr1, space; + + CHECK_DEPTH(env, 4, "set-args"); + + check_my_self(env, "set-args"); + + /* + * Handle args argument of set-args. + */ + if (MYSELF->my_args) { + FREE(MYSELF->my_args); + MYSELF->my_args = NULL; + } + two_swap(env); + MYSELF->my_args = pop_a_duped_string(env, &args_len); + MYSELF->my_args_len = args_len; + + if (call_my_parent(env, "decode-unit")) + forth_abort(env, "set-args: decode-unit failed"); + + ncells = get_number_of_parent_address_cells(env); + + /* + * Kludge: For GP2, my-space comes from decode-unit hi.address. + * for PCI, my-space from decode-unit won't have the bus#, so we need + * to get it from config_address. Unfortunately, there is no easy + * way to figure out here which one we're looking at. We take the + * expediant of or'ing the two values together. + */ + space = POP(DS); /* pop phys.hi */ + if ((cdp = (common_data_t *)env->private) != NULL) + space |= cdp->fc.config_address; + + MYSELF->device->my_space = MYSELF->my_space = space; + + adr_ptr = MYSELF->my_addr; + adr_ptr1 = MYSELF->device->my_addr; + while (--ncells) { + *adr_ptr++ = *adr_ptr1++ = POP(DS); + } +} + +void +my_parent(fcode_env_t *env) +{ + check_my_self(env, "my-parent"); + PUSH(DS, (fstack_t)MYSELF->parent); +} + +instance_t * +open_instance_chain(fcode_env_t *env, device_t *phandle, int exec) +{ + instance_t *parent; + + if (!phandle) + return (NULL); + parent = open_instance_chain(env, phandle->parent, exec); + return (create_ihandle(env, phandle, parent)); +} + +void +close_instance_chain(fcode_env_t *env, instance_t *ihandle, int exec) +{ + instance_t *parent; + + if (ihandle) { + parent = ihandle->parent; + close_instance_chain(env, parent, exec); + if (ihandle->my_args) + FREE(ihandle->my_args); + FREE(ihandle); + } +} + +void +begin_package(fcode_env_t *env) +{ + fstack_t ok; + char *name; + + CHECK_DEPTH(env, 6, "begin-package"); + two_dup(env); + name = pop_a_string(env, NULL); + find_package(env); + ok = POP(DS); + if (ok) { + PUSH(DS, 0); + PUSH(DS, 0); + rot(env); + open_package(env); + MYSELF = (instance_t *)POP(DS); + check_my_self(env, "begin-package"); + new_device(env); + set_args(env); + } else { + log_message(MSG_INFO, "Package '%s' not found\n", name); + } +} + +void +open_package(fcode_env_t *env) +{ + device_t *phandle; + instance_t *ihandle; + int len; + + CHECK_DEPTH(env, 3, "open-package"); + CONVERT_PHANDLE(env, phandle, POP(DS)); + ihandle = open_instance_chain(env, phandle, 1); + ihandle->my_args = pop_a_duped_string(env, &len); + ihandle->my_args_len = len; + PUSH(DS, (fstack_t)ihandle); +} + +void +dollar_open_package(fcode_env_t *env) +{ + fstack_t ok; + + CHECK_DEPTH(env, 4, "$open-package"); + find_package(env); + ok = POP(DS); + if (ok) { + open_package(env); + } else { + PUSH(DS, 0); + } +} + +void +close_package(fcode_env_t *env) +{ + instance_t *ihandle; + + CHECK_DEPTH(env, 1, "close-package"); + ihandle = (instance_t *)POP(DS); + close_instance_chain(env, ihandle, 1); +} + +static void (*find_method_hook)(fcode_env_t *); + +void +set_find_method_hook(fcode_env_t *env, void (*hook)(fcode_env_t *)) +{ + find_method_hook = hook; +} + +void +find_method(fcode_env_t *env) +{ + fstack_t d; + device_t *device; + acf_t acf = 0; + + CHECK_DEPTH(env, 3, "find-method"); + if (find_method_hook) { + (*find_method_hook)(env); + if (TOS) /* Found it */ + return; + POP(DS); + } + + d = POP(DS); + CONVERT_PHANDLE(env, device, d); + PUSH(DS, (fstack_t)&device->vocabulary); + acf = voc_find(env); + PUSH(DS, (fstack_t)acf); + if (acf) { + PUSH(DS, TRUE); + } +} + +/* + * 'call-package' Fcode + */ +void +call_package(fcode_env_t *env) +{ + instance_t *ihandle, *saved_myself; + + CHECK_DEPTH(env, 2, "call-package"); + ihandle = (instance_t *)POP(DS); + saved_myself = MYSELF; + MYSELF = ihandle; + execute(env); + MYSELF = saved_myself; +} + +void +ihandle_to_phandle(fcode_env_t *env) +{ + instance_t *i; + + CHECK_DEPTH(env, 1, "ihandle>phandle"); + i = (instance_t *)TOS; + REVERT_PHANDLE(env, TOS, i->device); +} + +char * +get_package_name(fcode_env_t *env, device_t *d) +{ + char *name; + prop_t *prop; + + prop = lookup_package_property(env, "name", d); + if (prop == NULL) { + name = "<Unnamed>"; + } else { + name = (char *)prop->data; + } + return (name); +} + +static char *package_search_path = "/packages:/openprom"; + +device_t * +match_package_path(fcode_env_t *env, char *path) +{ + device_t *d; + char *name; + int len; + + if (*path == '/') { + d = env->root_node->child; + path++; + } else + d = env->current_device; + while (*path != '\0' && d != NULL) { + name = get_package_name(env, d); + len = strlen(name); + if (strncmp(name, path, len) == 0) { + path += len; + if (*path == '\0') { + return (d); + } + /* skip the '/' */ + if (*path++ != '/') + break; + d = d->child; + } else { + d = d->peer; + } + } + return (NULL); +} + +device_t * +locate_package(fcode_env_t *env, char *start) +{ + device_t *d; + char *p, *next_p; + char *tpath, *fpath; + + if ((d = match_package_path(env, start)) != NULL) + return (d); + + /* + * ignore starting '/' + */ + if (*start == '/') + *start++; + + fpath = STRDUP(package_search_path); + for (p = fpath; p != NULL; p = next_p) { + if ((next_p = strchr(p, ':')) != NULL) + *next_p++ = '\0'; + tpath = MALLOC(strlen(p) + strlen(start) + 2); + sprintf(tpath, "%s/%s", p, start); + if ((d = match_package_path(env, tpath)) != NULL) { + FREE(fpath); + FREE(tpath); + return (d); + } + FREE(tpath); + } + FREE(fpath); + return (NULL); +} + +void +find_package(fcode_env_t *env) +{ + char *path; + device_t *package; + fstack_t ph = 0; + + CHECK_DEPTH(env, 2, "find-package"); + if ((path = pop_a_duped_string(env, NULL)) != NULL) { + if (strcmp(path, "/") == 0) + package = env->root_node; + else + package = locate_package(env, path); + FREE(path); + REVERT_PHANDLE(env, ph, package); + } + PUSH(DS, ph); + if (package) + PUSH(DS, TRUE); +} + +static void +encode_unit_hack(fcode_env_t *env) +{ + int hi, i; + uint_t ncells = get_number_of_parent_address_cells(env); + + for (i = 0; i < ncells; i++) + POP(DS); + push_a_string(env, NULL); +} + +void +dollar_call_method(fcode_env_t *env) +{ + instance_t *old_myself; + instance_t *myself; + device_t *device; + char *method; + + CHECK_DEPTH(env, 3, "$call-method"); + check_my_self(env, "$call-method"); + old_myself = MYSELF; + myself = (instance_t *)POP(DS); + + method = (char *)DS[-1]; + debug_msg(DEBUG_CALL_METHOD, "$call_method %s\n", method); + + if (old_myself && !myself) { + /* We hit the root of our tree */ + device = old_myself->device; + return; + } + + MYSELF = myself; + check_my_self(env, "$call-method"); + device = MYSELF->device; + do_push_package(env, device); + PUSH(DS, (fstack_t)device); + REVERT_PHANDLE(env, TOS, device); + find_method(env); + if (TOS) { + (void) POP(DS); + execute(env); + } else if (strcmp(method, "encode-unit") == 0) { + encode_unit_hack(env); + } else { + throw_from_fclib(env, 1, "Unimplemented package method: %s%s", + get_path(env, device), method); + } + MYSELF = old_myself; + do_push_package(env, MYSELF->device); +} + +void +dollar_call_parent(fcode_env_t *env) +{ + CHECK_DEPTH(env, 2, "$call-parent"); + + check_my_self(env, "$call-parent"); + + PUSH(DS, (fstack_t)MYSELF->parent); + dollar_call_method(env); +} + +#ifdef DEBUG +void +current_device(fcode_env_t *env) +{ + PUSH(DS, (fstack_t)&env->current_device); +} + +char * +get_path(fcode_env_t *env, device_t *d) +{ + char *pre_path, *name, *path; + int n; + + if (d->parent) + pre_path = get_path(env, d->parent); + else + pre_path = STRDUP(""); + + name = get_package_name(env, d); + n = strlen(pre_path) + strlen(name) + 1; + path = MALLOC(n); + strcpy(path, pre_path); + strcat(path, name); + if (d->child && d->parent) + strcat(path, "/"); + FREE(pre_path); + return (path); +} + +static void +pwd_dollar(fcode_env_t *env) +{ + if (env->current_device) + push_a_string(env, get_path(env, env->current_device)); + else + push_a_string(env, NULL); +} + +void +pwd(fcode_env_t *env) +{ + if (env->current_device) { + log_message(MSG_INFO, "%s\n", + get_path(env, env->current_device)); + } else { + log_message(MSG_INFO, "No device context\n"); + } +} + +void +do_ls(fcode_env_t *env) +{ + device_t *d; + + if (env->current_device == NULL) { + log_message(MSG_INFO, "No device context\n"); + return; + } + + d = env->current_device->child; + while (d) { + char *name; + fstack_t ph; + name = get_package_name(env, d); + REVERT_PHANDLE(env, ph, d); + log_message(MSG_INFO, "%llx %s\n", (uint64_t)ph, name); + d = d->peer; + } +} + +void +paren_cd(fcode_env_t *env) +{ + char *str; + device_t *p; + + str = pop_a_string(env, NULL); + if (strcmp(str, "/") == 0) { + root_node(env); + return; + } + + if (env->current_device == NULL) { + log_message(MSG_INFO, "No device context\n"); + return; + } + + if (strcmp(str, "..") == 0) + p = env->current_device->parent; + else { + device_t *n = env->current_device->child; + + p = NULL; + while (n) { + char *name; + + name = get_package_name(env, n); + if (strcmp(name, str) == 0) { + p = n; + break; + } + n = n->peer; + } + } + + if (p) { + activate_device(env, p); + } else { + log_message(MSG_INFO, "No such node: %s\n", str); + } +} + +void +do_cd(fcode_env_t *env) +{ + parse_word(env); + paren_cd(env); +} + +void +do_unselect_dev(fcode_env_t *env) +{ + check_my_self(env, "unselect-dev"); + PUSH(DS, (fstack_t)MYSELF); + close_package(env); + deactivate_device(env, NULL); +} + +void +do_select_dev(fcode_env_t *env) +{ + PUSH(DS, 0); + PUSH(DS, 0); + two_swap(env); + dollar_open_package(env); + if (TOS) { + MYSELF = (instance_t *)POP(DS); + check_my_self(env, "select-dev"); + activate_device(env, MYSELF->device); + } else { + drop(env); + log_message(MSG_INFO, "Can't open package\n"); + } +} + +void +device_end(fcode_env_t *env) +{ + if (env->current_device) { + deactivate_device(env, NULL); + } +} + +void +end_package(fcode_env_t *env) +{ + finish_device(env); + close_instance_chain(env, MYSELF, 0); + device_end(env); + MYSELF = NULL; +} + +void +exec_parent_method(fcode_env_t *env) +{ + instance_t *old_myself; + instance_t *myself; + device_t *device; + char *method; + fstack_t d; + + check_my_self(env, "exec-parent-method"); + old_myself = MYSELF; + MYSELF = MYSELF->parent; + + method = (char *)DS[-1]; + debug_msg(DEBUG_FIND_FCODE, "exec_parent_method: '%s'\n", method); + + check_my_self(env, "exec-parent-method"); + device = MYSELF->device; + do_push_package(env, device); + PUSH(DS, (fstack_t)device); + REVERT_PHANDLE(env, TOS, device); + find_method(env); + d = POP(DS); + if (d) { + debug_msg(DEBUG_FIND_FCODE, "exec-parent-method: '%s'/%x" + " execute\n", method, (int)TOS); + execute(env); + PUSH(DS, TRUE); + } else { + debug_msg(DEBUG_FIND_FCODE, "exec-parent-method: '%s'" + " not found\n", method); + PUSH(DS, FALSE); + } + MYSELF = old_myself; + do_push_package(env, MYSELF->device); +} + +void +dump_device(fcode_env_t *env) +{ + device_t *phandle; + int i; + + CONVERT_PHANDLE(env, phandle, POP(DS)); + log_message(MSG_DEBUG, "Node: %p\n", phandle); + log_message(MSG_DEBUG, " Parent: (%8p) %p\n", + &phandle->parent, phandle->parent); + log_message(MSG_DEBUG, " Child: (%8p) %p\n", + &phandle->child, phandle->child); + log_message(MSG_DEBUG, " Peer: (%8p) %p\n", + &phandle->peer, phandle->peer); + log_message(MSG_DEBUG, " Private: (%8p) %p\n", + &phandle->private, phandle->private); + log_message(MSG_DEBUG, " Props: (%8p) %p\n", + &phandle->properties, phandle->properties); + log_message(MSG_DEBUG, " Voc: (%8p) %p\n", + &phandle->vocabulary, phandle->vocabulary); + log_message(MSG_DEBUG, " sizes: (%8p) %d %d\n", + &phandle->data_size, + phandle->data_size[INIT_DATA], + phandle->data_size[UINIT_DATA]); + log_message(MSG_DEBUG, " my_space: %x\n", phandle->my_space); + log_message(MSG_DEBUG, " my_addr :"); + for (i = 0; i < MAX_MY_ADDR; i++) + log_message(MSG_DEBUG, " %x", (int)phandle->my_addr[i]); + log_message(MSG_DEBUG, "\n"); + log_message(MSG_DEBUG, " data: (%8p)\n", phandle->init_data); + for (i = 0; i < phandle->data_size[INIT_DATA]; i++) { + log_message(MSG_DEBUG, " %3d -> (%8p) %x\n", i, + &phandle->init_data[i], phandle->init_data[i]); + } +} + +void +dump_instance(fcode_env_t *env) +{ + int i; + instance_t *ihandle; + + ihandle = (instance_t *)POP(DS); + log_message(MSG_DEBUG, "Ihandle: %p\n", ihandle); + log_message(MSG_DEBUG, " Parent: (%8p) %p\n", + &ihandle->parent, ihandle->parent); + log_message(MSG_DEBUG, " Device: (%8p) %p\n", + &ihandle->device, ihandle->device); + log_message(MSG_DEBUG, " args: '%s'\n", + ((ihandle->my_args) ? ihandle->my_args : "")); + log_message(MSG_DEBUG, " my-space: %x\n", ihandle->my_space); + log_message(MSG_DEBUG, " my_addr :"); + for (i = 0; i < MAX_MY_ADDR; i++) + log_message(MSG_DEBUG, " %x", (int)ihandle->my_addr[i]); + log_message(MSG_DEBUG, "\n"); + log_message(MSG_DEBUG, " sizes: %d %d\n", + ihandle->device->data_size[INIT_DATA], + ihandle->device->data_size[UINIT_DATA]); + log_message(MSG_DEBUG, " data: (%8p) %x %x\n", + ihandle->data, ihandle->data[0], ihandle->data[1]); + if (ihandle->device->data_size[INIT_DATA]) { + log_message(MSG_DEBUG, " Initialised:\n"); + for (i = 0; i < ihandle->device->data_size[INIT_DATA]; i++) { + log_message(MSG_DEBUG, " %3d -> (%8p) %x\n", i, + &ihandle->data[INIT_DATA][i], + ihandle->data[INIT_DATA][i]); + } + } + if (ihandle->device->data_size[INIT_DATA]) { + log_message(MSG_DEBUG, " UnInitialised:\n"); + for (i = 0; i < ihandle->device->data_size[UINIT_DATA]; i++) { + log_message(MSG_DEBUG, " %3d -> (%8p) %x\n", i, + &ihandle->data[UINIT_DATA][i], + ihandle->data[UINIT_DATA][i]); + } + } +} + +#endif + +#pragma init(_init) + +#ifdef CONVERT_HANDLES +static device_t * +safe_convert_phandle(fcode_env_t *env, fstack_t d) +{ + return ((device_t *)d); +} + +static fstack_t +safe_revert_phandle(fcode_env_t *env, device_t *d) +{ + return ((fstack_t)d); +} + +static void +safe_allocate_phandle(fcode_env_t *env) +{ +} + +#endif + +static void +_init(void) +{ + fcode_env_t *env = initial_env; + char *name = "/"; + device_t *d; + + ASSERT(env); + NOTICE; + +#ifdef CONVERT_HANDLES + env->convert_phandle = safe_convert_phandle; + env->revert_phandle = safe_revert_phandle; + env->allocate_phandle = safe_allocate_phandle; +#endif + + /* build the root node */ + d = create_phandle(env, NULL); + env->current_device = d; + env->root_node = d; + push_a_string(env, name); + device_name(env); + env->current_device = NULL; + + create_my_self(env); + create_my_space(env); + + P1275(0x102, 0, "my-address", my_address); + /* Fcode 0x103 "my-space" is created using create_internal_value */ + + P1275(0x11f, 0, "new-device", new_device); + + P1275(0x127, 0, "finish-device", finish_device); + + FCODE(0x129, 0, "push-package", push_package); + FCODE(0x12a, 0, "pop-package", pop_package); + FCODE(0x12b, 0, "interpose", interpose); + + P1275(0x202, 0, "my-args", my_args); + /* Fcode 0x203 "my-self" is created using create_internal_value */ + P1275(0x204, 0, "find-package", find_package); + P1275(0x205, 0, "open-package", open_package); + P1275(0x206, 0, "close-package", close_package); + P1275(0x207, 0, "find-method", find_method); + P1275(0x208, 0, "call-package", call_package); + P1275(0x209, 0, "$call-parent", dollar_call_parent); + P1275(0x20a, 0, "my-parent", my_parent); + P1275(0x20b, 0, "ihandle>phandle", ihandle_to_phandle); + + P1275(0x20d, 0, "my-unit", my_unit); + P1275(0x20e, 0, "$call-method", dollar_call_method); + P1275(0x20f, 0, "$open-package", dollar_open_package); + + P1275(0x23b, 0, "child", child_node); + P1275(0x23c, 0, "peer", peer_node); + + P1275(0x23f, 0, "set-args", set_args); + + FORTH(IMMEDIATE, "root-node", root_node); + FORTH(0, "current-device", current_device); + FORTH(0, "pwd$", pwd_dollar); + FORTH(IMMEDIATE, "pwd", pwd); + FORTH(IMMEDIATE, "ls", do_ls); + FORTH(IMMEDIATE, "(cd)", paren_cd); + FORTH(IMMEDIATE, "cd", do_cd); + FORTH(IMMEDIATE, "device-end", device_end); + FORTH(0, "select-dev", do_select_dev); + FORTH(0, "unselect-dev", do_unselect_dev); + FORTH(0, "begin-package", begin_package); + FORTH(0, "end-package", end_package); + FORTH(IMMEDIATE, "dump-device", dump_device); + FORTH(IMMEDIATE, "dump-instance", dump_instance); + FORTH(0, "exec-parent-method", exec_parent_method); +} |