Added new ext fields to IFC
[oweals/u-boot.git] / common / cmd_source.c
1 /*
2  * (C) Copyright 2001
3  * Kyle Harris, kharris@nexus-tech.net
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * The "source" command allows to define "script images", i. e. files
26  * that contain command sequences that can be executed by the command
27  * interpreter. It returns the exit status of the last command
28  * executed from the script. This is very similar to running a shell
29  * script in a UNIX shell, hence the name for the command.
30  */
31
32 /* #define DEBUG */
33
34 #include <common.h>
35 #include <command.h>
36 #include <image.h>
37 #include <malloc.h>
38 #include <asm/byteorder.h>
39 #if defined(CONFIG_8xx)
40 #include <mpc8xx.h>
41 #endif
42
43 int
44 source (ulong addr, const char *fit_uname)
45 {
46         ulong           len;
47         image_header_t  *hdr;
48         ulong           *data;
49         int             verify;
50 #if defined(CONFIG_FIT)
51         const void*     fit_hdr;
52         int             noffset;
53         const void      *fit_data;
54         size_t          fit_len;
55 #endif
56
57         verify = getenv_yesno ("verify");
58
59         switch (genimg_get_format ((void *)addr)) {
60         case IMAGE_FORMAT_LEGACY:
61                 hdr = (image_header_t *)addr;
62
63                 if (!image_check_magic (hdr)) {
64                         puts ("Bad magic number\n");
65                         return 1;
66                 }
67
68                 if (!image_check_hcrc (hdr)) {
69                         puts ("Bad header crc\n");
70                         return 1;
71                 }
72
73                 if (verify) {
74                         if (!image_check_dcrc (hdr)) {
75                                 puts ("Bad data crc\n");
76                                 return 1;
77                         }
78                 }
79
80                 if (!image_check_type (hdr, IH_TYPE_SCRIPT)) {
81                         puts ("Bad image type\n");
82                         return 1;
83                 }
84
85                 /* get length of script */
86                 data = (ulong *)image_get_data (hdr);
87
88                 if ((len = uimage_to_cpu (*data)) == 0) {
89                         puts ("Empty Script\n");
90                         return 1;
91                 }
92
93                 /*
94                  * scripts are just multi-image files with one component, seek
95                  * past the zero-terminated sequence of image lengths to get
96                  * to the actual image data
97                  */
98                 while (*data++);
99                 break;
100 #if defined(CONFIG_FIT)
101         case IMAGE_FORMAT_FIT:
102                 if (fit_uname == NULL) {
103                         puts ("No FIT subimage unit name\n");
104                         return 1;
105                 }
106
107                 fit_hdr = (const void *)addr;
108                 if (!fit_check_format (fit_hdr)) {
109                         puts ("Bad FIT image format\n");
110                         return 1;
111                 }
112
113                 /* get script component image node offset */
114                 noffset = fit_image_get_node (fit_hdr, fit_uname);
115                 if (noffset < 0) {
116                         printf ("Can't find '%s' FIT subimage\n", fit_uname);
117                         return 1;
118                 }
119
120                 if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) {
121                         puts ("Not a image image\n");
122                         return 1;
123                 }
124
125                 /* verify integrity */
126                 if (verify) {
127                         if (!fit_image_check_hashes (fit_hdr, noffset)) {
128                                 puts ("Bad Data Hash\n");
129                                 return 1;
130                         }
131                 }
132
133                 /* get script subimage data address and length */
134                 if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
135                         puts ("Could not find script subimage data\n");
136                         return 1;
137                 }
138
139                 data = (ulong *)fit_data;
140                 len = (ulong)fit_len;
141                 break;
142 #endif
143         default:
144                 puts ("Wrong image format for \"source\" command\n");
145                 return 1;
146         }
147
148         debug ("** Script length: %ld\n", len);
149         return run_command_list((char *)data, len, 0);
150 }
151
152 /**************************************************/
153 #if defined(CONFIG_CMD_SOURCE)
154 int
155 do_source (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
156 {
157         ulong addr;
158         int rcode;
159         const char *fit_uname = NULL;
160
161         /* Find script image */
162         if (argc < 2) {
163                 addr = CONFIG_SYS_LOAD_ADDR;
164                 debug ("*  source: default load address = 0x%08lx\n", addr);
165 #if defined(CONFIG_FIT)
166         } else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) {
167                 debug ("*  source: subimage '%s' from FIT image at 0x%08lx\n",
168                                 fit_uname, addr);
169 #endif
170         } else {
171                 addr = simple_strtoul(argv[1], NULL, 16);
172                 debug ("*  source: cmdline image address = 0x%08lx\n", addr);
173         }
174
175         printf ("## Executing script at %08lx\n", addr);
176         rcode = source (addr, fit_uname);
177         return rcode;
178 }
179
180 U_BOOT_CMD(
181         source, 2, 0,   do_source,
182         "run script from memory",
183         "[addr]\n"
184         "\t- run script starting at addr\n"
185         "\t- A valid image header must be present"
186 #if defined(CONFIG_FIT)
187         "\n"
188         "For FIT format uImage addr must include subimage\n"
189         "unit name in the form of addr:<subimg_uname>"
190 #endif
191 );
192 #endif