Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / ia64 / stand / common / fileload.c
blobddd2de8878b02b500b716de94ef227c5656fbf75
1 /* $NetBSD: fileload.c,v 1.1 2006/04/07 14:21:29 cherry Exp $ */
3 /*-
4 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
29 #include <sys/cdefs.h>
32 * file/module function dispatcher, support, etc.
35 #include <lib/libsa/stand.h>
36 #include <sys/param.h>
37 #include <sys/lkm.h>
38 #include <sys/queue.h>
40 #include "bootstrap.h"
42 static int file_load(char *filename, vaddr_t dest, struct preloaded_file **result);
43 static int file_havepath(const char *name);
44 static void file_insert_tail(struct preloaded_file *mp);
46 /* load address should be tweaked by first module loaded (kernel) */
47 static vaddr_t loadaddr = 0;
49 struct preloaded_file *preloaded_files = NULL;
52 * load a kernel from disk.
54 * kernels are loaded as:
56 * load <path> <options>
59 int
60 command_load(int argc, char *argv[])
62 char *typestr;
63 int dofile, dokld, ch, error;
65 dokld = dofile = 0;
66 optind = 1;
67 optreset = 1;
68 typestr = NULL;
69 if (argc == 1) {
70 command_errmsg = "no filename specified";
71 return(CMD_ERROR);
73 while ((ch = getopt(argc, argv, "k:")) != -1) {
74 switch(ch) {
75 case 'k':
76 dokld = 1;
77 break;
78 case '?':
79 default:
80 /* getopt has already reported an error */
81 return(CMD_OK);
84 argv += (optind - 1);
85 argc -= (optind - 1);
88 * Do we have explicit KLD load ?
90 if (dokld || file_havepath(argv[1])) {
91 error = file_loadkernel(argv[1], argc - 2, argv + 2);
92 if (error == EEXIST)
93 sprintf(command_errbuf, "warning: KLD '%s' already loaded", argv[1]);
95 return (error == 0 ? CMD_OK : CMD_ERROR);
99 int
100 command_unload(int argc, char *argv[])
102 struct preloaded_file *fp;
104 while (preloaded_files != NULL) {
105 fp = preloaded_files;
106 preloaded_files = preloaded_files->f_next;
107 file_discard(fp);
109 loadaddr = 0;
110 unsetenv("kernelname");
111 return(CMD_OK);
116 command_lskern(int argc, char *argv[])
118 struct preloaded_file *fp;
119 char lbuf[80];
120 int ch, verbose;
122 verbose = 0;
123 optind = 1;
124 optreset = 1;
126 pager_open();
127 for (fp = preloaded_files; fp; fp = fp->f_next) {
128 sprintf(lbuf, " %p: %s (%s, 0x%lx)\n",
129 (void *) fp->f_addr, fp->f_name, fp->f_type, (long) fp->f_size);
130 pager_output(lbuf);
131 if (fp->f_args != NULL) {
132 pager_output(" args: ");
133 pager_output(fp->f_args);
134 pager_output("\n");
137 pager_close();
138 return(CMD_OK);
142 * File level interface, functions file_*
145 file_load(char *filename, vaddr_t dest, struct preloaded_file **result)
147 struct preloaded_file *fp;
148 int error;
149 int i;
151 error = EFTYPE;
152 for (i = 0, fp = NULL; file_formats[i] && fp == NULL; i++) {
153 error = (file_formats[i]->l_load)(filename, dest, &fp);
154 if (error == 0) {
155 fp->f_loader = i; /* remember the loader */
156 *result = fp;
157 break;
159 if (error == EFTYPE)
160 continue; /* Unknown to this handler? */
161 if (error) {
162 sprintf(command_errbuf, "can't load file '%s': %s",
163 filename, strerror(error));
164 break;
167 return (error);
171 * Load specified KLD. If path is omitted, then try to locate it via
172 * search path.
175 file_loadkernel(char *filename, int argc, char *argv[])
177 struct preloaded_file *fp, *last_file;
178 int err;
181 * Check if KLD already loaded
183 fp = file_findfile(filename, NULL);
184 if (fp) {
185 sprintf(command_errbuf, "warning: KLD '%s' already loaded", filename);
186 free(filename);
187 return (0);
189 for (last_file = preloaded_files;
190 last_file != NULL && last_file->f_next != NULL;
191 last_file = last_file->f_next)
194 do {
195 err = file_load(filename, loadaddr, &fp);
196 if (err)
197 break;
198 fp->f_args = unargv(argc, argv);
199 loadaddr = fp->f_addr + fp->f_size;
200 file_insert_tail(fp); /* Add to the list of loaded files */
201 } while(0);
202 if (err == EFTYPE)
203 sprintf(command_errbuf, "don't know how to load module '%s'", filename);
204 if (err && fp)
205 file_discard(fp);
206 free(filename);
207 return (err);
211 * Find a file matching (name) and (type).
212 * NULL may be passed as a wildcard to either.
214 struct preloaded_file *
215 file_findfile(char *name, char *type)
217 struct preloaded_file *fp;
219 for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
220 if (((name == NULL) || !strcmp(name, fp->f_name)) &&
221 ((type == NULL) || !strcmp(type, fp->f_type)))
222 break;
224 return (fp);
228 * Check if file name have any qualifiers
230 static int
231 file_havepath(const char *name)
233 const char *cp;
235 archsw.arch_getdev(NULL, name, &cp);
236 return (cp != name || strchr(name, '/') != NULL);
240 * Throw a file away
242 void
243 file_discard(struct preloaded_file *fp)
245 if (fp == NULL)
246 return;
247 if (fp->f_name != NULL)
248 free(fp->f_name);
249 if (fp->f_type != NULL)
250 free(fp->f_type);
251 if (fp->f_args != NULL)
252 free(fp->f_args);
253 if (fp->marks != NULL)
254 free(fp->marks);
255 free(fp);
259 * Allocate a new file; must be used instead of malloc()
260 * to ensure safe initialisation.
262 struct preloaded_file *
263 file_alloc(void)
265 struct preloaded_file *fp;
267 if ((fp = alloc(sizeof(struct preloaded_file))) != NULL) {
268 memset(fp, 0, sizeof(struct preloaded_file));
270 if (fp->marks = alloc(sizeof(u_long))) {
271 memset(fp->marks, 0, sizeof(u_long));
274 return (fp);
278 * Add a module to the chain
280 static void
281 file_insert_tail(struct preloaded_file *fp)
283 struct preloaded_file *cm;
285 /* Append to list of loaded file */
286 fp->f_next = NULL;
287 if (preloaded_files == NULL) {
288 preloaded_files = fp;
289 } else {
290 for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
292 cm->f_next = fp;