1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  Program Loader commands			File: ui_loadcmds.c
5    *
6    *  User interface for program loader
7    *
8    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47
48#include "lib_types.h"
49#include "lib_string.h"
50#include "lib_queue.h"
51#include "lib_malloc.h"
52#include "lib_printf.h"
53
54#include "cfe_iocb.h"
55#include "cfe_device.h"
56#include "cfe_console.h"
57#include "cfe_devfuncs.h"
58
59#include "ui_command.h"
60#include "cfe.h"
61
62#include "net_ebuf.h"
63#include "net_ether.h"
64#include "net_api.h"
65
66#include "cfe_fileops.h"
67#include "cfe_boot.h"
68
69#include "bsp_config.h"
70#include "cfe_loader.h"
71#include "cfe_autoboot.h"
72
73#include "url.h"
74
75
76int ui_init_loadcmds(void);
77static int ui_cmd_load(ui_cmdline_t *cmd,int argc,char *argv[]);
78
79#if CFG_NETWORK
80static int ui_cmd_save(ui_cmdline_t *cmd,int argc,char *argv[]);
81#endif
82
83#if CFG_AUTOBOOT
84static int ui_cmd_autoboot(ui_cmdline_t *cmd,int argc,char *argv[]);
85#endif	/* CFG_AUTOBOOT */
86static int ui_cmd_boot(ui_cmdline_t *cmd,int argc,char *argv[]);
87static int ui_cmd_batch(ui_cmdline_t *cmd,int argc,char *argv[]);
88static int ui_cmd_go(ui_cmdline_t *cmd,int argc,char *argv[]);
89
90
91extern cfe_loadargs_t cfe_loadargs;
92
93static long getaddr(char *str)
94{
95    /*
96     * hold on to your lunch, this is really, really bad!
97     * Make 64-bit addresses expressed as 8-digit numbers
98     * sign extend automagically.  Saves typing, but is very
99     * gross.  Not very portable, either.
100     */
101    int longaddr = 0;
102    long newaddr;
103
104    longaddr = strlen(str);
105    if (memcmp(str,"0x",2) == 0) longaddr -= 2;
106    longaddr = (longaddr > 8) ? 1 : 0;
107
108    if (longaddr) newaddr = (long) xtoq(str);
109    else newaddr = (long) xtoi(str);
110
111    return newaddr;
112}
113
114
115
116int ui_init_loadcmds(void)
117{
118
119#if CFG_NETWORK
120    cmd_addcmd("save",
121	       ui_cmd_save,
122	       NULL,
123	       "Save a region of memory to a remote file via TFTP",
124	       "save [-options] host:filename startaddr length\n\n",
125	       "");
126#endif
127
128    cmd_addcmd("load",
129	       ui_cmd_load,
130	       NULL,
131	       "Load an executable file into memory without executing it",
132	       "load [-options] host:filename|dev:filename\n\n"
133	       "This command loads an executable file into memory, but does not\n"
134	       "execute it.  It can be used for loading data files, overlays or\n"
135	       "other programs needed before the 'boot' command is used.  By\n"
136	       "default, 'load' will load a raw binary at virtual address 0x20000000.",
137	       "-elf;Load the file as an ELF executable|"
138	       "-srec;Load the file as ASCII S-records|"
139	       "-raw;Load the file as a raw binary|"
140#if CFG_ZLIB || CFG_LZMA
141	       "-z;Load compessed file|"
142#endif
143	       "-loader=*;Specify CFE loader name|"
144	       "-tftp;Load the file using the TFTP protocol|"
145	       "-fatfs;Load the file from a FAT file system|"
146	       "-rawfs;Load the file from an unformatted file system|"
147#if CFG_TCP && CFG_HTTPFS
148	       "-http;Load the file using the HTTP protocol|"
149#endif
150               "-fs=*;Specify CFE file system name|"
151	       "-max=*;Specify the maximum number of bytes to load (raw only)|"
152	       "-addr=*;Specify the load address (hex) (raw only)");
153
154    cmd_addcmd("boot",
155	       ui_cmd_boot,
156	       NULL,
157	       "Load an executable file into memory and execute it",
158	       "boot [-options] host:filename|dev:filename\n\n"
159	       "This command loads and executes a program from a boot device\n"
160	       "By default, 'boot' will load a raw binary at virtual \n"
161	       "address 0x20000000 and then jump to that address",
162	       "-elf;Load the file as an ELF executable|"
163	       "-srec;Load the file as ASCII S-records|"
164	       "-raw;Load the file as a raw binary|"
165#if CFG_ZLIB || CFG_LZMA
166	       "-z;Load compessed file|"
167#endif
168	       "-loader=*;Specify CFE loader name|"
169	       "-tftp;Load the file using the TFTP protocol|"
170	       "-fatfs;Load the file from a FAT file system|"
171	       "-rawfs;Load the file from an unformatted file system|"
172#if CFG_TCP && CFG_HTTPFS
173	       "-http;Load the file using the HTTP protocol|"
174#endif
175               "-fs=*;Specify CFE file system name|"
176	       "-max=*;Specify the maximum number of bytes to load (raw only)|"
177	       "-addr=*;Specify the load address (hex) (raw only)|"
178	       "-noclose;Don't close network link before executing program");
179
180    cmd_addcmd("go",
181	       ui_cmd_go,
182	       NULL,
183	       "Start a previously loaded program.",
184	       "go [address]\n\n"
185	       "The 'go' command will start a program previously loaded with \n"
186	       "the 'load' command.  You can override the start address by"
187	       "specifying it as a parameter to the 'go' command.",
188	       "-noclose;Don't close network link before executing program");
189
190    cmd_addcmd("batch",
191	       ui_cmd_batch,
192	       NULL,
193	       "Load a batch file into memory and execute it",
194	       "batch [-options] host:filename|dev:filename\n\n"
195	       "This command loads and executes a batch file from a boot device",
196#if CFG_ZLIB || CFG_LZMA
197	       "-z;Load compessed file|"
198#endif
199#if CFG_ROMBOOT
200	       "-raw;Load the file as a raw binary|"
201	       "-max=*;Specify the maximum number of bytes to load (raw only)|"
202	       "-addr=*;Specify the load address (hex) (raw only)|"
203#endif
204	       "-tftp;Load the file using the TFTP protocol|"
205	       "-fatfs;Load the file from a FAT file system|"
206	       "-rawfs;Load the file from an unformatted file system|"
207               "-fs=*;Specify CFE file system name");
208
209#if CFG_AUTOBOOT
210    cmd_addcmd("autoboot",
211	       ui_cmd_autoboot,
212	       NULL,
213	       "Automatic system bootstrap.",
214	       "autoboot [dev]\n\n"
215	       "The 'autoboot' command causes an automatic system bootstrap from\n"
216	       "a predefined list of devices and boot files.  This list is \n"
217	       "specific to the board and port of CFE.  To try autobooting from\n"
218	       "a specific device, you can specify the CFE device name on the command line.",
219	       "-forever;Loop over devices until boot is successful|"
220	       "-interruptible;Scan console between devices, drop to prompt if key pressed");
221#endif	/* CFG_AUTOBOOT */
222
223    return 0;
224}
225
226
227#if CFG_AUTOBOOT
228static int ui_cmd_autoboot(ui_cmdline_t *cmd,int argc,char *argv[])
229{
230    int res;
231    char *x;
232    int flags = 0;
233
234    if (cmd_sw_isset(cmd,"-forever")) flags |= CFE_AUTOFLG_TRYFOREVER;
235    if (cmd_sw_isset(cmd,"-interruptible")) flags |= CFE_AUTOFLG_POLLCONSOLE;
236
237    x = cmd_getarg(cmd,0);
238    res = cfe_autoboot(x,flags);
239
240    return res;
241}
242#endif	/* CFG_AUTOBOOT */
243
244static int ui_cmd_go(ui_cmdline_t *cmd,int argc,char *argv[])
245{
246    char *arg;
247
248    arg = cmd_getarg(cmd,0);
249    if (arg) {
250	cfe_loadargs.la_entrypt = getaddr(arg);
251	}
252
253    if (cmd_sw_isset(cmd,"-noclose")) {
254	cfe_loadargs.la_flags |= LOADFLG_NOCLOSE;
255	}
256
257    cfe_go(&cfe_loadargs);
258
259    return 0;
260}
261
262
263
264static int ui_cmd_bootcommon(ui_cmdline_t *cmd,int argc,char *argv[],int flags)
265{
266    int res;
267    char *arg;
268    cfe_loadargs_t *la = &cfe_loadargs;
269    char copy[200];
270
271    la->la_flags = flags;
272
273    arg = cmd_getarg(cmd,0);
274    strncpy(copy,arg,sizeof(copy));
275
276    if (!arg) {
277	xprintf("No program name specified\n");
278	return -1;
279	}
280
281    res = ui_process_url(arg,cmd,la);
282    if (res < 0) return res;
283
284    /*
285     * Pick up the remaining command line parameters for use as
286     * arguments to the loaded program.
287     */
288
289    la->la_options = cmd_getarg(cmd,1);
290
291    /*
292     * Note: we might not come back here if we really launch the program.
293     */
294
295    xprintf("Loader:%s Filesys:%s Dev:%s File:%s Options:%s\n",
296	    la->la_loader,la->la_filesys,la->la_device,la->la_filename,la->la_options);
297
298    res = cfe_boot(la->la_loader,la);
299
300    /*
301     * Give the bad news.
302     */
303
304    if (res < 0) xprintf("Could not load %s: %s\n",copy,cfe_errortext(res));
305
306    return res;
307}
308
309
310static int ui_cmd_load(ui_cmdline_t *cmd,int argc,char *argv[])
311{
312    int flags = LOADFLG_NOISY;
313
314    return ui_cmd_bootcommon(cmd,argc,argv,flags);
315}
316
317
318
319
320static int ui_cmd_boot(ui_cmdline_t *cmd,int argc,char *argv[])
321{
322    int flags = LOADFLG_NOISY | LOADFLG_EXECUTE;
323
324    return ui_cmd_bootcommon(cmd,argc,argv,flags);
325}
326
327static int ui_cmd_batch(ui_cmdline_t *cmd,int argc,char *argv[])
328{
329    int flags = LOADFLG_NOISY | LOADFLG_EXECUTE | LOADFLG_BATCH;
330
331    return ui_cmd_bootcommon(cmd,argc,argv,flags);
332}
333
334#if CFG_NETWORK
335static int ui_cmd_save(ui_cmdline_t *cmd,int argc,char *argv[])
336{
337    char *x;
338    uint8_t *start,*end;
339    int len;
340    char *fname;
341    int res;
342
343    fname = cmd_getarg(cmd,0);
344
345    if ((x = cmd_getarg(cmd,1))) {
346	start = (uint8_t *) getaddr(x);
347	}
348    else {
349	return ui_showusage(cmd);
350	}
351
352    if ((x = cmd_getarg(cmd,2))) {
353	len = xtoi(x);
354	}
355    else {
356	return ui_showusage(cmd);
357	}
358
359    end = start+len;
360
361    res = cfe_savedata("tftp","",fname,start,end);
362
363    if (res < 0) {
364	return ui_showerror(res,"Could not dump data to network");
365	}
366    else {
367	xprintf("%d bytes written to %s\n",res,fname);
368	}
369
370    return 0;
371}
372#endif
373