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
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.
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]
23 * Copyright (c) 2000 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
38 #include <sys/systeminfo.h>
39 #include <sys/utsname.h>
41 #include <fcode/private.h>
42 #include <fcode/log.h>
44 #include <fcdriver/fcdriver.h>
46 static char *default_search_path
;
47 static char search_proto
[] =
48 "/usr/platform/%s/lib/efcode%s:"
49 "/usr/platform/%s/lib/efcode%s:"
53 * Build the library/drop-in fcode search path. If there's no architecture
54 * passed, we build the search path (per the PSARC decision):
55 * /usr/platform/`uname -i`/lib/efcode
56 * /usr/platform/`uname -m`/lib/efcode
58 * If there is an architecture passed, we prepend the following search path to
60 * /usr/platform/`uname -i`/lib/efcode/{architecture}
61 * /usr/platform/`uname -m`/lib/efcode/{architecture}
62 * /usr/lib/efcode/{architecture}
63 * This allows FCode drop-in searches to find FCode in the non-architecture
67 build_default_search_path(char *arch
)
69 char platform
[100], *p
;
71 struct utsname utsname
;
74 sysinfo(SI_PLATFORM
, platform
, sizeof (platform
));
76 len
= strlen(search_proto
) + strlen(platform
) + strlen(utsname
.machine
);
78 len
+= len
+ (3 * strlen(arch
)) + 1;
80 default_search_path
= MALLOC(len
);
82 sprintf(default_search_path
, search_proto
, platform
, arch
,
83 utsname
.machine
, arch
, arch
);
84 p
= default_search_path
+ strlen(default_search_path
);
87 p
= default_search_path
;
89 sprintf(p
, search_proto
, platform
, "", utsname
.machine
, "", "");
93 set_default_search_path(fcode_env_t
*env
)
95 if (default_search_path
)
96 FREE(default_search_path
);
99 default_search_path
= pop_a_duped_string(env
, NULL
);
103 get_default_search_path(fcode_env_t
*env
)
105 push_a_string(env
, default_search_path
);
109 * Complicated by fact that a library (e.g. a 32-bit library) can match the
110 * file name. But if we're running as 64-bit, dlopen on that library will
114 search_path(char *name
, char *search
, int (*fn
)(char *))
119 fpath
= STRDUP(search
);
120 for (p
= fpath
; p
!= NULL
; p
= next_p
) {
121 if ((next_p
= strchr(p
, ':')) != NULL
)
123 tpath
= MALLOC(strlen(p
) + strlen(name
) + 2);
124 sprintf(tpath
, "%s/%s", p
, name
);
136 load_lib_file(char *path
)
140 debug_msg(DEBUG_FIND_FCODE
, "load_lib_file: '%s' -> ", path
);
141 if (stat(path
, &buf
)) {
142 debug_msg(DEBUG_FIND_FCODE
, "stat failed\n");
145 if (dlopen(path
, RTLD_NOW
) != NULL
) {
146 debug_msg(DEBUG_FIND_FCODE
, "OK\n");
149 debug_msg(DEBUG_FIND_FCODE
, "dlopen failed\n");
154 is_fcode_file(char *path
)
160 static char func_name
[] = "is_fcode_file";
161 extern int check_fcode_header(char *, uchar_t
*, int);
163 debug_msg(DEBUG_FIND_FCODE
, "%s: '%s' -> ", func_name
, path
);
164 if ((fd
= open(path
, O_RDONLY
)) < 0) {
165 debug_msg(DEBUG_FIND_FCODE
, "%s: '%s' can't open\n", func_name
,
169 if (fstat(fd
, &statb
) != 0 || read(fd
, header
, sizeof (header
)) < 0) {
170 debug_msg(DEBUG_FIND_FCODE
, "%s: '%s' can't fstat/read\n",
175 status
= check_fcode_header(path
, header
, statb
.st_size
);
176 debug_msg(DEBUG_FIND_FCODE
, "%s: '%s' format %s\n", func_name
, path
,
177 status
? "OK" : "NOT OK");
183 find_lib_file(fcode_env_t
*env
, char *prefix
, char *name
, char *suffix
,
186 char *search
, *fname
;
188 common_data_t
*cdp
= env
->private;
190 if ((search
= cdp
->search_path
) == NULL
&&
191 (search
= default_search_path
) == NULL
) {
192 log_message(MSG_ERROR
, "find_lib_file: no search path\n");
196 lib_name
= MALLOC(strlen(name
) + strlen(prefix
) + strlen(suffix
) + 1);
197 sprintf(lib_name
, "%s%s%s", prefix
, name
, suffix
);
198 fname
= search_path(lib_name
, search
, fn
);
204 search_for_fcode_file(fcode_env_t
*env
, char *basename
)
206 return (find_lib_file(env
, "", basename
, ".fc", is_fcode_file
));
210 load_appropriate_file(fcode_env_t
*env
, char *name
, device_t
*d
)
214 if ((fname
= find_lib_file(env
, "lfc_", name
, ".so", load_lib_file
))
216 debug_msg(DEBUG_FIND_FCODE
, "Loading Library: %s\n", fname
);
218 } else if ((fname
= search_for_fcode_file(env
, name
)) != NULL
) {
219 debug_msg(DEBUG_FIND_FCODE
, "Loading Fcode: %s\n", fname
);
220 run_fcode_from_file(env
, fname
, 0);
223 throw_from_fclib(env
, 1,
224 "Can't find 'lfc_%s.so' or '%s.fc'\n", name
, name
);
229 install_node_data(fcode_env_t
*env
, device_t
*d
)
234 static char func_name
[] = "install_node_data";
237 if ((p
= lookup_package_property(env
, "device_type",
238 d
->parent
)) == NULL
) {
239 log_message(MSG_ERROR
, "%s: no 'device_type' property"
240 " for '%s'\n", func_name
, get_path(env
, d
->parent
));
244 * Warning: lookup_package_property uses a static data area to
245 * build the property node returned, so we have to grab a copy
248 strcpy(libname
, (char *)p
->data
);
249 strcat(libname
, "_");
253 if ((p
= lookup_package_property(env
, "device_type", d
)) == NULL
) {
254 log_message(MSG_ERROR
, "%s: no 'device_type' property for"
255 " '%s'\n", func_name
, get_path(env
, d
));
260 * Warning: lookup_package_property uses a static data area to build
261 * the property node returned, so we have to grab a copy of the
264 strcat(libname
, (char *)p
->data
);
266 debug_msg(DEBUG_FIND_FCODE
, "%s: `%s` lname: '%s'\n", func_name
,
267 get_path(env
, d
), libname
);
269 load_appropriate_file(env
, libname
, d
);
277 fcode_env_t
*env
= initial_env
;
282 build_default_search_path("");
283 FORTH(0, "set-default-search-path", set_default_search_path
);
284 FORTH(0, "get-default-search-path", get_default_search_path
);