summaryrefslogtreecommitdiff
path: root/usr/src/lib/efcode/packages/populate.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/efcode/packages/populate.c')
-rw-r--r--usr/src/lib/efcode/packages/populate.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/usr/src/lib/efcode/packages/populate.c b/usr/src/lib/efcode/packages/populate.c
new file mode 100644
index 0000000000..6d9cc7501e
--- /dev/null
+++ b/usr/src/lib/efcode/packages/populate.c
@@ -0,0 +1,310 @@
+/*
+ * 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 <unistd.h>
+#include <strings.h>
+
+#include <fcode/private.h>
+#include <fcode/log.h>
+
+#include <fcdriver/fcdriver.h>
+
+static device_t *builtin_driver_device;
+
+static int
+is_device_builtin_package(fcode_env_t *env, device_t *d)
+{
+ return (d == builtin_driver_device);
+}
+
+static char *dropin_name;
+
+/*
+ * do-builtin-dropin ( -- )
+ * Convoluted name just in case someone has "do-dropin" word in Fcode.
+ * Somewhat different from do-dropin in OBP, as we just load the Fcode, we
+ * don't do a byte-load.
+ */
+static void
+do_builtin_dropin(fcode_env_t *env)
+{
+ fc_cell_t len, result;
+ char *buf;
+ int error;
+ static char func_name[] = "do-builtin-dropin";
+ extern int check_fcode_header(char *, uchar_t *, int);
+
+ if (dropin_name == NULL) {
+ log_message(MSG_ERROR, "%s: dropin_name not set\n", func_name);
+ return;
+ }
+ debug_msg(DEBUG_FIND_FCODE, "%s: '%s'\n", func_name, dropin_name);
+ error = fc_run_priv(env->private, "sunos,get-fcode-size", 1, 1,
+ fc_ptr2cell(dropin_name), &len);
+ if (error)
+ return;
+ if (len == 0) {
+ log_message(MSG_WARN, "%s: '%s' zero length Fcode\n",
+ func_name, dropin_name);
+ return;
+ }
+ buf = MALLOC(len);
+ error = fc_run_priv(env->private, "sunos,get-fcode", 3, 1,
+ fc_ptr2cell(dropin_name), fc_ptr2cell(buf), len, &result);
+ if (error) {
+ FREE(buf);
+ return;
+ }
+
+ if (check_fcode_header(dropin_name, (uchar_t *)buf, len) == 0)
+ log_message(MSG_WARN, "%s: '%s' fcode header NOT OK\n",
+ func_name, dropin_name);
+
+ debug_msg(DEBUG_FIND_FCODE,
+ "%s: '%s' doing byte-load len: %x\n", func_name, dropin_name,
+ (int)len);
+ PUSH(DS, (fstack_t)buf);
+ PUSH(DS, 1);
+ byte_load(env);
+}
+
+static void
+do_builtin_file(fcode_env_t *env)
+{
+ char *fname;
+ static char func_name[] = "do-builtin-file";
+ fstack_t d;
+
+ if (dropin_name == NULL) {
+ log_message(MSG_ERROR, "%s: dropin_name not set\n", func_name);
+ return;
+ }
+ debug_msg(DEBUG_FIND_FCODE, "%s: '%s'\n", func_name, dropin_name);
+ push_a_string(env, dropin_name);
+ load_file(env);
+ d = POP(DS);
+ if (d) {
+ debug_msg(DEBUG_FIND_FCODE, "%s: byte-load '%s'\n", func_name,
+ dropin_name);
+ PUSH(DS, 1);
+ byte_load(env);
+ } else
+ debug_msg(DEBUG_FIND_FCODE, "%s: load_file '%s' FAIL\n",
+ func_name, dropin_name);
+}
+
+/*
+ * We need to lookup the builtin name via an FC_RUN_PRIV call to make sure
+ * the builtin exists. If it exists, then we need to leave the xt of
+ * do-builtin-dropin on the stack and remember the name for do-dropin. This is
+ * extremely convoluted because we can't a priori populate
+ * SUNW,builtin-drivers.
+ */
+static void
+builtin_driver_method_hook(fcode_env_t *env)
+{
+ device_t *device;
+ char *method, *path;
+ fc_cell_t len;
+ fstack_t d;
+ int error;
+ static char func_name[] = "builtin-driver-method-hook";
+
+ d = POP(DS);
+ CONVERT_PHANDLE(env, device, d);
+ if (!is_device_builtin_package(env, device)) {
+ PUSH(DS, d);
+ PUSH(DS, FALSE);
+ return;
+ }
+
+ method = pop_a_string(env, NULL);
+
+ /*
+ * Check for file in filesystem. If it exists, we'll just try to do
+ * a do-dropin-file.
+ */
+ if ((path = search_for_fcode_file(env, method)) != NULL) {
+ debug_msg(DEBUG_FIND_FCODE, "%s: '%s' file: '%s'\n", func_name,
+ method, path);
+ if (dropin_name) {
+ FREE(dropin_name);
+ }
+ dropin_name = STRDUP(path);
+ push_a_string(env, "do-builtin-file");
+ dollar_find(env);
+ return;
+ }
+
+ error = fc_run_priv(env->private, "sunos,get-fcode-size", 1, 1,
+ fc_ptr2cell(method), &len);
+ if (error || len == 0) {
+ if (len == 0)
+ debug_msg(DEBUG_FIND_FCODE, "%s: '%s' NOT FOUND\n",
+ func_name, method);
+ push_a_string(env, method);
+ PUSH(DS, d);
+ PUSH(DS, FALSE);
+ } else {
+ debug_msg(DEBUG_FIND_FCODE, "%s: '%s' FOUND len: %x\n",
+ func_name, method, (int)len);
+ if (dropin_name) {
+ FREE(dropin_name);
+ }
+ dropin_name = STRDUP(method);
+ push_a_string(env, "do-builtin-dropin");
+ dollar_find(env);
+ }
+}
+
+void
+make_a_node(fcode_env_t *env, char *name, int finish)
+{
+ new_device(env);
+ push_a_string(env, name);
+ device_name(env);
+ if (finish)
+ finish_device(env);
+}
+
+void
+install_package_nodes(fcode_env_t *env)
+{
+ MYSELF = open_instance_chain(env, env->root_node, 0);
+ if (MYSELF != NULL) {
+ make_a_node(env, "packages", 0);
+ make_a_node(env, "disk-label", 0);
+ finish_device(env);
+ make_a_node(env, "SUNW,builtin-drivers", 0);
+ builtin_driver_device = env->current_device;
+ finish_device(env);
+ finish_device(env);
+ close_instance_chain(env, MYSELF, 0);
+ device_end(env);
+ MYSELF = 0;
+ }
+}
+
+/*
+ * find-builtin-driver ( str len -- xt true | false )
+ */
+void
+find_builtin_driver(fcode_env_t *env)
+{
+ fstack_t d;
+
+ CHECK_DEPTH(env, 2, "find-builtin-driver");
+ push_a_string(env, "SUNW,builtin-drivers");
+ find_package(env);
+ d = POP(DS);
+ if (d) {
+ find_method(env);
+ } else {
+ two_drop(env);
+ PUSH(DS, FALSE);
+ }
+}
+
+void
+exec_builtin_driver(fcode_env_t *env)
+{
+ fstack_t d;
+ char *method, *path, *buf;
+ fc_cell_t len, result;
+ int error;
+ static char func_name[] = "exec-builtin-driver";
+ extern int check_fcode_header(char *, uchar_t *, int);
+
+ CHECK_DEPTH(env, 2, func_name);
+ method = pop_a_string(env, NULL);
+
+ /*
+ * Check for file in filesystem. If it exists, we'll just try to do
+ * a do-dropin-file.
+ */
+ if ((path = search_for_fcode_file(env, method)) != NULL) {
+ push_a_string(env, path);
+ load_file(env);
+ return;
+ }
+
+ error = fc_run_priv(env->private, "sunos,get-fcode-size", 1, 1,
+ fc_ptr2cell(method), &len);
+ if (error || len == 0) {
+ if (len == 0)
+ debug_msg(DEBUG_FIND_FCODE, "%s: '%s' NOT FOUND\n",
+ func_name, method);
+ PUSH(DS, 0);
+ return;
+ }
+ debug_msg(DEBUG_FIND_FCODE, "%s: '%s' FOUND len: %x\n",
+ func_name, method, (int)len);
+ buf = MALLOC(len);
+ error = fc_run_priv(env->private, "sunos,get-fcode", 3, 1,
+ fc_ptr2cell(method), fc_ptr2cell(buf), len, &result);
+ if (error) {
+ FREE(buf);
+ PUSH(DS, 0);
+ return;
+ }
+
+ if (check_fcode_header(dropin_name, (uchar_t *)buf, len) == 0)
+ log_message(MSG_WARN, "%s: '%s' fcode header NOT OK\n",
+ func_name, method);
+
+ debug_msg(DEBUG_FIND_FCODE, "%s: '%s' dropin Fcode: 0x%p/0x%x\n",
+ func_name, method, buf, (int)len);
+ PUSH(DS, (fstack_t)buf);
+ PUSH(DS, len);
+}
+
+#pragma init(_init)
+
+static void
+_init(void)
+{
+ extern void set_find_method_hook(fcode_env_t *,
+ void (*)(fcode_env_t *));
+ fcode_env_t *env = initial_env;
+ fstack_t d;
+
+ ASSERT(env);
+ NOTICE;
+
+ set_find_method_hook(env, builtin_driver_method_hook);
+
+ FORTH(0, "install-package-nodes", install_package_nodes);
+ FORTH(0, "find-builtin-driver", find_builtin_driver);
+ FORTH(0, "exec-builtin-driver", exec_builtin_driver);
+ FORTH(0, "builtin-driver-method-hook",
+ builtin_driver_method_hook);
+ FORTH(0, "do-builtin-dropin", do_builtin_dropin);
+ FORTH(0, "do-builtin-file", do_builtin_file);
+}