Commit 9c3483113de1204118a1b252bf4c81b899dd12b4

Authored by Heiko Schocher
Committed by Albert ARIBAUD
1 parent 2627c8c0a1

common: add possibility for readline_into_buffer timeout

add possibility to add a timeout when reading a line
into a buffer.

Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Mike Frysinger <vapier@gentoo.org>
Acked-by: Mike Frysinger <vapier@gentoo.org>

Showing 4 changed files with 21 additions and 7 deletions Inline Diff

1 /* 1 /*
2 * (C) Copyright 2000-2010 2 * (C) Copyright 2000-2010
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 * 4 *
5 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> 5 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
6 * Andreas Heppel <aheppel@sysgo.de> 6 * Andreas Heppel <aheppel@sysgo.de>
7 * 7 *
8 * Copyright 2011 Freescale Semiconductor, Inc. 8 * Copyright 2011 Freescale Semiconductor, Inc.
9 * 9 *
10 * See file CREDITS for list of people who contributed to this 10 * See file CREDITS for list of people who contributed to this
11 * project. 11 * project.
12 * 12 *
13 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as 14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of 15 * published by the Free Software Foundation; either version 2 of
16 * the License, or (at your option) any later version. 16 * the License, or (at your option) any later version.
17 * 17 *
18 * This program is distributed in the hope that it will be useful, 18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details. 21 * GNU General Public License for more details.
22 * 22 *
23 * You should have received a copy of the GNU General Public License 23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software 24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 * MA 02111-1307 USA 26 * MA 02111-1307 USA
27 */ 27 */
28 28
29 /* 29 /*
30 * Support for persistent environment data 30 * Support for persistent environment data
31 * 31 *
32 * The "environment" is stored on external storage as a list of '\0' 32 * The "environment" is stored on external storage as a list of '\0'
33 * terminated "name=value" strings. The end of the list is marked by 33 * terminated "name=value" strings. The end of the list is marked by
34 * a double '\0'. The environment is preceeded by a 32 bit CRC over 34 * a double '\0'. The environment is preceeded by a 32 bit CRC over
35 * the data part and, in case of redundant environment, a byte of 35 * the data part and, in case of redundant environment, a byte of
36 * flags. 36 * flags.
37 * 37 *
38 * This linearized representation will also be used before 38 * This linearized representation will also be used before
39 * relocation, i. e. as long as we don't have a full C runtime 39 * relocation, i. e. as long as we don't have a full C runtime
40 * environment. After that, we use a hash table. 40 * environment. After that, we use a hash table.
41 */ 41 */
42 42
43 #include <common.h> 43 #include <common.h>
44 #include <command.h> 44 #include <command.h>
45 #include <environment.h> 45 #include <environment.h>
46 #include <search.h> 46 #include <search.h>
47 #include <errno.h> 47 #include <errno.h>
48 #include <malloc.h> 48 #include <malloc.h>
49 #include <watchdog.h> 49 #include <watchdog.h>
50 #include <serial.h> 50 #include <serial.h>
51 #include <linux/stddef.h> 51 #include <linux/stddef.h>
52 #include <asm/byteorder.h> 52 #include <asm/byteorder.h>
53 #if defined(CONFIG_CMD_NET) 53 #if defined(CONFIG_CMD_NET)
54 #include <net.h> 54 #include <net.h>
55 #endif 55 #endif
56 56
57 DECLARE_GLOBAL_DATA_PTR; 57 DECLARE_GLOBAL_DATA_PTR;
58 58
59 #if !defined(CONFIG_ENV_IS_IN_EEPROM) && \ 59 #if !defined(CONFIG_ENV_IS_IN_EEPROM) && \
60 !defined(CONFIG_ENV_IS_IN_FLASH) && \ 60 !defined(CONFIG_ENV_IS_IN_FLASH) && \
61 !defined(CONFIG_ENV_IS_IN_DATAFLASH) && \ 61 !defined(CONFIG_ENV_IS_IN_DATAFLASH) && \
62 !defined(CONFIG_ENV_IS_IN_MG_DISK) && \ 62 !defined(CONFIG_ENV_IS_IN_MG_DISK) && \
63 !defined(CONFIG_ENV_IS_IN_MMC) && \ 63 !defined(CONFIG_ENV_IS_IN_MMC) && \
64 !defined(CONFIG_ENV_IS_IN_NAND) && \ 64 !defined(CONFIG_ENV_IS_IN_NAND) && \
65 !defined(CONFIG_ENV_IS_IN_NVRAM) && \ 65 !defined(CONFIG_ENV_IS_IN_NVRAM) && \
66 !defined(CONFIG_ENV_IS_IN_ONENAND) && \ 66 !defined(CONFIG_ENV_IS_IN_ONENAND) && \
67 !defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \ 67 !defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \
68 !defined(CONFIG_ENV_IS_NOWHERE) 68 !defined(CONFIG_ENV_IS_NOWHERE)
69 # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\ 69 # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
70 SPI_FLASH|MG_DISK|NVRAM|MMC} or CONFIG_ENV_IS_NOWHERE 70 SPI_FLASH|MG_DISK|NVRAM|MMC} or CONFIG_ENV_IS_NOWHERE
71 #endif 71 #endif
72 72
73 #define XMK_STR(x) #x 73 #define XMK_STR(x) #x
74 #define MK_STR(x) XMK_STR(x) 74 #define MK_STR(x) XMK_STR(x)
75 75
76 /* 76 /*
77 * Maximum expected input data size for import command 77 * Maximum expected input data size for import command
78 */ 78 */
79 #define MAX_ENV_SIZE (1 << 20) /* 1 MiB */ 79 #define MAX_ENV_SIZE (1 << 20) /* 1 MiB */
80 80
81 ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ 81 ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */
82 ulong save_addr; /* Default Save Address */ 82 ulong save_addr; /* Default Save Address */
83 ulong save_size; /* Default Save Size (in bytes) */ 83 ulong save_size; /* Default Save Size (in bytes) */
84 84
85 /* 85 /*
86 * Table with supported baudrates (defined in config_xyz.h) 86 * Table with supported baudrates (defined in config_xyz.h)
87 */ 87 */
88 static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; 88 static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
89 #define N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0])) 89 #define N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0]))
90 90
91 /* 91 /*
92 * This variable is incremented on each do_env_set(), so it can 92 * This variable is incremented on each do_env_set(), so it can
93 * be used via get_env_id() as an indication, if the environment 93 * be used via get_env_id() as an indication, if the environment
94 * has changed or not. So it is possible to reread an environment 94 * has changed or not. So it is possible to reread an environment
95 * variable only if the environment was changed ... done so for 95 * variable only if the environment was changed ... done so for
96 * example in NetInitLoop() 96 * example in NetInitLoop()
97 */ 97 */
98 static int env_id = 1; 98 static int env_id = 1;
99 99
100 int get_env_id(void) 100 int get_env_id(void)
101 { 101 {
102 return env_id; 102 return env_id;
103 } 103 }
104 104
105 /* 105 /*
106 * Command interface: print one or all environment variables 106 * Command interface: print one or all environment variables
107 * 107 *
108 * Returns 0 in case of error, or length of printed string 108 * Returns 0 in case of error, or length of printed string
109 */ 109 */
110 static int env_print(char *name) 110 static int env_print(char *name)
111 { 111 {
112 char *res = NULL; 112 char *res = NULL;
113 size_t len; 113 size_t len;
114 114
115 if (name) { /* print a single name */ 115 if (name) { /* print a single name */
116 ENTRY e, *ep; 116 ENTRY e, *ep;
117 117
118 e.key = name; 118 e.key = name;
119 e.data = NULL; 119 e.data = NULL;
120 hsearch_r(e, FIND, &ep, &env_htab); 120 hsearch_r(e, FIND, &ep, &env_htab);
121 if (ep == NULL) 121 if (ep == NULL)
122 return 0; 122 return 0;
123 len = printf("%s=%s\n", ep->key, ep->data); 123 len = printf("%s=%s\n", ep->key, ep->data);
124 return len; 124 return len;
125 } 125 }
126 126
127 /* print whole list */ 127 /* print whole list */
128 len = hexport_r(&env_htab, '\n', &res, 0, 0, NULL); 128 len = hexport_r(&env_htab, '\n', &res, 0, 0, NULL);
129 129
130 if (len > 0) { 130 if (len > 0) {
131 puts(res); 131 puts(res);
132 free(res); 132 free(res);
133 return len; 133 return len;
134 } 134 }
135 135
136 /* should never happen */ 136 /* should never happen */
137 return 0; 137 return 0;
138 } 138 }
139 139
140 int do_env_print (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 140 int do_env_print (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
141 { 141 {
142 int i; 142 int i;
143 int rcode = 0; 143 int rcode = 0;
144 144
145 if (argc == 1) { 145 if (argc == 1) {
146 /* print all env vars */ 146 /* print all env vars */
147 rcode = env_print(NULL); 147 rcode = env_print(NULL);
148 if (!rcode) 148 if (!rcode)
149 return 1; 149 return 1;
150 printf("\nEnvironment size: %d/%ld bytes\n", 150 printf("\nEnvironment size: %d/%ld bytes\n",
151 rcode, (ulong)ENV_SIZE); 151 rcode, (ulong)ENV_SIZE);
152 return 0; 152 return 0;
153 } 153 }
154 154
155 /* print selected env vars */ 155 /* print selected env vars */
156 for (i = 1; i < argc; ++i) { 156 for (i = 1; i < argc; ++i) {
157 int rc = env_print(argv[i]); 157 int rc = env_print(argv[i]);
158 if (!rc) { 158 if (!rc) {
159 printf("## Error: \"%s\" not defined\n", argv[i]); 159 printf("## Error: \"%s\" not defined\n", argv[i]);
160 ++rcode; 160 ++rcode;
161 } 161 }
162 } 162 }
163 163
164 return rcode; 164 return rcode;
165 } 165 }
166 166
167 #ifdef CONFIG_CMD_GREPENV 167 #ifdef CONFIG_CMD_GREPENV
168 static int do_env_grep(cmd_tbl_t *cmdtp, int flag, 168 static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
169 int argc, char * const argv[]) 169 int argc, char * const argv[])
170 { 170 {
171 ENTRY *match; 171 ENTRY *match;
172 unsigned char matched[env_htab.size / 8]; 172 unsigned char matched[env_htab.size / 8];
173 int rcode = 1, arg = 1, idx; 173 int rcode = 1, arg = 1, idx;
174 174
175 if (argc < 2) 175 if (argc < 2)
176 return cmd_usage(cmdtp); 176 return cmd_usage(cmdtp);
177 177
178 memset(matched, 0, env_htab.size / 8); 178 memset(matched, 0, env_htab.size / 8);
179 179
180 while (arg <= argc) { 180 while (arg <= argc) {
181 idx = 0; 181 idx = 0;
182 while ((idx = hstrstr_r(argv[arg], idx, &match, &env_htab))) { 182 while ((idx = hstrstr_r(argv[arg], idx, &match, &env_htab))) {
183 if (!(matched[idx / 8] & (1 << (idx & 7)))) { 183 if (!(matched[idx / 8] & (1 << (idx & 7)))) {
184 puts(match->key); 184 puts(match->key);
185 puts("="); 185 puts("=");
186 puts(match->data); 186 puts(match->data);
187 puts("\n"); 187 puts("\n");
188 } 188 }
189 matched[idx / 8] |= 1 << (idx & 7); 189 matched[idx / 8] |= 1 << (idx & 7);
190 rcode = 0; 190 rcode = 0;
191 } 191 }
192 arg++; 192 arg++;
193 } 193 }
194 194
195 return rcode; 195 return rcode;
196 } 196 }
197 #endif 197 #endif
198 198
199 /* 199 /*
200 * Set a new environment variable, 200 * Set a new environment variable,
201 * or replace or delete an existing one. 201 * or replace or delete an existing one.
202 */ 202 */
203 int _do_env_set(int flag, int argc, char * const argv[]) 203 int _do_env_set(int flag, int argc, char * const argv[])
204 { 204 {
205 bd_t *bd = gd->bd; 205 bd_t *bd = gd->bd;
206 int i, len; 206 int i, len;
207 int console = -1; 207 int console = -1;
208 char *name, *value, *s; 208 char *name, *value, *s;
209 ENTRY e, *ep; 209 ENTRY e, *ep;
210 210
211 name = argv[1]; 211 name = argv[1];
212 212
213 if (strchr(name, '=')) { 213 if (strchr(name, '=')) {
214 printf("## Error: illegal character '=' in variable name" 214 printf("## Error: illegal character '=' in variable name"
215 "\"%s\"\n", name); 215 "\"%s\"\n", name);
216 return 1; 216 return 1;
217 } 217 }
218 218
219 env_id++; 219 env_id++;
220 /* 220 /*
221 * search if variable with this name already exists 221 * search if variable with this name already exists
222 */ 222 */
223 e.key = name; 223 e.key = name;
224 e.data = NULL; 224 e.data = NULL;
225 hsearch_r(e, FIND, &ep, &env_htab); 225 hsearch_r(e, FIND, &ep, &env_htab);
226 226
227 /* Check for console redirection */ 227 /* Check for console redirection */
228 if (strcmp(name, "stdin") == 0) 228 if (strcmp(name, "stdin") == 0)
229 console = stdin; 229 console = stdin;
230 else if (strcmp(name, "stdout") == 0) 230 else if (strcmp(name, "stdout") == 0)
231 console = stdout; 231 console = stdout;
232 else if (strcmp(name, "stderr") == 0) 232 else if (strcmp(name, "stderr") == 0)
233 console = stderr; 233 console = stderr;
234 234
235 if (console != -1) { 235 if (console != -1) {
236 if (argc < 3) { /* Cannot delete it! */ 236 if (argc < 3) { /* Cannot delete it! */
237 printf("Can't delete \"%s\"\n", name); 237 printf("Can't delete \"%s\"\n", name);
238 return 1; 238 return 1;
239 } 239 }
240 240
241 #ifdef CONFIG_CONSOLE_MUX 241 #ifdef CONFIG_CONSOLE_MUX
242 i = iomux_doenv(console, argv[2]); 242 i = iomux_doenv(console, argv[2]);
243 if (i) 243 if (i)
244 return i; 244 return i;
245 #else 245 #else
246 /* Try assigning specified device */ 246 /* Try assigning specified device */
247 if (console_assign(console, argv[2]) < 0) 247 if (console_assign(console, argv[2]) < 0)
248 return 1; 248 return 1;
249 249
250 #ifdef CONFIG_SERIAL_MULTI 250 #ifdef CONFIG_SERIAL_MULTI
251 if (serial_assign(argv[2]) < 0) 251 if (serial_assign(argv[2]) < 0)
252 return 1; 252 return 1;
253 #endif 253 #endif
254 #endif /* CONFIG_CONSOLE_MUX */ 254 #endif /* CONFIG_CONSOLE_MUX */
255 } 255 }
256 256
257 /* 257 /*
258 * Some variables like "ethaddr" and "serial#" can be set only 258 * Some variables like "ethaddr" and "serial#" can be set only
259 * once and cannot be deleted; also, "ver" is readonly. 259 * once and cannot be deleted; also, "ver" is readonly.
260 */ 260 */
261 if (ep) { /* variable exists */ 261 if (ep) { /* variable exists */
262 #ifndef CONFIG_ENV_OVERWRITE 262 #ifndef CONFIG_ENV_OVERWRITE
263 if (strcmp(name, "serial#") == 0 || 263 if (strcmp(name, "serial#") == 0 ||
264 (strcmp(name, "ethaddr") == 0 264 (strcmp(name, "ethaddr") == 0
265 #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR) 265 #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
266 && strcmp(ep->data, MK_STR(CONFIG_ETHADDR)) != 0 266 && strcmp(ep->data, MK_STR(CONFIG_ETHADDR)) != 0
267 #endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */ 267 #endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */
268 )) { 268 )) {
269 printf("Can't overwrite \"%s\"\n", name); 269 printf("Can't overwrite \"%s\"\n", name);
270 return 1; 270 return 1;
271 } 271 }
272 #endif 272 #endif
273 /* 273 /*
274 * Switch to new baudrate if new baudrate is supported 274 * Switch to new baudrate if new baudrate is supported
275 */ 275 */
276 if (strcmp(name, "baudrate") == 0) { 276 if (strcmp(name, "baudrate") == 0) {
277 int baudrate = simple_strtoul(argv[2], NULL, 10); 277 int baudrate = simple_strtoul(argv[2], NULL, 10);
278 int i; 278 int i;
279 for (i = 0; i < N_BAUDRATES; ++i) { 279 for (i = 0; i < N_BAUDRATES; ++i) {
280 if (baudrate == baudrate_table[i]) 280 if (baudrate == baudrate_table[i])
281 break; 281 break;
282 } 282 }
283 if (i == N_BAUDRATES) { 283 if (i == N_BAUDRATES) {
284 printf("## Baudrate %d bps not supported\n", 284 printf("## Baudrate %d bps not supported\n",
285 baudrate); 285 baudrate);
286 return 1; 286 return 1;
287 } 287 }
288 printf("## Switch baudrate to %d bps and" 288 printf("## Switch baudrate to %d bps and"
289 "press ENTER ...\n", baudrate); 289 "press ENTER ...\n", baudrate);
290 udelay(50000); 290 udelay(50000);
291 gd->baudrate = baudrate; 291 gd->baudrate = baudrate;
292 #if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) 292 #if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2)
293 gd->bd->bi_baudrate = baudrate; 293 gd->bd->bi_baudrate = baudrate;
294 #endif 294 #endif
295 295
296 serial_setbrg(); 296 serial_setbrg();
297 udelay(50000); 297 udelay(50000);
298 while (getc() != '\r') 298 while (getc() != '\r')
299 ; 299 ;
300 } 300 }
301 } 301 }
302 302
303 /* Delete only ? */ 303 /* Delete only ? */
304 if (argc < 3 || argv[2] == NULL) { 304 if (argc < 3 || argv[2] == NULL) {
305 int rc = hdelete_r(name, &env_htab); 305 int rc = hdelete_r(name, &env_htab);
306 return !rc; 306 return !rc;
307 } 307 }
308 308
309 /* 309 /*
310 * Insert / replace new value 310 * Insert / replace new value
311 */ 311 */
312 for (i = 2, len = 0; i < argc; ++i) 312 for (i = 2, len = 0; i < argc; ++i)
313 len += strlen(argv[i]) + 1; 313 len += strlen(argv[i]) + 1;
314 314
315 value = malloc(len); 315 value = malloc(len);
316 if (value == NULL) { 316 if (value == NULL) {
317 printf("## Can't malloc %d bytes\n", len); 317 printf("## Can't malloc %d bytes\n", len);
318 return 1; 318 return 1;
319 } 319 }
320 for (i = 2, s = value; i < argc; ++i) { 320 for (i = 2, s = value; i < argc; ++i) {
321 char *v = argv[i]; 321 char *v = argv[i];
322 322
323 while ((*s++ = *v++) != '\0') 323 while ((*s++ = *v++) != '\0')
324 ; 324 ;
325 *(s - 1) = ' '; 325 *(s - 1) = ' ';
326 } 326 }
327 if (s != value) 327 if (s != value)
328 *--s = '\0'; 328 *--s = '\0';
329 329
330 e.key = name; 330 e.key = name;
331 e.data = value; 331 e.data = value;
332 hsearch_r(e, ENTER, &ep, &env_htab); 332 hsearch_r(e, ENTER, &ep, &env_htab);
333 free(value); 333 free(value);
334 if (!ep) { 334 if (!ep) {
335 printf("## Error inserting \"%s\" variable, errno=%d\n", 335 printf("## Error inserting \"%s\" variable, errno=%d\n",
336 name, errno); 336 name, errno);
337 return 1; 337 return 1;
338 } 338 }
339 339
340 /* 340 /*
341 * Some variables should be updated when the corresponding 341 * Some variables should be updated when the corresponding
342 * entry in the environment is changed 342 * entry in the environment is changed
343 */ 343 */
344 if (strcmp(name, "ipaddr") == 0) { 344 if (strcmp(name, "ipaddr") == 0) {
345 char *s = argv[2]; /* always use only one arg */ 345 char *s = argv[2]; /* always use only one arg */
346 char *e; 346 char *e;
347 unsigned long addr; 347 unsigned long addr;
348 bd->bi_ip_addr = 0; 348 bd->bi_ip_addr = 0;
349 for (addr = 0, i = 0; i < 4; ++i) { 349 for (addr = 0, i = 0; i < 4; ++i) {
350 ulong val = s ? simple_strtoul(s, &e, 10) : 0; 350 ulong val = s ? simple_strtoul(s, &e, 10) : 0;
351 addr <<= 8; 351 addr <<= 8;
352 addr |= val & 0xFF; 352 addr |= val & 0xFF;
353 if (s) 353 if (s)
354 s = *e ? e + 1 : e; 354 s = *e ? e + 1 : e;
355 } 355 }
356 bd->bi_ip_addr = htonl(addr); 356 bd->bi_ip_addr = htonl(addr);
357 return 0; 357 return 0;
358 } else if (strcmp(argv[1], "loadaddr") == 0) { 358 } else if (strcmp(argv[1], "loadaddr") == 0) {
359 load_addr = simple_strtoul(argv[2], NULL, 16); 359 load_addr = simple_strtoul(argv[2], NULL, 16);
360 return 0; 360 return 0;
361 } 361 }
362 #if defined(CONFIG_CMD_NET) 362 #if defined(CONFIG_CMD_NET)
363 else if (strcmp(argv[1], "bootfile") == 0) { 363 else if (strcmp(argv[1], "bootfile") == 0) {
364 copy_filename(BootFile, argv[2], sizeof(BootFile)); 364 copy_filename(BootFile, argv[2], sizeof(BootFile));
365 return 0; 365 return 0;
366 } 366 }
367 #endif 367 #endif
368 return 0; 368 return 0;
369 } 369 }
370 370
371 int setenv(const char *varname, const char *varvalue) 371 int setenv(const char *varname, const char *varvalue)
372 { 372 {
373 const char * const argv[4] = { "setenv", varname, varvalue, NULL }; 373 const char * const argv[4] = { "setenv", varname, varvalue, NULL };
374 374
375 if (varvalue == NULL || varvalue[0] == '\0') 375 if (varvalue == NULL || varvalue[0] == '\0')
376 return _do_env_set(0, 2, (char * const *)argv); 376 return _do_env_set(0, 2, (char * const *)argv);
377 else 377 else
378 return _do_env_set(0, 3, (char * const *)argv); 378 return _do_env_set(0, 3, (char * const *)argv);
379 } 379 }
380 380
381 /** 381 /**
382 * Set an environment variable to an integer value 382 * Set an environment variable to an integer value
383 * 383 *
384 * @param varname Environmet variable to set 384 * @param varname Environmet variable to set
385 * @param value Value to set it to 385 * @param value Value to set it to
386 * @return 0 if ok, 1 on error 386 * @return 0 if ok, 1 on error
387 */ 387 */
388 int setenv_ulong(const char *varname, ulong value) 388 int setenv_ulong(const char *varname, ulong value)
389 { 389 {
390 /* TODO: this should be unsigned */ 390 /* TODO: this should be unsigned */
391 char *str = simple_itoa(value); 391 char *str = simple_itoa(value);
392 392
393 return setenv(varname, str); 393 return setenv(varname, str);
394 } 394 }
395 395
396 /** 396 /**
397 * Set an environment variable to an address in hex 397 * Set an environment variable to an address in hex
398 * 398 *
399 * @param varname Environmet variable to set 399 * @param varname Environmet variable to set
400 * @param addr Value to set it to 400 * @param addr Value to set it to
401 * @return 0 if ok, 1 on error 401 * @return 0 if ok, 1 on error
402 */ 402 */
403 int setenv_addr(const char *varname, const void *addr) 403 int setenv_addr(const char *varname, const void *addr)
404 { 404 {
405 char str[17]; 405 char str[17];
406 406
407 sprintf(str, "%lx", (uintptr_t)addr); 407 sprintf(str, "%lx", (uintptr_t)addr);
408 return setenv(varname, str); 408 return setenv(varname, str);
409 } 409 }
410 410
411 int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 411 int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
412 { 412 {
413 if (argc < 2) 413 if (argc < 2)
414 return cmd_usage(cmdtp); 414 return cmd_usage(cmdtp);
415 415
416 return _do_env_set(flag, argc, argv); 416 return _do_env_set(flag, argc, argv);
417 } 417 }
418 418
419 /* 419 /*
420 * Prompt for environment variable 420 * Prompt for environment variable
421 */ 421 */
422 #if defined(CONFIG_CMD_ASKENV) 422 #if defined(CONFIG_CMD_ASKENV)
423 int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 423 int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
424 { 424 {
425 char message[CONFIG_SYS_CBSIZE]; 425 char message[CONFIG_SYS_CBSIZE];
426 int size = CONFIG_SYS_CBSIZE - 1; 426 int size = CONFIG_SYS_CBSIZE - 1;
427 int i, len, pos; 427 int i, len, pos;
428 char *local_args[4]; 428 char *local_args[4];
429 429
430 local_args[0] = argv[0]; 430 local_args[0] = argv[0];
431 local_args[1] = argv[1]; 431 local_args[1] = argv[1];
432 local_args[2] = NULL; 432 local_args[2] = NULL;
433 local_args[3] = NULL; 433 local_args[3] = NULL;
434 434
435 /* Check the syntax */ 435 /* Check the syntax */
436 switch (argc) { 436 switch (argc) {
437 case 1: 437 case 1:
438 return cmd_usage(cmdtp); 438 return cmd_usage(cmdtp);
439 439
440 case 2: /* env_ask envname */ 440 case 2: /* env_ask envname */
441 sprintf(message, "Please enter '%s':", argv[1]); 441 sprintf(message, "Please enter '%s':", argv[1]);
442 break; 442 break;
443 443
444 case 3: /* env_ask envname size */ 444 case 3: /* env_ask envname size */
445 sprintf(message, "Please enter '%s':", argv[1]); 445 sprintf(message, "Please enter '%s':", argv[1]);
446 size = simple_strtoul(argv[2], NULL, 10); 446 size = simple_strtoul(argv[2], NULL, 10);
447 break; 447 break;
448 448
449 default: /* env_ask envname message1 ... messagen size */ 449 default: /* env_ask envname message1 ... messagen size */
450 for (i = 2, pos = 0; i < argc - 1; i++) { 450 for (i = 2, pos = 0; i < argc - 1; i++) {
451 if (pos) 451 if (pos)
452 message[pos++] = ' '; 452 message[pos++] = ' ';
453 453
454 strcpy(message + pos, argv[i]); 454 strcpy(message + pos, argv[i]);
455 pos += strlen(argv[i]); 455 pos += strlen(argv[i]);
456 } 456 }
457 457
458 message[pos] = '\0'; 458 message[pos] = '\0';
459 size = simple_strtoul(argv[argc - 1], NULL, 10); 459 size = simple_strtoul(argv[argc - 1], NULL, 10);
460 break; 460 break;
461 } 461 }
462 462
463 if (size >= CONFIG_SYS_CBSIZE) 463 if (size >= CONFIG_SYS_CBSIZE)
464 size = CONFIG_SYS_CBSIZE - 1; 464 size = CONFIG_SYS_CBSIZE - 1;
465 465
466 if (size <= 0) 466 if (size <= 0)
467 return 1; 467 return 1;
468 468
469 /* prompt for input */ 469 /* prompt for input */
470 len = readline(message); 470 len = readline(message);
471 471
472 if (size < len) 472 if (size < len)
473 console_buffer[size] = '\0'; 473 console_buffer[size] = '\0';
474 474
475 len = 2; 475 len = 2;
476 if (console_buffer[0] != '\0') { 476 if (console_buffer[0] != '\0') {
477 local_args[2] = console_buffer; 477 local_args[2] = console_buffer;
478 len = 3; 478 len = 3;
479 } 479 }
480 480
481 /* Continue calling setenv code */ 481 /* Continue calling setenv code */
482 return _do_env_set(flag, len, local_args); 482 return _do_env_set(flag, len, local_args);
483 } 483 }
484 #endif 484 #endif
485 485
486 /* 486 /*
487 * Interactively edit an environment variable 487 * Interactively edit an environment variable
488 */ 488 */
489 #if defined(CONFIG_CMD_EDITENV) 489 #if defined(CONFIG_CMD_EDITENV)
490 int do_env_edit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 490 int do_env_edit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
491 { 491 {
492 char buffer[CONFIG_SYS_CBSIZE]; 492 char buffer[CONFIG_SYS_CBSIZE];
493 char *init_val; 493 char *init_val;
494 494
495 if (argc < 2) 495 if (argc < 2)
496 return cmd_usage(cmdtp); 496 return cmd_usage(cmdtp);
497 497
498 /* Set read buffer to initial value or empty sting */ 498 /* Set read buffer to initial value or empty sting */
499 init_val = getenv(argv[1]); 499 init_val = getenv(argv[1]);
500 if (init_val) 500 if (init_val)
501 sprintf(buffer, "%s", init_val); 501 sprintf(buffer, "%s", init_val);
502 else 502 else
503 buffer[0] = '\0'; 503 buffer[0] = '\0';
504 504
505 readline_into_buffer("edit: ", buffer); 505 readline_into_buffer("edit: ", buffer, 0);
506 506
507 return setenv(argv[1], buffer); 507 return setenv(argv[1], buffer);
508 } 508 }
509 #endif /* CONFIG_CMD_EDITENV */ 509 #endif /* CONFIG_CMD_EDITENV */
510 510
511 /* 511 /*
512 * Look up variable from environment, 512 * Look up variable from environment,
513 * return address of storage for that variable, 513 * return address of storage for that variable,
514 * or NULL if not found 514 * or NULL if not found
515 */ 515 */
516 char *getenv(const char *name) 516 char *getenv(const char *name)
517 { 517 {
518 if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */ 518 if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */
519 ENTRY e, *ep; 519 ENTRY e, *ep;
520 520
521 WATCHDOG_RESET(); 521 WATCHDOG_RESET();
522 522
523 e.key = name; 523 e.key = name;
524 e.data = NULL; 524 e.data = NULL;
525 hsearch_r(e, FIND, &ep, &env_htab); 525 hsearch_r(e, FIND, &ep, &env_htab);
526 526
527 return ep ? ep->data : NULL; 527 return ep ? ep->data : NULL;
528 } 528 }
529 529
530 /* restricted capabilities before import */ 530 /* restricted capabilities before import */
531 if (getenv_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0) 531 if (getenv_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)
532 return (char *)(gd->env_buf); 532 return (char *)(gd->env_buf);
533 533
534 return NULL; 534 return NULL;
535 } 535 }
536 536
537 /* 537 /*
538 * Look up variable from environment for restricted C runtime env. 538 * Look up variable from environment for restricted C runtime env.
539 */ 539 */
540 int getenv_f(const char *name, char *buf, unsigned len) 540 int getenv_f(const char *name, char *buf, unsigned len)
541 { 541 {
542 int i, nxt; 542 int i, nxt;
543 543
544 for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { 544 for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
545 int val, n; 545 int val, n;
546 546
547 for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) { 547 for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) {
548 if (nxt >= CONFIG_ENV_SIZE) 548 if (nxt >= CONFIG_ENV_SIZE)
549 return -1; 549 return -1;
550 } 550 }
551 551
552 val = envmatch((uchar *)name, i); 552 val = envmatch((uchar *)name, i);
553 if (val < 0) 553 if (val < 0)
554 continue; 554 continue;
555 555
556 /* found; copy out */ 556 /* found; copy out */
557 for (n = 0; n < len; ++n, ++buf) { 557 for (n = 0; n < len; ++n, ++buf) {
558 *buf = env_get_char(val++); 558 *buf = env_get_char(val++);
559 if (*buf == '\0') 559 if (*buf == '\0')
560 return n; 560 return n;
561 } 561 }
562 562
563 if (n) 563 if (n)
564 *--buf = '\0'; 564 *--buf = '\0';
565 565
566 printf("env_buf [%d bytes] too small for value of \"%s\"\n", 566 printf("env_buf [%d bytes] too small for value of \"%s\"\n",
567 len, name); 567 len, name);
568 568
569 return n; 569 return n;
570 } 570 }
571 571
572 return -1; 572 return -1;
573 } 573 }
574 574
575 /** 575 /**
576 * Decode the integer value of an environment variable and return it. 576 * Decode the integer value of an environment variable and return it.
577 * 577 *
578 * @param name Name of environemnt variable 578 * @param name Name of environemnt variable
579 * @param base Number base to use (normally 10, or 16 for hex) 579 * @param base Number base to use (normally 10, or 16 for hex)
580 * @param default_val Default value to return if the variable is not 580 * @param default_val Default value to return if the variable is not
581 * found 581 * found
582 * @return the decoded value, or default_val if not found 582 * @return the decoded value, or default_val if not found
583 */ 583 */
584 ulong getenv_ulong(const char *name, int base, ulong default_val) 584 ulong getenv_ulong(const char *name, int base, ulong default_val)
585 { 585 {
586 /* 586 /*
587 * We can use getenv() here, even before relocation, since the 587 * We can use getenv() here, even before relocation, since the
588 * environment variable value is an integer and thus short. 588 * environment variable value is an integer and thus short.
589 */ 589 */
590 const char *str = getenv(name); 590 const char *str = getenv(name);
591 591
592 return str ? simple_strtoul(str, NULL, base) : default_val; 592 return str ? simple_strtoul(str, NULL, base) : default_val;
593 } 593 }
594 594
595 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) 595 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
596 int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 596 int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
597 { 597 {
598 printf("Saving Environment to %s...\n", env_name_spec); 598 printf("Saving Environment to %s...\n", env_name_spec);
599 599
600 return saveenv() ? 1 : 0; 600 return saveenv() ? 1 : 0;
601 } 601 }
602 602
603 U_BOOT_CMD( 603 U_BOOT_CMD(
604 saveenv, 1, 0, do_env_save, 604 saveenv, 1, 0, do_env_save,
605 "save environment variables to persistent storage", 605 "save environment variables to persistent storage",
606 "" 606 ""
607 ); 607 );
608 #endif 608 #endif
609 609
610 610
611 /* 611 /*
612 * Match a name / name=value pair 612 * Match a name / name=value pair
613 * 613 *
614 * s1 is either a simple 'name', or a 'name=value' pair. 614 * s1 is either a simple 'name', or a 'name=value' pair.
615 * i2 is the environment index for a 'name2=value2' pair. 615 * i2 is the environment index for a 'name2=value2' pair.
616 * If the names match, return the index for the value2, else -1. 616 * If the names match, return the index for the value2, else -1.
617 */ 617 */
618 int envmatch(uchar *s1, int i2) 618 int envmatch(uchar *s1, int i2)
619 { 619 {
620 while (*s1 == env_get_char(i2++)) 620 while (*s1 == env_get_char(i2++))
621 if (*s1++ == '=') 621 if (*s1++ == '=')
622 return i2; 622 return i2;
623 623
624 if (*s1 == '\0' && env_get_char(i2-1) == '=') 624 if (*s1 == '\0' && env_get_char(i2-1) == '=')
625 return i2; 625 return i2;
626 626
627 return -1; 627 return -1;
628 } 628 }
629 629
630 static int do_env_default(cmd_tbl_t *cmdtp, int flag, 630 static int do_env_default(cmd_tbl_t *cmdtp, int flag,
631 int argc, char * const argv[]) 631 int argc, char * const argv[])
632 { 632 {
633 if (argc != 2 || strcmp(argv[1], "-f") != 0) 633 if (argc != 2 || strcmp(argv[1], "-f") != 0)
634 return cmd_usage(cmdtp); 634 return cmd_usage(cmdtp);
635 635
636 set_default_env("## Resetting to default environment\n"); 636 set_default_env("## Resetting to default environment\n");
637 return 0; 637 return 0;
638 } 638 }
639 639
640 static int do_env_delete(cmd_tbl_t *cmdtp, int flag, 640 static int do_env_delete(cmd_tbl_t *cmdtp, int flag,
641 int argc, char * const argv[]) 641 int argc, char * const argv[])
642 { 642 {
643 printf("Not implemented yet\n"); 643 printf("Not implemented yet\n");
644 return 0; 644 return 0;
645 } 645 }
646 646
647 #ifdef CONFIG_CMD_EXPORTENV 647 #ifdef CONFIG_CMD_EXPORTENV
648 /* 648 /*
649 * env export [-t | -b | -c] [-s size] addr [var ...] 649 * env export [-t | -b | -c] [-s size] addr [var ...]
650 * -t: export as text format; if size is given, data will be 650 * -t: export as text format; if size is given, data will be
651 * padded with '\0' bytes; if not, one terminating '\0' 651 * padded with '\0' bytes; if not, one terminating '\0'
652 * will be added (which is included in the "filesize" 652 * will be added (which is included in the "filesize"
653 * setting so you can for exmple copy this to flash and 653 * setting so you can for exmple copy this to flash and
654 * keep the termination). 654 * keep the termination).
655 * -b: export as binary format (name=value pairs separated by 655 * -b: export as binary format (name=value pairs separated by
656 * '\0', list end marked by double "\0\0") 656 * '\0', list end marked by double "\0\0")
657 * -c: export as checksum protected environment format as 657 * -c: export as checksum protected environment format as
658 * used for example by "saveenv" command 658 * used for example by "saveenv" command
659 * -s size: 659 * -s size:
660 * size of output buffer 660 * size of output buffer
661 * addr: memory address where environment gets stored 661 * addr: memory address where environment gets stored
662 * var... List of variable names that get included into the 662 * var... List of variable names that get included into the
663 * export. Without arguments, the whole environment gets 663 * export. Without arguments, the whole environment gets
664 * exported. 664 * exported.
665 * 665 *
666 * With "-c" and size is NOT given, then the export command will 666 * With "-c" and size is NOT given, then the export command will
667 * format the data as currently used for the persistent storage, 667 * format the data as currently used for the persistent storage,
668 * i. e. it will use CONFIG_ENV_SECT_SIZE as output block size and 668 * i. e. it will use CONFIG_ENV_SECT_SIZE as output block size and
669 * prepend a valid CRC32 checksum and, in case of resundant 669 * prepend a valid CRC32 checksum and, in case of resundant
670 * environment, a "current" redundancy flag. If size is given, this 670 * environment, a "current" redundancy flag. If size is given, this
671 * value will be used instead of CONFIG_ENV_SECT_SIZE; again, CRC32 671 * value will be used instead of CONFIG_ENV_SECT_SIZE; again, CRC32
672 * checksum and redundancy flag will be inserted. 672 * checksum and redundancy flag will be inserted.
673 * 673 *
674 * With "-b" and "-t", always only the real data (including a 674 * With "-b" and "-t", always only the real data (including a
675 * terminating '\0' byte) will be written; here the optional size 675 * terminating '\0' byte) will be written; here the optional size
676 * argument will be used to make sure not to overflow the user 676 * argument will be used to make sure not to overflow the user
677 * provided buffer; the command will abort if the size is not 677 * provided buffer; the command will abort if the size is not
678 * sufficient. Any remainign space will be '\0' padded. 678 * sufficient. Any remainign space will be '\0' padded.
679 * 679 *
680 * On successful return, the variable "filesize" will be set. 680 * On successful return, the variable "filesize" will be set.
681 * Note that filesize includes the trailing/terminating '\0' byte(s). 681 * Note that filesize includes the trailing/terminating '\0' byte(s).
682 * 682 *
683 * Usage szenario: create a text snapshot/backup of the current settings: 683 * Usage szenario: create a text snapshot/backup of the current settings:
684 * 684 *
685 * => env export -t 100000 685 * => env export -t 100000
686 * => era ${backup_addr} +${filesize} 686 * => era ${backup_addr} +${filesize}
687 * => cp.b 100000 ${backup_addr} ${filesize} 687 * => cp.b 100000 ${backup_addr} ${filesize}
688 * 688 *
689 * Re-import this snapshot, deleting all other settings: 689 * Re-import this snapshot, deleting all other settings:
690 * 690 *
691 * => env import -d -t ${backup_addr} 691 * => env import -d -t ${backup_addr}
692 */ 692 */
693 static int do_env_export(cmd_tbl_t *cmdtp, int flag, 693 static int do_env_export(cmd_tbl_t *cmdtp, int flag,
694 int argc, char * const argv[]) 694 int argc, char * const argv[])
695 { 695 {
696 char buf[32]; 696 char buf[32];
697 char *addr, *cmd, *res; 697 char *addr, *cmd, *res;
698 size_t size = 0; 698 size_t size = 0;
699 ssize_t len; 699 ssize_t len;
700 env_t *envp; 700 env_t *envp;
701 char sep = '\n'; 701 char sep = '\n';
702 int chk = 0; 702 int chk = 0;
703 int fmt = 0; 703 int fmt = 0;
704 704
705 cmd = *argv; 705 cmd = *argv;
706 706
707 while (--argc > 0 && **++argv == '-') { 707 while (--argc > 0 && **++argv == '-') {
708 char *arg = *argv; 708 char *arg = *argv;
709 while (*++arg) { 709 while (*++arg) {
710 switch (*arg) { 710 switch (*arg) {
711 case 'b': /* raw binary format */ 711 case 'b': /* raw binary format */
712 if (fmt++) 712 if (fmt++)
713 goto sep_err; 713 goto sep_err;
714 sep = '\0'; 714 sep = '\0';
715 break; 715 break;
716 case 'c': /* external checksum format */ 716 case 'c': /* external checksum format */
717 if (fmt++) 717 if (fmt++)
718 goto sep_err; 718 goto sep_err;
719 sep = '\0'; 719 sep = '\0';
720 chk = 1; 720 chk = 1;
721 break; 721 break;
722 case 's': /* size given */ 722 case 's': /* size given */
723 if (--argc <= 0) 723 if (--argc <= 0)
724 return cmd_usage(cmdtp); 724 return cmd_usage(cmdtp);
725 size = simple_strtoul(*++argv, NULL, 16); 725 size = simple_strtoul(*++argv, NULL, 16);
726 goto NXTARG; 726 goto NXTARG;
727 case 't': /* text format */ 727 case 't': /* text format */
728 if (fmt++) 728 if (fmt++)
729 goto sep_err; 729 goto sep_err;
730 sep = '\n'; 730 sep = '\n';
731 break; 731 break;
732 default: 732 default:
733 return cmd_usage(cmdtp); 733 return cmd_usage(cmdtp);
734 } 734 }
735 } 735 }
736 NXTARG: ; 736 NXTARG: ;
737 } 737 }
738 738
739 if (argc < 1) 739 if (argc < 1)
740 return cmd_usage(cmdtp); 740 return cmd_usage(cmdtp);
741 741
742 addr = (char *)simple_strtoul(argv[0], NULL, 16); 742 addr = (char *)simple_strtoul(argv[0], NULL, 16);
743 743
744 if (size) 744 if (size)
745 memset(addr, '\0', size); 745 memset(addr, '\0', size);
746 746
747 argc--; 747 argc--;
748 argv++; 748 argv++;
749 749
750 if (sep) { /* export as text file */ 750 if (sep) { /* export as text file */
751 len = hexport_r(&env_htab, sep, &addr, size, argc, argv); 751 len = hexport_r(&env_htab, sep, &addr, size, argc, argv);
752 if (len < 0) { 752 if (len < 0) {
753 error("Cannot export environment: errno = %d\n", errno); 753 error("Cannot export environment: errno = %d\n", errno);
754 return 1; 754 return 1;
755 } 755 }
756 sprintf(buf, "%zX", (size_t)len); 756 sprintf(buf, "%zX", (size_t)len);
757 setenv("filesize", buf); 757 setenv("filesize", buf);
758 758
759 return 0; 759 return 0;
760 } 760 }
761 761
762 envp = (env_t *)addr; 762 envp = (env_t *)addr;
763 763
764 if (chk) /* export as checksum protected block */ 764 if (chk) /* export as checksum protected block */
765 res = (char *)envp->data; 765 res = (char *)envp->data;
766 else /* export as raw binary data */ 766 else /* export as raw binary data */
767 res = addr; 767 res = addr;
768 768
769 len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, argc, argv); 769 len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, argc, argv);
770 if (len < 0) { 770 if (len < 0) {
771 error("Cannot export environment: errno = %d\n", errno); 771 error("Cannot export environment: errno = %d\n", errno);
772 return 1; 772 return 1;
773 } 773 }
774 774
775 if (chk) { 775 if (chk) {
776 envp->crc = crc32(0, envp->data, ENV_SIZE); 776 envp->crc = crc32(0, envp->data, ENV_SIZE);
777 #ifdef CONFIG_ENV_ADDR_REDUND 777 #ifdef CONFIG_ENV_ADDR_REDUND
778 envp->flags = ACTIVE_FLAG; 778 envp->flags = ACTIVE_FLAG;
779 #endif 779 #endif
780 } 780 }
781 sprintf(buf, "%zX", (size_t)(len + offsetof(env_t, data))); 781 sprintf(buf, "%zX", (size_t)(len + offsetof(env_t, data)));
782 setenv("filesize", buf); 782 setenv("filesize", buf);
783 783
784 return 0; 784 return 0;
785 785
786 sep_err: 786 sep_err:
787 printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n", cmd); 787 printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n", cmd);
788 return 1; 788 return 1;
789 } 789 }
790 #endif 790 #endif
791 791
792 #ifdef CONFIG_CMD_IMPORTENV 792 #ifdef CONFIG_CMD_IMPORTENV
793 /* 793 /*
794 * env import [-d] [-t | -b | -c] addr [size] 794 * env import [-d] [-t | -b | -c] addr [size]
795 * -d: delete existing environment before importing; 795 * -d: delete existing environment before importing;
796 * otherwise overwrite / append to existion definitions 796 * otherwise overwrite / append to existion definitions
797 * -t: assume text format; either "size" must be given or the 797 * -t: assume text format; either "size" must be given or the
798 * text data must be '\0' terminated 798 * text data must be '\0' terminated
799 * -b: assume binary format ('\0' separated, "\0\0" terminated) 799 * -b: assume binary format ('\0' separated, "\0\0" terminated)
800 * -c: assume checksum protected environment format 800 * -c: assume checksum protected environment format
801 * addr: memory address to read from 801 * addr: memory address to read from
802 * size: length of input data; if missing, proper '\0' 802 * size: length of input data; if missing, proper '\0'
803 * termination is mandatory 803 * termination is mandatory
804 */ 804 */
805 static int do_env_import(cmd_tbl_t *cmdtp, int flag, 805 static int do_env_import(cmd_tbl_t *cmdtp, int flag,
806 int argc, char * const argv[]) 806 int argc, char * const argv[])
807 { 807 {
808 char *cmd, *addr; 808 char *cmd, *addr;
809 char sep = '\n'; 809 char sep = '\n';
810 int chk = 0; 810 int chk = 0;
811 int fmt = 0; 811 int fmt = 0;
812 int del = 0; 812 int del = 0;
813 size_t size; 813 size_t size;
814 814
815 cmd = *argv; 815 cmd = *argv;
816 816
817 while (--argc > 0 && **++argv == '-') { 817 while (--argc > 0 && **++argv == '-') {
818 char *arg = *argv; 818 char *arg = *argv;
819 while (*++arg) { 819 while (*++arg) {
820 switch (*arg) { 820 switch (*arg) {
821 case 'b': /* raw binary format */ 821 case 'b': /* raw binary format */
822 if (fmt++) 822 if (fmt++)
823 goto sep_err; 823 goto sep_err;
824 sep = '\0'; 824 sep = '\0';
825 break; 825 break;
826 case 'c': /* external checksum format */ 826 case 'c': /* external checksum format */
827 if (fmt++) 827 if (fmt++)
828 goto sep_err; 828 goto sep_err;
829 sep = '\0'; 829 sep = '\0';
830 chk = 1; 830 chk = 1;
831 break; 831 break;
832 case 't': /* text format */ 832 case 't': /* text format */
833 if (fmt++) 833 if (fmt++)
834 goto sep_err; 834 goto sep_err;
835 sep = '\n'; 835 sep = '\n';
836 break; 836 break;
837 case 'd': 837 case 'd':
838 del = 1; 838 del = 1;
839 break; 839 break;
840 default: 840 default:
841 return cmd_usage(cmdtp); 841 return cmd_usage(cmdtp);
842 } 842 }
843 } 843 }
844 } 844 }
845 845
846 if (argc < 1) 846 if (argc < 1)
847 return cmd_usage(cmdtp); 847 return cmd_usage(cmdtp);
848 848
849 if (!fmt) 849 if (!fmt)
850 printf("## Warning: defaulting to text format\n"); 850 printf("## Warning: defaulting to text format\n");
851 851
852 addr = (char *)simple_strtoul(argv[0], NULL, 16); 852 addr = (char *)simple_strtoul(argv[0], NULL, 16);
853 853
854 if (argc == 2) { 854 if (argc == 2) {
855 size = simple_strtoul(argv[1], NULL, 16); 855 size = simple_strtoul(argv[1], NULL, 16);
856 } else { 856 } else {
857 char *s = addr; 857 char *s = addr;
858 858
859 size = 0; 859 size = 0;
860 860
861 while (size < MAX_ENV_SIZE) { 861 while (size < MAX_ENV_SIZE) {
862 if ((*s == sep) && (*(s+1) == '\0')) 862 if ((*s == sep) && (*(s+1) == '\0'))
863 break; 863 break;
864 ++s; 864 ++s;
865 ++size; 865 ++size;
866 } 866 }
867 if (size == MAX_ENV_SIZE) { 867 if (size == MAX_ENV_SIZE) {
868 printf("## Warning: Input data exceeds %d bytes" 868 printf("## Warning: Input data exceeds %d bytes"
869 " - truncated\n", MAX_ENV_SIZE); 869 " - truncated\n", MAX_ENV_SIZE);
870 } 870 }
871 size += 2; 871 size += 2;
872 printf("## Info: input data size = %zu = 0x%zX\n", size, size); 872 printf("## Info: input data size = %zu = 0x%zX\n", size, size);
873 } 873 }
874 874
875 if (chk) { 875 if (chk) {
876 uint32_t crc; 876 uint32_t crc;
877 env_t *ep = (env_t *)addr; 877 env_t *ep = (env_t *)addr;
878 878
879 size -= offsetof(env_t, data); 879 size -= offsetof(env_t, data);
880 memcpy(&crc, &ep->crc, sizeof(crc)); 880 memcpy(&crc, &ep->crc, sizeof(crc));
881 881
882 if (crc32(0, ep->data, size) != crc) { 882 if (crc32(0, ep->data, size) != crc) {
883 puts("## Error: bad CRC, import failed\n"); 883 puts("## Error: bad CRC, import failed\n");
884 return 1; 884 return 1;
885 } 885 }
886 addr = (char *)ep->data; 886 addr = (char *)ep->data;
887 } 887 }
888 888
889 if (himport_r(&env_htab, addr, size, sep, del ? 0 : H_NOCLEAR) == 0) { 889 if (himport_r(&env_htab, addr, size, sep, del ? 0 : H_NOCLEAR) == 0) {
890 error("Environment import failed: errno = %d\n", errno); 890 error("Environment import failed: errno = %d\n", errno);
891 return 1; 891 return 1;
892 } 892 }
893 gd->flags |= GD_FLG_ENV_READY; 893 gd->flags |= GD_FLG_ENV_READY;
894 894
895 return 0; 895 return 0;
896 896
897 sep_err: 897 sep_err:
898 printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n", 898 printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n",
899 cmd); 899 cmd);
900 return 1; 900 return 1;
901 } 901 }
902 #endif 902 #endif
903 903
904 /* 904 /*
905 * New command line interface: "env" command with subcommands 905 * New command line interface: "env" command with subcommands
906 */ 906 */
907 static cmd_tbl_t cmd_env_sub[] = { 907 static cmd_tbl_t cmd_env_sub[] = {
908 #if defined(CONFIG_CMD_ASKENV) 908 #if defined(CONFIG_CMD_ASKENV)
909 U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", ""), 909 U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", ""),
910 #endif 910 #endif
911 U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", ""), 911 U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", ""),
912 U_BOOT_CMD_MKENT(delete, 2, 0, do_env_delete, "", ""), 912 U_BOOT_CMD_MKENT(delete, 2, 0, do_env_delete, "", ""),
913 #if defined(CONFIG_CMD_EDITENV) 913 #if defined(CONFIG_CMD_EDITENV)
914 U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", ""), 914 U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", ""),
915 #endif 915 #endif
916 #if defined(CONFIG_CMD_EXPORTENV) 916 #if defined(CONFIG_CMD_EXPORTENV)
917 U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", ""), 917 U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", ""),
918 #endif 918 #endif
919 #if defined(CONFIG_CMD_GREPENV) 919 #if defined(CONFIG_CMD_GREPENV)
920 U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""), 920 U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""),
921 #endif 921 #endif
922 #if defined(CONFIG_CMD_IMPORTENV) 922 #if defined(CONFIG_CMD_IMPORTENV)
923 U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""), 923 U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""),
924 #endif 924 #endif
925 U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""), 925 U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""),
926 #if defined(CONFIG_CMD_RUN) 926 #if defined(CONFIG_CMD_RUN)
927 U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""), 927 U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""),
928 #endif 928 #endif
929 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) 929 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
930 U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""), 930 U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""),
931 #endif 931 #endif
932 U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""), 932 U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""),
933 }; 933 };
934 934
935 #if defined(CONFIG_NEEDS_MANUAL_RELOC) 935 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
936 void env_reloc(void) 936 void env_reloc(void)
937 { 937 {
938 fixup_cmdtable(cmd_env_sub, ARRAY_SIZE(cmd_env_sub)); 938 fixup_cmdtable(cmd_env_sub, ARRAY_SIZE(cmd_env_sub));
939 } 939 }
940 #endif 940 #endif
941 941
942 static int do_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 942 static int do_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
943 { 943 {
944 cmd_tbl_t *cp; 944 cmd_tbl_t *cp;
945 945
946 if (argc < 2) 946 if (argc < 2)
947 return cmd_usage(cmdtp); 947 return cmd_usage(cmdtp);
948 948
949 /* drop initial "env" arg */ 949 /* drop initial "env" arg */
950 argc--; 950 argc--;
951 argv++; 951 argv++;
952 952
953 cp = find_cmd_tbl(argv[0], cmd_env_sub, ARRAY_SIZE(cmd_env_sub)); 953 cp = find_cmd_tbl(argv[0], cmd_env_sub, ARRAY_SIZE(cmd_env_sub));
954 954
955 if (cp) 955 if (cp)
956 return cp->cmd(cmdtp, flag, argc, argv); 956 return cp->cmd(cmdtp, flag, argc, argv);
957 957
958 return cmd_usage(cmdtp); 958 return cmd_usage(cmdtp);
959 } 959 }
960 960
961 U_BOOT_CMD( 961 U_BOOT_CMD(
962 env, CONFIG_SYS_MAXARGS, 1, do_env, 962 env, CONFIG_SYS_MAXARGS, 1, do_env,
963 "environment handling commands", 963 "environment handling commands",
964 #if defined(CONFIG_CMD_ASKENV) 964 #if defined(CONFIG_CMD_ASKENV)
965 "ask name [message] [size] - ask for environment variable\nenv " 965 "ask name [message] [size] - ask for environment variable\nenv "
966 #endif 966 #endif
967 "default -f - reset default environment\n" 967 "default -f - reset default environment\n"
968 #if defined(CONFIG_CMD_EDITENV) 968 #if defined(CONFIG_CMD_EDITENV)
969 "env edit name - edit environment variable\n" 969 "env edit name - edit environment variable\n"
970 #endif 970 #endif
971 "env export [-t | -b | -c] [-s size] addr [var ...] - export environment\n" 971 "env export [-t | -b | -c] [-s size] addr [var ...] - export environment\n"
972 #if defined(CONFIG_CMD_GREPENV) 972 #if defined(CONFIG_CMD_GREPENV)
973 "env grep string [...] - search environment\n" 973 "env grep string [...] - search environment\n"
974 #endif 974 #endif
975 "env import [-d] [-t | -b | -c] addr [size] - import environment\n" 975 "env import [-d] [-t | -b | -c] addr [size] - import environment\n"
976 "env print [name ...] - print environment\n" 976 "env print [name ...] - print environment\n"
977 #if defined(CONFIG_CMD_RUN) 977 #if defined(CONFIG_CMD_RUN)
978 "env run var [...] - run commands in an environment variable\n" 978 "env run var [...] - run commands in an environment variable\n"
979 #endif 979 #endif
980 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) 980 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
981 "env save - save environment\n" 981 "env save - save environment\n"
982 #endif 982 #endif
983 "env set [-f] name [arg ...]\n" 983 "env set [-f] name [arg ...]\n"
984 ); 984 );
985 985
986 /* 986 /*
987 * Old command line interface, kept for compatibility 987 * Old command line interface, kept for compatibility
988 */ 988 */
989 989
990 #if defined(CONFIG_CMD_EDITENV) 990 #if defined(CONFIG_CMD_EDITENV)
991 U_BOOT_CMD_COMPLETE( 991 U_BOOT_CMD_COMPLETE(
992 editenv, 2, 0, do_env_edit, 992 editenv, 2, 0, do_env_edit,
993 "edit environment variable", 993 "edit environment variable",
994 "name\n" 994 "name\n"
995 " - edit environment variable 'name'", 995 " - edit environment variable 'name'",
996 var_complete 996 var_complete
997 ); 997 );
998 #endif 998 #endif
999 999
1000 U_BOOT_CMD_COMPLETE( 1000 U_BOOT_CMD_COMPLETE(
1001 printenv, CONFIG_SYS_MAXARGS, 1, do_env_print, 1001 printenv, CONFIG_SYS_MAXARGS, 1, do_env_print,
1002 "print environment variables", 1002 "print environment variables",
1003 "\n - print values of all environment variables\n" 1003 "\n - print values of all environment variables\n"
1004 "printenv name ...\n" 1004 "printenv name ...\n"
1005 " - print value of environment variable 'name'", 1005 " - print value of environment variable 'name'",
1006 var_complete 1006 var_complete
1007 ); 1007 );
1008 1008
1009 #ifdef CONFIG_CMD_GREPENV 1009 #ifdef CONFIG_CMD_GREPENV
1010 U_BOOT_CMD_COMPLETE( 1010 U_BOOT_CMD_COMPLETE(
1011 grepenv, CONFIG_SYS_MAXARGS, 0, do_env_grep, 1011 grepenv, CONFIG_SYS_MAXARGS, 0, do_env_grep,
1012 "search environment variables", 1012 "search environment variables",
1013 "string ...\n" 1013 "string ...\n"
1014 " - list environment name=value pairs matching 'string'", 1014 " - list environment name=value pairs matching 'string'",
1015 var_complete 1015 var_complete
1016 ); 1016 );
1017 #endif 1017 #endif
1018 1018
1019 U_BOOT_CMD_COMPLETE( 1019 U_BOOT_CMD_COMPLETE(
1020 setenv, CONFIG_SYS_MAXARGS, 0, do_env_set, 1020 setenv, CONFIG_SYS_MAXARGS, 0, do_env_set,
1021 "set environment variables", 1021 "set environment variables",
1022 "name value ...\n" 1022 "name value ...\n"
1023 " - set environment variable 'name' to 'value ...'\n" 1023 " - set environment variable 'name' to 'value ...'\n"
1024 "setenv name\n" 1024 "setenv name\n"
1025 " - delete environment variable 'name'", 1025 " - delete environment variable 'name'",
1026 var_complete 1026 var_complete
1027 ); 1027 );
1028 1028
1029 #if defined(CONFIG_CMD_ASKENV) 1029 #if defined(CONFIG_CMD_ASKENV)
1030 1030
1031 U_BOOT_CMD( 1031 U_BOOT_CMD(
1032 askenv, CONFIG_SYS_MAXARGS, 1, do_env_ask, 1032 askenv, CONFIG_SYS_MAXARGS, 1, do_env_ask,
1033 "get environment variables from stdin", 1033 "get environment variables from stdin",
1034 "name [message] [size]\n" 1034 "name [message] [size]\n"
1035 " - get environment variable 'name' from stdin (max 'size' chars)\n" 1035 " - get environment variable 'name' from stdin (max 'size' chars)\n"
1036 "askenv name\n" 1036 "askenv name\n"
1037 " - get environment variable 'name' from stdin\n" 1037 " - get environment variable 'name' from stdin\n"
1038 "askenv name size\n" 1038 "askenv name size\n"
1039 " - get environment variable 'name' from stdin (max 'size' chars)\n" 1039 " - get environment variable 'name' from stdin (max 'size' chars)\n"
1040 "askenv name [message] size\n" 1040 "askenv name [message] size\n"
1041 " - display 'message' string and get environment variable 'name'" 1041 " - display 'message' string and get environment variable 'name'"
1042 "from stdin (max 'size' chars)" 1042 "from stdin (max 'size' chars)"
1043 ); 1043 );
1044 #endif 1044 #endif
1045 1045
1046 #if defined(CONFIG_CMD_RUN) 1046 #if defined(CONFIG_CMD_RUN)
1047 U_BOOT_CMD_COMPLETE( 1047 U_BOOT_CMD_COMPLETE(
1048 run, CONFIG_SYS_MAXARGS, 1, do_run, 1048 run, CONFIG_SYS_MAXARGS, 1, do_run,
1049 "run commands in an environment variable", 1049 "run commands in an environment variable",
1050 "var [...]\n" 1050 "var [...]\n"
1051 " - run the commands in the environment variable(s) 'var'", 1051 " - run the commands in the environment variable(s) 'var'",
1052 var_complete 1052 var_complete
1053 ); 1053 );
1054 #endif 1054 #endif
1055 1055
1 /* 1 /*
2 * (C) Copyright 2000 2 * (C) Copyright 2000
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 * 4 *
5 * Add to readline cmdline-editing by 5 * Add to readline cmdline-editing by
6 * (C) Copyright 2005 6 * (C) Copyright 2005
7 * JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com> 7 * JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com>
8 * 8 *
9 * See file CREDITS for list of people who contributed to this 9 * See file CREDITS for list of people who contributed to this
10 * project. 10 * project.
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as 13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of 14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version. 15 * the License, or (at your option) any later version.
16 * 16 *
17 * This program is distributed in the hope that it will be useful, 17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details. 20 * GNU General Public License for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License 22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software 23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA 25 * MA 02111-1307 USA
26 */ 26 */
27 27
28 /* #define DEBUG */ 28 /* #define DEBUG */
29 29
30 #include <common.h> 30 #include <common.h>
31 #include <watchdog.h> 31 #include <watchdog.h>
32 #include <command.h> 32 #include <command.h>
33 #include <version.h> 33 #include <version.h>
34 #ifdef CONFIG_MODEM_SUPPORT 34 #ifdef CONFIG_MODEM_SUPPORT
35 #include <malloc.h> /* for free() prototype */ 35 #include <malloc.h> /* for free() prototype */
36 #endif 36 #endif
37 37
38 #ifdef CONFIG_SYS_HUSH_PARSER 38 #ifdef CONFIG_SYS_HUSH_PARSER
39 #include <hush.h> 39 #include <hush.h>
40 #endif 40 #endif
41 41
42 #include <post.h> 42 #include <post.h>
43 #include <linux/ctype.h> 43 #include <linux/ctype.h>
44 44
45 #if defined(CONFIG_SILENT_CONSOLE) || defined(CONFIG_POST) || defined(CONFIG_CMDLINE_EDITING) 45 #if defined(CONFIG_SILENT_CONSOLE) || defined(CONFIG_POST) || defined(CONFIG_CMDLINE_EDITING)
46 DECLARE_GLOBAL_DATA_PTR; 46 DECLARE_GLOBAL_DATA_PTR;
47 #endif 47 #endif
48 48
49 /* 49 /*
50 * Board-specific Platform code can reimplement show_boot_progress () if needed 50 * Board-specific Platform code can reimplement show_boot_progress () if needed
51 */ 51 */
52 void inline __show_boot_progress (int val) {} 52 void inline __show_boot_progress (int val) {}
53 void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress"))); 53 void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
54 54
55 #if defined(CONFIG_UPDATE_TFTP) 55 #if defined(CONFIG_UPDATE_TFTP)
56 int update_tftp (ulong addr); 56 int update_tftp (ulong addr);
57 #endif /* CONFIG_UPDATE_TFTP */ 57 #endif /* CONFIG_UPDATE_TFTP */
58 58
59 #define MAX_DELAY_STOP_STR 32 59 #define MAX_DELAY_STOP_STR 32
60 60
61 #undef DEBUG_PARSER 61 #undef DEBUG_PARSER
62 62
63 char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */ 63 char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */
64 64
65 static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen); 65 static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
66 static const char erase_seq[] = "\b \b"; /* erase sequence */ 66 static const char erase_seq[] = "\b \b"; /* erase sequence */
67 static const char tab_seq[] = " "; /* used to expand TABs */ 67 static const char tab_seq[] = " "; /* used to expand TABs */
68 68
69 #ifdef CONFIG_BOOT_RETRY_TIME 69 #ifdef CONFIG_BOOT_RETRY_TIME
70 static uint64_t endtime = 0; /* must be set, default is instant timeout */ 70 static uint64_t endtime = 0; /* must be set, default is instant timeout */
71 static int retry_time = -1; /* -1 so can call readline before main_loop */ 71 static int retry_time = -1; /* -1 so can call readline before main_loop */
72 #endif 72 #endif
73 73
74 #define endtick(seconds) (get_ticks() + (uint64_t)(seconds) * get_tbclk()) 74 #define endtick(seconds) (get_ticks() + (uint64_t)(seconds) * get_tbclk())
75 75
76 #ifndef CONFIG_BOOT_RETRY_MIN 76 #ifndef CONFIG_BOOT_RETRY_MIN
77 #define CONFIG_BOOT_RETRY_MIN CONFIG_BOOT_RETRY_TIME 77 #define CONFIG_BOOT_RETRY_MIN CONFIG_BOOT_RETRY_TIME
78 #endif 78 #endif
79 79
80 #ifdef CONFIG_MODEM_SUPPORT 80 #ifdef CONFIG_MODEM_SUPPORT
81 int do_mdm_init = 0; 81 int do_mdm_init = 0;
82 extern void mdm_init(void); /* defined in board.c */ 82 extern void mdm_init(void); /* defined in board.c */
83 #endif 83 #endif
84 84
85 /*************************************************************************** 85 /***************************************************************************
86 * Watch for 'delay' seconds for autoboot stop or autoboot delay string. 86 * Watch for 'delay' seconds for autoboot stop or autoboot delay string.
87 * returns: 0 - no key string, allow autoboot 1 - got key string, abort 87 * returns: 0 - no key string, allow autoboot 1 - got key string, abort
88 */ 88 */
89 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) 89 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
90 # if defined(CONFIG_AUTOBOOT_KEYED) 90 # if defined(CONFIG_AUTOBOOT_KEYED)
91 #ifndef CONFIG_MENU 91 #ifndef CONFIG_MENU
92 static inline 92 static inline
93 #endif 93 #endif
94 int abortboot(int bootdelay) 94 int abortboot(int bootdelay)
95 { 95 {
96 int abort = 0; 96 int abort = 0;
97 uint64_t etime = endtick(bootdelay); 97 uint64_t etime = endtick(bootdelay);
98 struct { 98 struct {
99 char* str; 99 char* str;
100 u_int len; 100 u_int len;
101 int retry; 101 int retry;
102 } 102 }
103 delaykey [] = { 103 delaykey [] = {
104 { str: getenv ("bootdelaykey"), retry: 1 }, 104 { str: getenv ("bootdelaykey"), retry: 1 },
105 { str: getenv ("bootdelaykey2"), retry: 1 }, 105 { str: getenv ("bootdelaykey2"), retry: 1 },
106 { str: getenv ("bootstopkey"), retry: 0 }, 106 { str: getenv ("bootstopkey"), retry: 0 },
107 { str: getenv ("bootstopkey2"), retry: 0 }, 107 { str: getenv ("bootstopkey2"), retry: 0 },
108 }; 108 };
109 109
110 char presskey [MAX_DELAY_STOP_STR]; 110 char presskey [MAX_DELAY_STOP_STR];
111 u_int presskey_len = 0; 111 u_int presskey_len = 0;
112 u_int presskey_max = 0; 112 u_int presskey_max = 0;
113 u_int i; 113 u_int i;
114 114
115 # ifdef CONFIG_AUTOBOOT_PROMPT 115 # ifdef CONFIG_AUTOBOOT_PROMPT
116 printf(CONFIG_AUTOBOOT_PROMPT); 116 printf(CONFIG_AUTOBOOT_PROMPT);
117 # endif 117 # endif
118 118
119 # ifdef CONFIG_AUTOBOOT_DELAY_STR 119 # ifdef CONFIG_AUTOBOOT_DELAY_STR
120 if (delaykey[0].str == NULL) 120 if (delaykey[0].str == NULL)
121 delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR; 121 delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR;
122 # endif 122 # endif
123 # ifdef CONFIG_AUTOBOOT_DELAY_STR2 123 # ifdef CONFIG_AUTOBOOT_DELAY_STR2
124 if (delaykey[1].str == NULL) 124 if (delaykey[1].str == NULL)
125 delaykey[1].str = CONFIG_AUTOBOOT_DELAY_STR2; 125 delaykey[1].str = CONFIG_AUTOBOOT_DELAY_STR2;
126 # endif 126 # endif
127 # ifdef CONFIG_AUTOBOOT_STOP_STR 127 # ifdef CONFIG_AUTOBOOT_STOP_STR
128 if (delaykey[2].str == NULL) 128 if (delaykey[2].str == NULL)
129 delaykey[2].str = CONFIG_AUTOBOOT_STOP_STR; 129 delaykey[2].str = CONFIG_AUTOBOOT_STOP_STR;
130 # endif 130 # endif
131 # ifdef CONFIG_AUTOBOOT_STOP_STR2 131 # ifdef CONFIG_AUTOBOOT_STOP_STR2
132 if (delaykey[3].str == NULL) 132 if (delaykey[3].str == NULL)
133 delaykey[3].str = CONFIG_AUTOBOOT_STOP_STR2; 133 delaykey[3].str = CONFIG_AUTOBOOT_STOP_STR2;
134 # endif 134 # endif
135 135
136 for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) { 136 for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
137 delaykey[i].len = delaykey[i].str == NULL ? 137 delaykey[i].len = delaykey[i].str == NULL ?
138 0 : strlen (delaykey[i].str); 138 0 : strlen (delaykey[i].str);
139 delaykey[i].len = delaykey[i].len > MAX_DELAY_STOP_STR ? 139 delaykey[i].len = delaykey[i].len > MAX_DELAY_STOP_STR ?
140 MAX_DELAY_STOP_STR : delaykey[i].len; 140 MAX_DELAY_STOP_STR : delaykey[i].len;
141 141
142 presskey_max = presskey_max > delaykey[i].len ? 142 presskey_max = presskey_max > delaykey[i].len ?
143 presskey_max : delaykey[i].len; 143 presskey_max : delaykey[i].len;
144 144
145 # if DEBUG_BOOTKEYS 145 # if DEBUG_BOOTKEYS
146 printf("%s key:<%s>\n", 146 printf("%s key:<%s>\n",
147 delaykey[i].retry ? "delay" : "stop", 147 delaykey[i].retry ? "delay" : "stop",
148 delaykey[i].str ? delaykey[i].str : "NULL"); 148 delaykey[i].str ? delaykey[i].str : "NULL");
149 # endif 149 # endif
150 } 150 }
151 151
152 /* In order to keep up with incoming data, check timeout only 152 /* In order to keep up with incoming data, check timeout only
153 * when catch up. 153 * when catch up.
154 */ 154 */
155 do { 155 do {
156 if (tstc()) { 156 if (tstc()) {
157 if (presskey_len < presskey_max) { 157 if (presskey_len < presskey_max) {
158 presskey [presskey_len ++] = getc(); 158 presskey [presskey_len ++] = getc();
159 } 159 }
160 else { 160 else {
161 for (i = 0; i < presskey_max - 1; i ++) 161 for (i = 0; i < presskey_max - 1; i ++)
162 presskey [i] = presskey [i + 1]; 162 presskey [i] = presskey [i + 1];
163 163
164 presskey [i] = getc(); 164 presskey [i] = getc();
165 } 165 }
166 } 166 }
167 167
168 for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) { 168 for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
169 if (delaykey[i].len > 0 && 169 if (delaykey[i].len > 0 &&
170 presskey_len >= delaykey[i].len && 170 presskey_len >= delaykey[i].len &&
171 memcmp (presskey + presskey_len - delaykey[i].len, 171 memcmp (presskey + presskey_len - delaykey[i].len,
172 delaykey[i].str, 172 delaykey[i].str,
173 delaykey[i].len) == 0) { 173 delaykey[i].len) == 0) {
174 # if DEBUG_BOOTKEYS 174 # if DEBUG_BOOTKEYS
175 printf("got %skey\n", 175 printf("got %skey\n",
176 delaykey[i].retry ? "delay" : "stop"); 176 delaykey[i].retry ? "delay" : "stop");
177 # endif 177 # endif
178 178
179 # ifdef CONFIG_BOOT_RETRY_TIME 179 # ifdef CONFIG_BOOT_RETRY_TIME
180 /* don't retry auto boot */ 180 /* don't retry auto boot */
181 if (! delaykey[i].retry) 181 if (! delaykey[i].retry)
182 retry_time = -1; 182 retry_time = -1;
183 # endif 183 # endif
184 abort = 1; 184 abort = 1;
185 } 185 }
186 } 186 }
187 } while (!abort && get_ticks() <= etime); 187 } while (!abort && get_ticks() <= etime);
188 188
189 # if DEBUG_BOOTKEYS 189 # if DEBUG_BOOTKEYS
190 if (!abort) 190 if (!abort)
191 puts("key timeout\n"); 191 puts("key timeout\n");
192 # endif 192 # endif
193 193
194 #ifdef CONFIG_SILENT_CONSOLE 194 #ifdef CONFIG_SILENT_CONSOLE
195 if (abort) 195 if (abort)
196 gd->flags &= ~GD_FLG_SILENT; 196 gd->flags &= ~GD_FLG_SILENT;
197 #endif 197 #endif
198 198
199 return abort; 199 return abort;
200 } 200 }
201 201
202 # else /* !defined(CONFIG_AUTOBOOT_KEYED) */ 202 # else /* !defined(CONFIG_AUTOBOOT_KEYED) */
203 203
204 #ifdef CONFIG_MENUKEY 204 #ifdef CONFIG_MENUKEY
205 static int menukey = 0; 205 static int menukey = 0;
206 #endif 206 #endif
207 207
208 #ifndef CONFIG_MENU 208 #ifndef CONFIG_MENU
209 static inline 209 static inline
210 #endif 210 #endif
211 int abortboot(int bootdelay) 211 int abortboot(int bootdelay)
212 { 212 {
213 int abort = 0; 213 int abort = 0;
214 214
215 #ifdef CONFIG_MENUPROMPT 215 #ifdef CONFIG_MENUPROMPT
216 printf(CONFIG_MENUPROMPT); 216 printf(CONFIG_MENUPROMPT);
217 #else 217 #else
218 printf("Hit any key to stop autoboot: %2d ", bootdelay); 218 printf("Hit any key to stop autoboot: %2d ", bootdelay);
219 #endif 219 #endif
220 220
221 #if defined CONFIG_ZERO_BOOTDELAY_CHECK 221 #if defined CONFIG_ZERO_BOOTDELAY_CHECK
222 /* 222 /*
223 * Check if key already pressed 223 * Check if key already pressed
224 * Don't check if bootdelay < 0 224 * Don't check if bootdelay < 0
225 */ 225 */
226 if (bootdelay >= 0) { 226 if (bootdelay >= 0) {
227 if (tstc()) { /* we got a key press */ 227 if (tstc()) { /* we got a key press */
228 (void) getc(); /* consume input */ 228 (void) getc(); /* consume input */
229 puts ("\b\b\b 0"); 229 puts ("\b\b\b 0");
230 abort = 1; /* don't auto boot */ 230 abort = 1; /* don't auto boot */
231 } 231 }
232 } 232 }
233 #endif 233 #endif
234 234
235 while ((bootdelay > 0) && (!abort)) { 235 while ((bootdelay > 0) && (!abort)) {
236 int i; 236 int i;
237 237
238 --bootdelay; 238 --bootdelay;
239 /* delay 100 * 10ms */ 239 /* delay 100 * 10ms */
240 for (i=0; !abort && i<100; ++i) { 240 for (i=0; !abort && i<100; ++i) {
241 if (tstc()) { /* we got a key press */ 241 if (tstc()) { /* we got a key press */
242 abort = 1; /* don't auto boot */ 242 abort = 1; /* don't auto boot */
243 bootdelay = 0; /* no more delay */ 243 bootdelay = 0; /* no more delay */
244 # ifdef CONFIG_MENUKEY 244 # ifdef CONFIG_MENUKEY
245 menukey = getc(); 245 menukey = getc();
246 # else 246 # else
247 (void) getc(); /* consume input */ 247 (void) getc(); /* consume input */
248 # endif 248 # endif
249 break; 249 break;
250 } 250 }
251 udelay(10000); 251 udelay(10000);
252 } 252 }
253 253
254 printf("\b\b\b%2d ", bootdelay); 254 printf("\b\b\b%2d ", bootdelay);
255 } 255 }
256 256
257 putc('\n'); 257 putc('\n');
258 258
259 #ifdef CONFIG_SILENT_CONSOLE 259 #ifdef CONFIG_SILENT_CONSOLE
260 if (abort) 260 if (abort)
261 gd->flags &= ~GD_FLG_SILENT; 261 gd->flags &= ~GD_FLG_SILENT;
262 #endif 262 #endif
263 263
264 return abort; 264 return abort;
265 } 265 }
266 # endif /* CONFIG_AUTOBOOT_KEYED */ 266 # endif /* CONFIG_AUTOBOOT_KEYED */
267 #endif /* CONFIG_BOOTDELAY >= 0 */ 267 #endif /* CONFIG_BOOTDELAY >= 0 */
268 268
269 /* 269 /*
270 * Return 0 on success, or != 0 on error. 270 * Return 0 on success, or != 0 on error.
271 */ 271 */
272 #ifndef CONFIG_CMD_PXE 272 #ifndef CONFIG_CMD_PXE
273 static inline 273 static inline
274 #endif 274 #endif
275 int run_command2(const char *cmd, int flag) 275 int run_command2(const char *cmd, int flag)
276 { 276 {
277 #ifndef CONFIG_SYS_HUSH_PARSER 277 #ifndef CONFIG_SYS_HUSH_PARSER
278 /* 278 /*
279 * run_command can return 0 or 1 for success, so clean up its result. 279 * run_command can return 0 or 1 for success, so clean up its result.
280 */ 280 */
281 if (run_command(cmd, flag) == -1) 281 if (run_command(cmd, flag) == -1)
282 return 1; 282 return 1;
283 283
284 return 0; 284 return 0;
285 #else 285 #else
286 return parse_string_outer(cmd, 286 return parse_string_outer(cmd,
287 FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); 287 FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
288 #endif 288 #endif
289 } 289 }
290 290
291 /****************************************************************************/ 291 /****************************************************************************/
292 292
293 void main_loop (void) 293 void main_loop (void)
294 { 294 {
295 #ifndef CONFIG_SYS_HUSH_PARSER 295 #ifndef CONFIG_SYS_HUSH_PARSER
296 static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, }; 296 static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
297 int len; 297 int len;
298 int rc = 1; 298 int rc = 1;
299 int flag; 299 int flag;
300 #endif 300 #endif
301 301
302 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) 302 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
303 char *s; 303 char *s;
304 int bootdelay; 304 int bootdelay;
305 #endif 305 #endif
306 #ifdef CONFIG_PREBOOT 306 #ifdef CONFIG_PREBOOT
307 char *p; 307 char *p;
308 #endif 308 #endif
309 #ifdef CONFIG_BOOTCOUNT_LIMIT 309 #ifdef CONFIG_BOOTCOUNT_LIMIT
310 unsigned long bootcount = 0; 310 unsigned long bootcount = 0;
311 unsigned long bootlimit = 0; 311 unsigned long bootlimit = 0;
312 char *bcs; 312 char *bcs;
313 char bcs_set[16]; 313 char bcs_set[16];
314 #endif /* CONFIG_BOOTCOUNT_LIMIT */ 314 #endif /* CONFIG_BOOTCOUNT_LIMIT */
315 315
316 #ifdef CONFIG_BOOTCOUNT_LIMIT 316 #ifdef CONFIG_BOOTCOUNT_LIMIT
317 bootcount = bootcount_load(); 317 bootcount = bootcount_load();
318 bootcount++; 318 bootcount++;
319 bootcount_store (bootcount); 319 bootcount_store (bootcount);
320 sprintf (bcs_set, "%lu", bootcount); 320 sprintf (bcs_set, "%lu", bootcount);
321 setenv ("bootcount", bcs_set); 321 setenv ("bootcount", bcs_set);
322 bcs = getenv ("bootlimit"); 322 bcs = getenv ("bootlimit");
323 bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0; 323 bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0;
324 #endif /* CONFIG_BOOTCOUNT_LIMIT */ 324 #endif /* CONFIG_BOOTCOUNT_LIMIT */
325 325
326 #ifdef CONFIG_MODEM_SUPPORT 326 #ifdef CONFIG_MODEM_SUPPORT
327 debug ("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init); 327 debug ("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init);
328 if (do_mdm_init) { 328 if (do_mdm_init) {
329 char *str = strdup(getenv("mdm_cmd")); 329 char *str = strdup(getenv("mdm_cmd"));
330 setenv ("preboot", str); /* set or delete definition */ 330 setenv ("preboot", str); /* set or delete definition */
331 if (str != NULL) 331 if (str != NULL)
332 free (str); 332 free (str);
333 mdm_init(); /* wait for modem connection */ 333 mdm_init(); /* wait for modem connection */
334 } 334 }
335 #endif /* CONFIG_MODEM_SUPPORT */ 335 #endif /* CONFIG_MODEM_SUPPORT */
336 336
337 #ifdef CONFIG_VERSION_VARIABLE 337 #ifdef CONFIG_VERSION_VARIABLE
338 { 338 {
339 setenv ("ver", version_string); /* set version variable */ 339 setenv ("ver", version_string); /* set version variable */
340 } 340 }
341 #endif /* CONFIG_VERSION_VARIABLE */ 341 #endif /* CONFIG_VERSION_VARIABLE */
342 342
343 #ifdef CONFIG_SYS_HUSH_PARSER 343 #ifdef CONFIG_SYS_HUSH_PARSER
344 u_boot_hush_start (); 344 u_boot_hush_start ();
345 #endif 345 #endif
346 346
347 #if defined(CONFIG_HUSH_INIT_VAR) 347 #if defined(CONFIG_HUSH_INIT_VAR)
348 hush_init_var (); 348 hush_init_var ();
349 #endif 349 #endif
350 350
351 #ifdef CONFIG_PREBOOT 351 #ifdef CONFIG_PREBOOT
352 if ((p = getenv ("preboot")) != NULL) { 352 if ((p = getenv ("preboot")) != NULL) {
353 # ifdef CONFIG_AUTOBOOT_KEYED 353 # ifdef CONFIG_AUTOBOOT_KEYED
354 int prev = disable_ctrlc(1); /* disable Control C checking */ 354 int prev = disable_ctrlc(1); /* disable Control C checking */
355 # endif 355 # endif
356 356
357 run_command2(p, 0); 357 run_command2(p, 0);
358 358
359 # ifdef CONFIG_AUTOBOOT_KEYED 359 # ifdef CONFIG_AUTOBOOT_KEYED
360 disable_ctrlc(prev); /* restore Control C checking */ 360 disable_ctrlc(prev); /* restore Control C checking */
361 # endif 361 # endif
362 } 362 }
363 #endif /* CONFIG_PREBOOT */ 363 #endif /* CONFIG_PREBOOT */
364 364
365 #if defined(CONFIG_UPDATE_TFTP) 365 #if defined(CONFIG_UPDATE_TFTP)
366 update_tftp (0UL); 366 update_tftp (0UL);
367 #endif /* CONFIG_UPDATE_TFTP */ 367 #endif /* CONFIG_UPDATE_TFTP */
368 368
369 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) 369 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
370 s = getenv ("bootdelay"); 370 s = getenv ("bootdelay");
371 bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; 371 bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
372 372
373 debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay); 373 debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
374 374
375 # ifdef CONFIG_BOOT_RETRY_TIME 375 # ifdef CONFIG_BOOT_RETRY_TIME
376 init_cmd_timeout (); 376 init_cmd_timeout ();
377 # endif /* CONFIG_BOOT_RETRY_TIME */ 377 # endif /* CONFIG_BOOT_RETRY_TIME */
378 378
379 #ifdef CONFIG_POST 379 #ifdef CONFIG_POST
380 if (gd->flags & GD_FLG_POSTFAIL) { 380 if (gd->flags & GD_FLG_POSTFAIL) {
381 s = getenv("failbootcmd"); 381 s = getenv("failbootcmd");
382 } 382 }
383 else 383 else
384 #endif /* CONFIG_POST */ 384 #endif /* CONFIG_POST */
385 #ifdef CONFIG_BOOTCOUNT_LIMIT 385 #ifdef CONFIG_BOOTCOUNT_LIMIT
386 if (bootlimit && (bootcount > bootlimit)) { 386 if (bootlimit && (bootcount > bootlimit)) {
387 printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n", 387 printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
388 (unsigned)bootlimit); 388 (unsigned)bootlimit);
389 s = getenv ("altbootcmd"); 389 s = getenv ("altbootcmd");
390 } 390 }
391 else 391 else
392 #endif /* CONFIG_BOOTCOUNT_LIMIT */ 392 #endif /* CONFIG_BOOTCOUNT_LIMIT */
393 s = getenv ("bootcmd"); 393 s = getenv ("bootcmd");
394 394
395 debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>"); 395 debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
396 396
397 if (bootdelay >= 0 && s && !abortboot (bootdelay)) { 397 if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
398 # ifdef CONFIG_AUTOBOOT_KEYED 398 # ifdef CONFIG_AUTOBOOT_KEYED
399 int prev = disable_ctrlc(1); /* disable Control C checking */ 399 int prev = disable_ctrlc(1); /* disable Control C checking */
400 # endif 400 # endif
401 401
402 run_command2(s, 0); 402 run_command2(s, 0);
403 403
404 # ifdef CONFIG_AUTOBOOT_KEYED 404 # ifdef CONFIG_AUTOBOOT_KEYED
405 disable_ctrlc(prev); /* restore Control C checking */ 405 disable_ctrlc(prev); /* restore Control C checking */
406 # endif 406 # endif
407 } 407 }
408 408
409 # ifdef CONFIG_MENUKEY 409 # ifdef CONFIG_MENUKEY
410 if (menukey == CONFIG_MENUKEY) { 410 if (menukey == CONFIG_MENUKEY) {
411 s = getenv("menucmd"); 411 s = getenv("menucmd");
412 if (s) 412 if (s)
413 run_command2(s, 0); 413 run_command2(s, 0);
414 } 414 }
415 #endif /* CONFIG_MENUKEY */ 415 #endif /* CONFIG_MENUKEY */
416 #endif /* CONFIG_BOOTDELAY */ 416 #endif /* CONFIG_BOOTDELAY */
417 417
418 /* 418 /*
419 * Main Loop for Monitor Command Processing 419 * Main Loop for Monitor Command Processing
420 */ 420 */
421 #ifdef CONFIG_SYS_HUSH_PARSER 421 #ifdef CONFIG_SYS_HUSH_PARSER
422 parse_file_outer(); 422 parse_file_outer();
423 /* This point is never reached */ 423 /* This point is never reached */
424 for (;;); 424 for (;;);
425 #else 425 #else
426 for (;;) { 426 for (;;) {
427 #ifdef CONFIG_BOOT_RETRY_TIME 427 #ifdef CONFIG_BOOT_RETRY_TIME
428 if (rc >= 0) { 428 if (rc >= 0) {
429 /* Saw enough of a valid command to 429 /* Saw enough of a valid command to
430 * restart the timeout. 430 * restart the timeout.
431 */ 431 */
432 reset_cmd_timeout(); 432 reset_cmd_timeout();
433 } 433 }
434 #endif 434 #endif
435 len = readline (CONFIG_SYS_PROMPT); 435 len = readline (CONFIG_SYS_PROMPT);
436 436
437 flag = 0; /* assume no special flags for now */ 437 flag = 0; /* assume no special flags for now */
438 if (len > 0) 438 if (len > 0)
439 strcpy (lastcommand, console_buffer); 439 strcpy (lastcommand, console_buffer);
440 else if (len == 0) 440 else if (len == 0)
441 flag |= CMD_FLAG_REPEAT; 441 flag |= CMD_FLAG_REPEAT;
442 #ifdef CONFIG_BOOT_RETRY_TIME 442 #ifdef CONFIG_BOOT_RETRY_TIME
443 else if (len == -2) { 443 else if (len == -2) {
444 /* -2 means timed out, retry autoboot 444 /* -2 means timed out, retry autoboot
445 */ 445 */
446 puts ("\nTimed out waiting for command\n"); 446 puts ("\nTimed out waiting for command\n");
447 # ifdef CONFIG_RESET_TO_RETRY 447 # ifdef CONFIG_RESET_TO_RETRY
448 /* Reinit board to run initialization code again */ 448 /* Reinit board to run initialization code again */
449 do_reset (NULL, 0, 0, NULL); 449 do_reset (NULL, 0, 0, NULL);
450 # else 450 # else
451 return; /* retry autoboot */ 451 return; /* retry autoboot */
452 # endif 452 # endif
453 } 453 }
454 #endif 454 #endif
455 455
456 if (len == -1) 456 if (len == -1)
457 puts ("<INTERRUPT>\n"); 457 puts ("<INTERRUPT>\n");
458 else 458 else
459 rc = run_command (lastcommand, flag); 459 rc = run_command (lastcommand, flag);
460 460
461 if (rc <= 0) { 461 if (rc <= 0) {
462 /* invalid command or not repeatable, forget it */ 462 /* invalid command or not repeatable, forget it */
463 lastcommand[0] = 0; 463 lastcommand[0] = 0;
464 } 464 }
465 } 465 }
466 #endif /*CONFIG_SYS_HUSH_PARSER*/ 466 #endif /*CONFIG_SYS_HUSH_PARSER*/
467 } 467 }
468 468
469 #ifdef CONFIG_BOOT_RETRY_TIME 469 #ifdef CONFIG_BOOT_RETRY_TIME
470 /*************************************************************************** 470 /***************************************************************************
471 * initialize command line timeout 471 * initialize command line timeout
472 */ 472 */
473 void init_cmd_timeout(void) 473 void init_cmd_timeout(void)
474 { 474 {
475 char *s = getenv ("bootretry"); 475 char *s = getenv ("bootretry");
476 476
477 if (s != NULL) 477 if (s != NULL)
478 retry_time = (int)simple_strtol(s, NULL, 10); 478 retry_time = (int)simple_strtol(s, NULL, 10);
479 else 479 else
480 retry_time = CONFIG_BOOT_RETRY_TIME; 480 retry_time = CONFIG_BOOT_RETRY_TIME;
481 481
482 if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN) 482 if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
483 retry_time = CONFIG_BOOT_RETRY_MIN; 483 retry_time = CONFIG_BOOT_RETRY_MIN;
484 } 484 }
485 485
486 /*************************************************************************** 486 /***************************************************************************
487 * reset command line timeout to retry_time seconds 487 * reset command line timeout to retry_time seconds
488 */ 488 */
489 void reset_cmd_timeout(void) 489 void reset_cmd_timeout(void)
490 { 490 {
491 endtime = endtick(retry_time); 491 endtime = endtick(retry_time);
492 } 492 }
493 #endif 493 #endif
494 494
495 #ifdef CONFIG_CMDLINE_EDITING 495 #ifdef CONFIG_CMDLINE_EDITING
496 496
497 /* 497 /*
498 * cmdline-editing related codes from vivi. 498 * cmdline-editing related codes from vivi.
499 * Author: Janghoon Lyu <nandy@mizi.com> 499 * Author: Janghoon Lyu <nandy@mizi.com>
500 */ 500 */
501 501
502 #define putnstr(str,n) do { \ 502 #define putnstr(str,n) do { \
503 printf ("%.*s", (int)n, str); \ 503 printf ("%.*s", (int)n, str); \
504 } while (0) 504 } while (0)
505 505
506 #define CTL_CH(c) ((c) - 'a' + 1) 506 #define CTL_CH(c) ((c) - 'a' + 1)
507 #define CTL_BACKSPACE ('\b') 507 #define CTL_BACKSPACE ('\b')
508 #define DEL ((char)255) 508 #define DEL ((char)255)
509 #define DEL7 ((char)127) 509 #define DEL7 ((char)127)
510 #define CREAD_HIST_CHAR ('!') 510 #define CREAD_HIST_CHAR ('!')
511 511
512 #define getcmd_putch(ch) putc(ch) 512 #define getcmd_putch(ch) putc(ch)
513 #define getcmd_getch() getc() 513 #define getcmd_getch() getc()
514 #define getcmd_cbeep() getcmd_putch('\a') 514 #define getcmd_cbeep() getcmd_putch('\a')
515 515
516 #define HIST_MAX 20 516 #define HIST_MAX 20
517 #define HIST_SIZE CONFIG_SYS_CBSIZE 517 #define HIST_SIZE CONFIG_SYS_CBSIZE
518 518
519 static int hist_max = 0; 519 static int hist_max = 0;
520 static int hist_add_idx = 0; 520 static int hist_add_idx = 0;
521 static int hist_cur = -1; 521 static int hist_cur = -1;
522 unsigned hist_num = 0; 522 unsigned hist_num = 0;
523 523
524 char* hist_list[HIST_MAX]; 524 char* hist_list[HIST_MAX];
525 char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */ 525 char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */
526 526
527 #define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1) 527 #define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1)
528 528
529 static void hist_init(void) 529 static void hist_init(void)
530 { 530 {
531 int i; 531 int i;
532 532
533 hist_max = 0; 533 hist_max = 0;
534 hist_add_idx = 0; 534 hist_add_idx = 0;
535 hist_cur = -1; 535 hist_cur = -1;
536 hist_num = 0; 536 hist_num = 0;
537 537
538 for (i = 0; i < HIST_MAX; i++) { 538 for (i = 0; i < HIST_MAX; i++) {
539 hist_list[i] = hist_lines[i]; 539 hist_list[i] = hist_lines[i];
540 hist_list[i][0] = '\0'; 540 hist_list[i][0] = '\0';
541 } 541 }
542 } 542 }
543 543
544 static void cread_add_to_hist(char *line) 544 static void cread_add_to_hist(char *line)
545 { 545 {
546 strcpy(hist_list[hist_add_idx], line); 546 strcpy(hist_list[hist_add_idx], line);
547 547
548 if (++hist_add_idx >= HIST_MAX) 548 if (++hist_add_idx >= HIST_MAX)
549 hist_add_idx = 0; 549 hist_add_idx = 0;
550 550
551 if (hist_add_idx > hist_max) 551 if (hist_add_idx > hist_max)
552 hist_max = hist_add_idx; 552 hist_max = hist_add_idx;
553 553
554 hist_num++; 554 hist_num++;
555 } 555 }
556 556
557 static char* hist_prev(void) 557 static char* hist_prev(void)
558 { 558 {
559 char *ret; 559 char *ret;
560 int old_cur; 560 int old_cur;
561 561
562 if (hist_cur < 0) 562 if (hist_cur < 0)
563 return NULL; 563 return NULL;
564 564
565 old_cur = hist_cur; 565 old_cur = hist_cur;
566 if (--hist_cur < 0) 566 if (--hist_cur < 0)
567 hist_cur = hist_max; 567 hist_cur = hist_max;
568 568
569 if (hist_cur == hist_add_idx) { 569 if (hist_cur == hist_add_idx) {
570 hist_cur = old_cur; 570 hist_cur = old_cur;
571 ret = NULL; 571 ret = NULL;
572 } else 572 } else
573 ret = hist_list[hist_cur]; 573 ret = hist_list[hist_cur];
574 574
575 return (ret); 575 return (ret);
576 } 576 }
577 577
578 static char* hist_next(void) 578 static char* hist_next(void)
579 { 579 {
580 char *ret; 580 char *ret;
581 581
582 if (hist_cur < 0) 582 if (hist_cur < 0)
583 return NULL; 583 return NULL;
584 584
585 if (hist_cur == hist_add_idx) 585 if (hist_cur == hist_add_idx)
586 return NULL; 586 return NULL;
587 587
588 if (++hist_cur > hist_max) 588 if (++hist_cur > hist_max)
589 hist_cur = 0; 589 hist_cur = 0;
590 590
591 if (hist_cur == hist_add_idx) { 591 if (hist_cur == hist_add_idx) {
592 ret = ""; 592 ret = "";
593 } else 593 } else
594 ret = hist_list[hist_cur]; 594 ret = hist_list[hist_cur];
595 595
596 return (ret); 596 return (ret);
597 } 597 }
598 598
599 #ifndef CONFIG_CMDLINE_EDITING 599 #ifndef CONFIG_CMDLINE_EDITING
600 static void cread_print_hist_list(void) 600 static void cread_print_hist_list(void)
601 { 601 {
602 int i; 602 int i;
603 unsigned long n; 603 unsigned long n;
604 604
605 n = hist_num - hist_max; 605 n = hist_num - hist_max;
606 606
607 i = hist_add_idx + 1; 607 i = hist_add_idx + 1;
608 while (1) { 608 while (1) {
609 if (i > hist_max) 609 if (i > hist_max)
610 i = 0; 610 i = 0;
611 if (i == hist_add_idx) 611 if (i == hist_add_idx)
612 break; 612 break;
613 printf("%s\n", hist_list[i]); 613 printf("%s\n", hist_list[i]);
614 n++; 614 n++;
615 i++; 615 i++;
616 } 616 }
617 } 617 }
618 #endif /* CONFIG_CMDLINE_EDITING */ 618 #endif /* CONFIG_CMDLINE_EDITING */
619 619
620 #define BEGINNING_OF_LINE() { \ 620 #define BEGINNING_OF_LINE() { \
621 while (num) { \ 621 while (num) { \
622 getcmd_putch(CTL_BACKSPACE); \ 622 getcmd_putch(CTL_BACKSPACE); \
623 num--; \ 623 num--; \
624 } \ 624 } \
625 } 625 }
626 626
627 #define ERASE_TO_EOL() { \ 627 #define ERASE_TO_EOL() { \
628 if (num < eol_num) { \ 628 if (num < eol_num) { \
629 printf("%*s", (int)(eol_num - num), ""); \ 629 printf("%*s", (int)(eol_num - num), ""); \
630 do { \ 630 do { \
631 getcmd_putch(CTL_BACKSPACE); \ 631 getcmd_putch(CTL_BACKSPACE); \
632 } while (--eol_num > num); \ 632 } while (--eol_num > num); \
633 } \ 633 } \
634 } 634 }
635 635
636 #define REFRESH_TO_EOL() { \ 636 #define REFRESH_TO_EOL() { \
637 if (num < eol_num) { \ 637 if (num < eol_num) { \
638 wlen = eol_num - num; \ 638 wlen = eol_num - num; \
639 putnstr(buf + num, wlen); \ 639 putnstr(buf + num, wlen); \
640 num = eol_num; \ 640 num = eol_num; \
641 } \ 641 } \
642 } 642 }
643 643
644 static void cread_add_char(char ichar, int insert, unsigned long *num, 644 static void cread_add_char(char ichar, int insert, unsigned long *num,
645 unsigned long *eol_num, char *buf, unsigned long len) 645 unsigned long *eol_num, char *buf, unsigned long len)
646 { 646 {
647 unsigned long wlen; 647 unsigned long wlen;
648 648
649 /* room ??? */ 649 /* room ??? */
650 if (insert || *num == *eol_num) { 650 if (insert || *num == *eol_num) {
651 if (*eol_num > len - 1) { 651 if (*eol_num > len - 1) {
652 getcmd_cbeep(); 652 getcmd_cbeep();
653 return; 653 return;
654 } 654 }
655 (*eol_num)++; 655 (*eol_num)++;
656 } 656 }
657 657
658 if (insert) { 658 if (insert) {
659 wlen = *eol_num - *num; 659 wlen = *eol_num - *num;
660 if (wlen > 1) { 660 if (wlen > 1) {
661 memmove(&buf[*num+1], &buf[*num], wlen-1); 661 memmove(&buf[*num+1], &buf[*num], wlen-1);
662 } 662 }
663 663
664 buf[*num] = ichar; 664 buf[*num] = ichar;
665 putnstr(buf + *num, wlen); 665 putnstr(buf + *num, wlen);
666 (*num)++; 666 (*num)++;
667 while (--wlen) { 667 while (--wlen) {
668 getcmd_putch(CTL_BACKSPACE); 668 getcmd_putch(CTL_BACKSPACE);
669 } 669 }
670 } else { 670 } else {
671 /* echo the character */ 671 /* echo the character */
672 wlen = 1; 672 wlen = 1;
673 buf[*num] = ichar; 673 buf[*num] = ichar;
674 putnstr(buf + *num, wlen); 674 putnstr(buf + *num, wlen);
675 (*num)++; 675 (*num)++;
676 } 676 }
677 } 677 }
678 678
679 static void cread_add_str(char *str, int strsize, int insert, unsigned long *num, 679 static void cread_add_str(char *str, int strsize, int insert, unsigned long *num,
680 unsigned long *eol_num, char *buf, unsigned long len) 680 unsigned long *eol_num, char *buf, unsigned long len)
681 { 681 {
682 while (strsize--) { 682 while (strsize--) {
683 cread_add_char(*str, insert, num, eol_num, buf, len); 683 cread_add_char(*str, insert, num, eol_num, buf, len);
684 str++; 684 str++;
685 } 685 }
686 } 686 }
687 687
688 static int cread_line(const char *const prompt, char *buf, unsigned int *len) 688 static int cread_line(const char *const prompt, char *buf, unsigned int *len,
689 int timeout)
689 { 690 {
690 unsigned long num = 0; 691 unsigned long num = 0;
691 unsigned long eol_num = 0; 692 unsigned long eol_num = 0;
692 unsigned long wlen; 693 unsigned long wlen;
693 char ichar; 694 char ichar;
694 int insert = 1; 695 int insert = 1;
695 int esc_len = 0; 696 int esc_len = 0;
696 char esc_save[8]; 697 char esc_save[8];
697 int init_len = strlen(buf); 698 int init_len = strlen(buf);
699 int first = 1;
698 700
699 if (init_len) 701 if (init_len)
700 cread_add_str(buf, init_len, 1, &num, &eol_num, buf, *len); 702 cread_add_str(buf, init_len, 1, &num, &eol_num, buf, *len);
701 703
702 while (1) { 704 while (1) {
703 #ifdef CONFIG_BOOT_RETRY_TIME 705 #ifdef CONFIG_BOOT_RETRY_TIME
704 while (!tstc()) { /* while no incoming data */ 706 while (!tstc()) { /* while no incoming data */
705 if (retry_time >= 0 && get_ticks() > endtime) 707 if (retry_time >= 0 && get_ticks() > endtime)
706 return (-2); /* timed out */ 708 return (-2); /* timed out */
707 WATCHDOG_RESET(); 709 WATCHDOG_RESET();
708 } 710 }
709 #endif 711 #endif
712 if (first && timeout) {
713 uint64_t etime = endtick(timeout);
710 714
715 while (!tstc()) { /* while no incoming data */
716 if (get_ticks() >= etime)
717 return -2; /* timed out */
718 WATCHDOG_RESET();
719 }
720 first = 0;
721 }
722
711 ichar = getcmd_getch(); 723 ichar = getcmd_getch();
712 724
713 if ((ichar == '\n') || (ichar == '\r')) { 725 if ((ichar == '\n') || (ichar == '\r')) {
714 putc('\n'); 726 putc('\n');
715 break; 727 break;
716 } 728 }
717 729
718 /* 730 /*
719 * handle standard linux xterm esc sequences for arrow key, etc. 731 * handle standard linux xterm esc sequences for arrow key, etc.
720 */ 732 */
721 if (esc_len != 0) { 733 if (esc_len != 0) {
722 if (esc_len == 1) { 734 if (esc_len == 1) {
723 if (ichar == '[') { 735 if (ichar == '[') {
724 esc_save[esc_len] = ichar; 736 esc_save[esc_len] = ichar;
725 esc_len = 2; 737 esc_len = 2;
726 } else { 738 } else {
727 cread_add_str(esc_save, esc_len, insert, 739 cread_add_str(esc_save, esc_len, insert,
728 &num, &eol_num, buf, *len); 740 &num, &eol_num, buf, *len);
729 esc_len = 0; 741 esc_len = 0;
730 } 742 }
731 continue; 743 continue;
732 } 744 }
733 745
734 switch (ichar) { 746 switch (ichar) {
735 747
736 case 'D': /* <- key */ 748 case 'D': /* <- key */
737 ichar = CTL_CH('b'); 749 ichar = CTL_CH('b');
738 esc_len = 0; 750 esc_len = 0;
739 break; 751 break;
740 case 'C': /* -> key */ 752 case 'C': /* -> key */
741 ichar = CTL_CH('f'); 753 ichar = CTL_CH('f');
742 esc_len = 0; 754 esc_len = 0;
743 break; /* pass off to ^F handler */ 755 break; /* pass off to ^F handler */
744 case 'H': /* Home key */ 756 case 'H': /* Home key */
745 ichar = CTL_CH('a'); 757 ichar = CTL_CH('a');
746 esc_len = 0; 758 esc_len = 0;
747 break; /* pass off to ^A handler */ 759 break; /* pass off to ^A handler */
748 case 'A': /* up arrow */ 760 case 'A': /* up arrow */
749 ichar = CTL_CH('p'); 761 ichar = CTL_CH('p');
750 esc_len = 0; 762 esc_len = 0;
751 break; /* pass off to ^P handler */ 763 break; /* pass off to ^P handler */
752 case 'B': /* down arrow */ 764 case 'B': /* down arrow */
753 ichar = CTL_CH('n'); 765 ichar = CTL_CH('n');
754 esc_len = 0; 766 esc_len = 0;
755 break; /* pass off to ^N handler */ 767 break; /* pass off to ^N handler */
756 default: 768 default:
757 esc_save[esc_len++] = ichar; 769 esc_save[esc_len++] = ichar;
758 cread_add_str(esc_save, esc_len, insert, 770 cread_add_str(esc_save, esc_len, insert,
759 &num, &eol_num, buf, *len); 771 &num, &eol_num, buf, *len);
760 esc_len = 0; 772 esc_len = 0;
761 continue; 773 continue;
762 } 774 }
763 } 775 }
764 776
765 switch (ichar) { 777 switch (ichar) {
766 case 0x1b: 778 case 0x1b:
767 if (esc_len == 0) { 779 if (esc_len == 0) {
768 esc_save[esc_len] = ichar; 780 esc_save[esc_len] = ichar;
769 esc_len = 1; 781 esc_len = 1;
770 } else { 782 } else {
771 puts("impossible condition #876\n"); 783 puts("impossible condition #876\n");
772 esc_len = 0; 784 esc_len = 0;
773 } 785 }
774 break; 786 break;
775 787
776 case CTL_CH('a'): 788 case CTL_CH('a'):
777 BEGINNING_OF_LINE(); 789 BEGINNING_OF_LINE();
778 break; 790 break;
779 case CTL_CH('c'): /* ^C - break */ 791 case CTL_CH('c'): /* ^C - break */
780 *buf = '\0'; /* discard input */ 792 *buf = '\0'; /* discard input */
781 return (-1); 793 return (-1);
782 case CTL_CH('f'): 794 case CTL_CH('f'):
783 if (num < eol_num) { 795 if (num < eol_num) {
784 getcmd_putch(buf[num]); 796 getcmd_putch(buf[num]);
785 num++; 797 num++;
786 } 798 }
787 break; 799 break;
788 case CTL_CH('b'): 800 case CTL_CH('b'):
789 if (num) { 801 if (num) {
790 getcmd_putch(CTL_BACKSPACE); 802 getcmd_putch(CTL_BACKSPACE);
791 num--; 803 num--;
792 } 804 }
793 break; 805 break;
794 case CTL_CH('d'): 806 case CTL_CH('d'):
795 if (num < eol_num) { 807 if (num < eol_num) {
796 wlen = eol_num - num - 1; 808 wlen = eol_num - num - 1;
797 if (wlen) { 809 if (wlen) {
798 memmove(&buf[num], &buf[num+1], wlen); 810 memmove(&buf[num], &buf[num+1], wlen);
799 putnstr(buf + num, wlen); 811 putnstr(buf + num, wlen);
800 } 812 }
801 813
802 getcmd_putch(' '); 814 getcmd_putch(' ');
803 do { 815 do {
804 getcmd_putch(CTL_BACKSPACE); 816 getcmd_putch(CTL_BACKSPACE);
805 } while (wlen--); 817 } while (wlen--);
806 eol_num--; 818 eol_num--;
807 } 819 }
808 break; 820 break;
809 case CTL_CH('k'): 821 case CTL_CH('k'):
810 ERASE_TO_EOL(); 822 ERASE_TO_EOL();
811 break; 823 break;
812 case CTL_CH('e'): 824 case CTL_CH('e'):
813 REFRESH_TO_EOL(); 825 REFRESH_TO_EOL();
814 break; 826 break;
815 case CTL_CH('o'): 827 case CTL_CH('o'):
816 insert = !insert; 828 insert = !insert;
817 break; 829 break;
818 case CTL_CH('x'): 830 case CTL_CH('x'):
819 case CTL_CH('u'): 831 case CTL_CH('u'):
820 BEGINNING_OF_LINE(); 832 BEGINNING_OF_LINE();
821 ERASE_TO_EOL(); 833 ERASE_TO_EOL();
822 break; 834 break;
823 case DEL: 835 case DEL:
824 case DEL7: 836 case DEL7:
825 case 8: 837 case 8:
826 if (num) { 838 if (num) {
827 wlen = eol_num - num; 839 wlen = eol_num - num;
828 num--; 840 num--;
829 memmove(&buf[num], &buf[num+1], wlen); 841 memmove(&buf[num], &buf[num+1], wlen);
830 getcmd_putch(CTL_BACKSPACE); 842 getcmd_putch(CTL_BACKSPACE);
831 putnstr(buf + num, wlen); 843 putnstr(buf + num, wlen);
832 getcmd_putch(' '); 844 getcmd_putch(' ');
833 do { 845 do {
834 getcmd_putch(CTL_BACKSPACE); 846 getcmd_putch(CTL_BACKSPACE);
835 } while (wlen--); 847 } while (wlen--);
836 eol_num--; 848 eol_num--;
837 } 849 }
838 break; 850 break;
839 case CTL_CH('p'): 851 case CTL_CH('p'):
840 case CTL_CH('n'): 852 case CTL_CH('n'):
841 { 853 {
842 char * hline; 854 char * hline;
843 855
844 esc_len = 0; 856 esc_len = 0;
845 857
846 if (ichar == CTL_CH('p')) 858 if (ichar == CTL_CH('p'))
847 hline = hist_prev(); 859 hline = hist_prev();
848 else 860 else
849 hline = hist_next(); 861 hline = hist_next();
850 862
851 if (!hline) { 863 if (!hline) {
852 getcmd_cbeep(); 864 getcmd_cbeep();
853 continue; 865 continue;
854 } 866 }
855 867
856 /* nuke the current line */ 868 /* nuke the current line */
857 /* first, go home */ 869 /* first, go home */
858 BEGINNING_OF_LINE(); 870 BEGINNING_OF_LINE();
859 871
860 /* erase to end of line */ 872 /* erase to end of line */
861 ERASE_TO_EOL(); 873 ERASE_TO_EOL();
862 874
863 /* copy new line into place and display */ 875 /* copy new line into place and display */
864 strcpy(buf, hline); 876 strcpy(buf, hline);
865 eol_num = strlen(buf); 877 eol_num = strlen(buf);
866 REFRESH_TO_EOL(); 878 REFRESH_TO_EOL();
867 continue; 879 continue;
868 } 880 }
869 #ifdef CONFIG_AUTO_COMPLETE 881 #ifdef CONFIG_AUTO_COMPLETE
870 case '\t': { 882 case '\t': {
871 int num2, col; 883 int num2, col;
872 884
873 /* do not autocomplete when in the middle */ 885 /* do not autocomplete when in the middle */
874 if (num < eol_num) { 886 if (num < eol_num) {
875 getcmd_cbeep(); 887 getcmd_cbeep();
876 break; 888 break;
877 } 889 }
878 890
879 buf[num] = '\0'; 891 buf[num] = '\0';
880 col = strlen(prompt) + eol_num; 892 col = strlen(prompt) + eol_num;
881 num2 = num; 893 num2 = num;
882 if (cmd_auto_complete(prompt, buf, &num2, &col)) { 894 if (cmd_auto_complete(prompt, buf, &num2, &col)) {
883 col = num2 - num; 895 col = num2 - num;
884 num += col; 896 num += col;
885 eol_num += col; 897 eol_num += col;
886 } 898 }
887 break; 899 break;
888 } 900 }
889 #endif 901 #endif
890 default: 902 default:
891 cread_add_char(ichar, insert, &num, &eol_num, buf, *len); 903 cread_add_char(ichar, insert, &num, &eol_num, buf, *len);
892 break; 904 break;
893 } 905 }
894 } 906 }
895 *len = eol_num; 907 *len = eol_num;
896 buf[eol_num] = '\0'; /* lose the newline */ 908 buf[eol_num] = '\0'; /* lose the newline */
897 909
898 if (buf[0] && buf[0] != CREAD_HIST_CHAR) 910 if (buf[0] && buf[0] != CREAD_HIST_CHAR)
899 cread_add_to_hist(buf); 911 cread_add_to_hist(buf);
900 hist_cur = hist_add_idx; 912 hist_cur = hist_add_idx;
901 913
902 return 0; 914 return 0;
903 } 915 }
904 916
905 #endif /* CONFIG_CMDLINE_EDITING */ 917 #endif /* CONFIG_CMDLINE_EDITING */
906 918
907 /****************************************************************************/ 919 /****************************************************************************/
908 920
909 /* 921 /*
910 * Prompt for input and read a line. 922 * Prompt for input and read a line.
911 * If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0, 923 * If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0,
912 * time out when time goes past endtime (timebase time in ticks). 924 * time out when time goes past endtime (timebase time in ticks).
913 * Return: number of read characters 925 * Return: number of read characters
914 * -1 if break 926 * -1 if break
915 * -2 if timed out 927 * -2 if timed out
916 */ 928 */
917 int readline (const char *const prompt) 929 int readline (const char *const prompt)
918 { 930 {
919 /* 931 /*
920 * If console_buffer isn't 0-length the user will be prompted to modify 932 * If console_buffer isn't 0-length the user will be prompted to modify
921 * it instead of entering it from scratch as desired. 933 * it instead of entering it from scratch as desired.
922 */ 934 */
923 console_buffer[0] = '\0'; 935 console_buffer[0] = '\0';
924 936
925 return readline_into_buffer(prompt, console_buffer); 937 return readline_into_buffer(prompt, console_buffer, 0);
926 } 938 }
927 939
928 940
929 int readline_into_buffer (const char *const prompt, char * buffer) 941 int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
930 { 942 {
931 char *p = buffer; 943 char *p = buffer;
932 #ifdef CONFIG_CMDLINE_EDITING 944 #ifdef CONFIG_CMDLINE_EDITING
933 unsigned int len = CONFIG_SYS_CBSIZE; 945 unsigned int len = CONFIG_SYS_CBSIZE;
934 int rc; 946 int rc;
935 static int initted = 0; 947 static int initted = 0;
936 948
937 /* 949 /*
938 * History uses a global array which is not 950 * History uses a global array which is not
939 * writable until after relocation to RAM. 951 * writable until after relocation to RAM.
940 * Revert to non-history version if still 952 * Revert to non-history version if still
941 * running from flash. 953 * running from flash.
942 */ 954 */
943 if (gd->flags & GD_FLG_RELOC) { 955 if (gd->flags & GD_FLG_RELOC) {
944 if (!initted) { 956 if (!initted) {
945 hist_init(); 957 hist_init();
946 initted = 1; 958 initted = 1;
947 } 959 }
948 960
949 if (prompt) 961 if (prompt)
950 puts (prompt); 962 puts (prompt);
951 963
952 rc = cread_line(prompt, p, &len); 964 rc = cread_line(prompt, p, &len, timeout);
953 return rc < 0 ? rc : len; 965 return rc < 0 ? rc : len;
954 966
955 } else { 967 } else {
956 #endif /* CONFIG_CMDLINE_EDITING */ 968 #endif /* CONFIG_CMDLINE_EDITING */
957 char * p_buf = p; 969 char * p_buf = p;
958 int n = 0; /* buffer index */ 970 int n = 0; /* buffer index */
959 int plen = 0; /* prompt length */ 971 int plen = 0; /* prompt length */
960 int col; /* output column cnt */ 972 int col; /* output column cnt */
961 char c; 973 char c;
962 974
963 /* print prompt */ 975 /* print prompt */
964 if (prompt) { 976 if (prompt) {
965 plen = strlen (prompt); 977 plen = strlen (prompt);
966 puts (prompt); 978 puts (prompt);
967 } 979 }
968 col = plen; 980 col = plen;
969 981
970 for (;;) { 982 for (;;) {
971 #ifdef CONFIG_BOOT_RETRY_TIME 983 #ifdef CONFIG_BOOT_RETRY_TIME
972 while (!tstc()) { /* while no incoming data */ 984 while (!tstc()) { /* while no incoming data */
973 if (retry_time >= 0 && get_ticks() > endtime) 985 if (retry_time >= 0 && get_ticks() > endtime)
974 return (-2); /* timed out */ 986 return (-2); /* timed out */
975 WATCHDOG_RESET(); 987 WATCHDOG_RESET();
976 } 988 }
977 #endif 989 #endif
978 WATCHDOG_RESET(); /* Trigger watchdog, if needed */ 990 WATCHDOG_RESET(); /* Trigger watchdog, if needed */
979 991
980 #ifdef CONFIG_SHOW_ACTIVITY 992 #ifdef CONFIG_SHOW_ACTIVITY
981 while (!tstc()) { 993 while (!tstc()) {
982 extern void show_activity(int arg); 994 extern void show_activity(int arg);
983 show_activity(0); 995 show_activity(0);
984 WATCHDOG_RESET(); 996 WATCHDOG_RESET();
985 } 997 }
986 #endif 998 #endif
987 c = getc(); 999 c = getc();
988 1000
989 /* 1001 /*
990 * Special character handling 1002 * Special character handling
991 */ 1003 */
992 switch (c) { 1004 switch (c) {
993 case '\r': /* Enter */ 1005 case '\r': /* Enter */
994 case '\n': 1006 case '\n':
995 *p = '\0'; 1007 *p = '\0';
996 puts ("\r\n"); 1008 puts ("\r\n");
997 return (p - p_buf); 1009 return (p - p_buf);
998 1010
999 case '\0': /* nul */ 1011 case '\0': /* nul */
1000 continue; 1012 continue;
1001 1013
1002 case 0x03: /* ^C - break */ 1014 case 0x03: /* ^C - break */
1003 p_buf[0] = '\0'; /* discard input */ 1015 p_buf[0] = '\0'; /* discard input */
1004 return (-1); 1016 return (-1);
1005 1017
1006 case 0x15: /* ^U - erase line */ 1018 case 0x15: /* ^U - erase line */
1007 while (col > plen) { 1019 while (col > plen) {
1008 puts (erase_seq); 1020 puts (erase_seq);
1009 --col; 1021 --col;
1010 } 1022 }
1011 p = p_buf; 1023 p = p_buf;
1012 n = 0; 1024 n = 0;
1013 continue; 1025 continue;
1014 1026
1015 case 0x17: /* ^W - erase word */ 1027 case 0x17: /* ^W - erase word */
1016 p=delete_char(p_buf, p, &col, &n, plen); 1028 p=delete_char(p_buf, p, &col, &n, plen);
1017 while ((n > 0) && (*p != ' ')) { 1029 while ((n > 0) && (*p != ' ')) {
1018 p=delete_char(p_buf, p, &col, &n, plen); 1030 p=delete_char(p_buf, p, &col, &n, plen);
1019 } 1031 }
1020 continue; 1032 continue;
1021 1033
1022 case 0x08: /* ^H - backspace */ 1034 case 0x08: /* ^H - backspace */
1023 case 0x7F: /* DEL - backspace */ 1035 case 0x7F: /* DEL - backspace */
1024 p=delete_char(p_buf, p, &col, &n, plen); 1036 p=delete_char(p_buf, p, &col, &n, plen);
1025 continue; 1037 continue;
1026 1038
1027 default: 1039 default:
1028 /* 1040 /*
1029 * Must be a normal character then 1041 * Must be a normal character then
1030 */ 1042 */
1031 if (n < CONFIG_SYS_CBSIZE-2) { 1043 if (n < CONFIG_SYS_CBSIZE-2) {
1032 if (c == '\t') { /* expand TABs */ 1044 if (c == '\t') { /* expand TABs */
1033 #ifdef CONFIG_AUTO_COMPLETE 1045 #ifdef CONFIG_AUTO_COMPLETE
1034 /* if auto completion triggered just continue */ 1046 /* if auto completion triggered just continue */
1035 *p = '\0'; 1047 *p = '\0';
1036 if (cmd_auto_complete(prompt, console_buffer, &n, &col)) { 1048 if (cmd_auto_complete(prompt, console_buffer, &n, &col)) {
1037 p = p_buf + n; /* reset */ 1049 p = p_buf + n; /* reset */
1038 continue; 1050 continue;
1039 } 1051 }
1040 #endif 1052 #endif
1041 puts (tab_seq+(col&07)); 1053 puts (tab_seq+(col&07));
1042 col += 8 - (col&07); 1054 col += 8 - (col&07);
1043 } else { 1055 } else {
1044 ++col; /* echo input */ 1056 ++col; /* echo input */
1045 putc (c); 1057 putc (c);
1046 } 1058 }
1047 *p++ = c; 1059 *p++ = c;
1048 ++n; 1060 ++n;
1049 } else { /* Buffer full */ 1061 } else { /* Buffer full */
1050 putc ('\a'); 1062 putc ('\a');
1051 } 1063 }
1052 } 1064 }
1053 } 1065 }
1054 #ifdef CONFIG_CMDLINE_EDITING 1066 #ifdef CONFIG_CMDLINE_EDITING
1055 } 1067 }
1056 #endif 1068 #endif
1057 } 1069 }
1058 1070
1059 /****************************************************************************/ 1071 /****************************************************************************/
1060 1072
1061 static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen) 1073 static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen)
1062 { 1074 {
1063 char *s; 1075 char *s;
1064 1076
1065 if (*np == 0) { 1077 if (*np == 0) {
1066 return (p); 1078 return (p);
1067 } 1079 }
1068 1080
1069 if (*(--p) == '\t') { /* will retype the whole line */ 1081 if (*(--p) == '\t') { /* will retype the whole line */
1070 while (*colp > plen) { 1082 while (*colp > plen) {
1071 puts (erase_seq); 1083 puts (erase_seq);
1072 (*colp)--; 1084 (*colp)--;
1073 } 1085 }
1074 for (s=buffer; s<p; ++s) { 1086 for (s=buffer; s<p; ++s) {
1075 if (*s == '\t') { 1087 if (*s == '\t') {
1076 puts (tab_seq+((*colp) & 07)); 1088 puts (tab_seq+((*colp) & 07));
1077 *colp += 8 - ((*colp) & 07); 1089 *colp += 8 - ((*colp) & 07);
1078 } else { 1090 } else {
1079 ++(*colp); 1091 ++(*colp);
1080 putc (*s); 1092 putc (*s);
1081 } 1093 }
1082 } 1094 }
1083 } else { 1095 } else {
1084 puts (erase_seq); 1096 puts (erase_seq);
1085 (*colp)--; 1097 (*colp)--;
1086 } 1098 }
1087 (*np)--; 1099 (*np)--;
1088 return (p); 1100 return (p);
1089 } 1101 }
1090 1102
1091 /****************************************************************************/ 1103 /****************************************************************************/
1092 1104
1093 int parse_line (char *line, char *argv[]) 1105 int parse_line (char *line, char *argv[])
1094 { 1106 {
1095 int nargs = 0; 1107 int nargs = 0;
1096 1108
1097 #ifdef DEBUG_PARSER 1109 #ifdef DEBUG_PARSER
1098 printf ("parse_line: \"%s\"\n", line); 1110 printf ("parse_line: \"%s\"\n", line);
1099 #endif 1111 #endif
1100 while (nargs < CONFIG_SYS_MAXARGS) { 1112 while (nargs < CONFIG_SYS_MAXARGS) {
1101 1113
1102 /* skip any white space */ 1114 /* skip any white space */
1103 while (isblank(*line)) 1115 while (isblank(*line))
1104 ++line; 1116 ++line;
1105 1117
1106 if (*line == '\0') { /* end of line, no more args */ 1118 if (*line == '\0') { /* end of line, no more args */
1107 argv[nargs] = NULL; 1119 argv[nargs] = NULL;
1108 #ifdef DEBUG_PARSER 1120 #ifdef DEBUG_PARSER
1109 printf ("parse_line: nargs=%d\n", nargs); 1121 printf ("parse_line: nargs=%d\n", nargs);
1110 #endif 1122 #endif
1111 return (nargs); 1123 return (nargs);
1112 } 1124 }
1113 1125
1114 argv[nargs++] = line; /* begin of argument string */ 1126 argv[nargs++] = line; /* begin of argument string */
1115 1127
1116 /* find end of string */ 1128 /* find end of string */
1117 while (*line && !isblank(*line)) 1129 while (*line && !isblank(*line))
1118 ++line; 1130 ++line;
1119 1131
1120 if (*line == '\0') { /* end of line, no more args */ 1132 if (*line == '\0') { /* end of line, no more args */
1121 argv[nargs] = NULL; 1133 argv[nargs] = NULL;
1122 #ifdef DEBUG_PARSER 1134 #ifdef DEBUG_PARSER
1123 printf ("parse_line: nargs=%d\n", nargs); 1135 printf ("parse_line: nargs=%d\n", nargs);
1124 #endif 1136 #endif
1125 return (nargs); 1137 return (nargs);
1126 } 1138 }
1127 1139
1128 *line++ = '\0'; /* terminate current arg */ 1140 *line++ = '\0'; /* terminate current arg */
1129 } 1141 }
1130 1142
1131 printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS); 1143 printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS);
1132 1144
1133 #ifdef DEBUG_PARSER 1145 #ifdef DEBUG_PARSER
1134 printf ("parse_line: nargs=%d\n", nargs); 1146 printf ("parse_line: nargs=%d\n", nargs);
1135 #endif 1147 #endif
1136 return (nargs); 1148 return (nargs);
1137 } 1149 }
1138 1150
1139 /****************************************************************************/ 1151 /****************************************************************************/
1140 1152
1141 static void process_macros (const char *input, char *output) 1153 static void process_macros (const char *input, char *output)
1142 { 1154 {
1143 char c, prev; 1155 char c, prev;
1144 const char *varname_start = NULL; 1156 const char *varname_start = NULL;
1145 int inputcnt = strlen (input); 1157 int inputcnt = strlen (input);
1146 int outputcnt = CONFIG_SYS_CBSIZE; 1158 int outputcnt = CONFIG_SYS_CBSIZE;
1147 int state = 0; /* 0 = waiting for '$' */ 1159 int state = 0; /* 0 = waiting for '$' */
1148 1160
1149 /* 1 = waiting for '(' or '{' */ 1161 /* 1 = waiting for '(' or '{' */
1150 /* 2 = waiting for ')' or '}' */ 1162 /* 2 = waiting for ')' or '}' */
1151 /* 3 = waiting for ''' */ 1163 /* 3 = waiting for ''' */
1152 #ifdef DEBUG_PARSER 1164 #ifdef DEBUG_PARSER
1153 char *output_start = output; 1165 char *output_start = output;
1154 1166
1155 printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input), 1167 printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input),
1156 input); 1168 input);
1157 #endif 1169 #endif
1158 1170
1159 prev = '\0'; /* previous character */ 1171 prev = '\0'; /* previous character */
1160 1172
1161 while (inputcnt && outputcnt) { 1173 while (inputcnt && outputcnt) {
1162 c = *input++; 1174 c = *input++;
1163 inputcnt--; 1175 inputcnt--;
1164 1176
1165 if (state != 3) { 1177 if (state != 3) {
1166 /* remove one level of escape characters */ 1178 /* remove one level of escape characters */
1167 if ((c == '\\') && (prev != '\\')) { 1179 if ((c == '\\') && (prev != '\\')) {
1168 if (inputcnt-- == 0) 1180 if (inputcnt-- == 0)
1169 break; 1181 break;
1170 prev = c; 1182 prev = c;
1171 c = *input++; 1183 c = *input++;
1172 } 1184 }
1173 } 1185 }
1174 1186
1175 switch (state) { 1187 switch (state) {
1176 case 0: /* Waiting for (unescaped) $ */ 1188 case 0: /* Waiting for (unescaped) $ */
1177 if ((c == '\'') && (prev != '\\')) { 1189 if ((c == '\'') && (prev != '\\')) {
1178 state = 3; 1190 state = 3;
1179 break; 1191 break;
1180 } 1192 }
1181 if ((c == '$') && (prev != '\\')) { 1193 if ((c == '$') && (prev != '\\')) {
1182 state++; 1194 state++;
1183 } else { 1195 } else {
1184 *(output++) = c; 1196 *(output++) = c;
1185 outputcnt--; 1197 outputcnt--;
1186 } 1198 }
1187 break; 1199 break;
1188 case 1: /* Waiting for ( */ 1200 case 1: /* Waiting for ( */
1189 if (c == '(' || c == '{') { 1201 if (c == '(' || c == '{') {
1190 state++; 1202 state++;
1191 varname_start = input; 1203 varname_start = input;
1192 } else { 1204 } else {
1193 state = 0; 1205 state = 0;
1194 *(output++) = '$'; 1206 *(output++) = '$';
1195 outputcnt--; 1207 outputcnt--;
1196 1208
1197 if (outputcnt) { 1209 if (outputcnt) {
1198 *(output++) = c; 1210 *(output++) = c;
1199 outputcnt--; 1211 outputcnt--;
1200 } 1212 }
1201 } 1213 }
1202 break; 1214 break;
1203 case 2: /* Waiting for ) */ 1215 case 2: /* Waiting for ) */
1204 if (c == ')' || c == '}') { 1216 if (c == ')' || c == '}') {
1205 int i; 1217 int i;
1206 char envname[CONFIG_SYS_CBSIZE], *envval; 1218 char envname[CONFIG_SYS_CBSIZE], *envval;
1207 int envcnt = input - varname_start - 1; /* Varname # of chars */ 1219 int envcnt = input - varname_start - 1; /* Varname # of chars */
1208 1220
1209 /* Get the varname */ 1221 /* Get the varname */
1210 for (i = 0; i < envcnt; i++) { 1222 for (i = 0; i < envcnt; i++) {
1211 envname[i] = varname_start[i]; 1223 envname[i] = varname_start[i];
1212 } 1224 }
1213 envname[i] = 0; 1225 envname[i] = 0;
1214 1226
1215 /* Get its value */ 1227 /* Get its value */
1216 envval = getenv (envname); 1228 envval = getenv (envname);
1217 1229
1218 /* Copy into the line if it exists */ 1230 /* Copy into the line if it exists */
1219 if (envval != NULL) 1231 if (envval != NULL)
1220 while ((*envval) && outputcnt) { 1232 while ((*envval) && outputcnt) {
1221 *(output++) = *(envval++); 1233 *(output++) = *(envval++);
1222 outputcnt--; 1234 outputcnt--;
1223 } 1235 }
1224 /* Look for another '$' */ 1236 /* Look for another '$' */
1225 state = 0; 1237 state = 0;
1226 } 1238 }
1227 break; 1239 break;
1228 case 3: /* Waiting for ' */ 1240 case 3: /* Waiting for ' */
1229 if ((c == '\'') && (prev != '\\')) { 1241 if ((c == '\'') && (prev != '\\')) {
1230 state = 0; 1242 state = 0;
1231 } else { 1243 } else {
1232 *(output++) = c; 1244 *(output++) = c;
1233 outputcnt--; 1245 outputcnt--;
1234 } 1246 }
1235 break; 1247 break;
1236 } 1248 }
1237 prev = c; 1249 prev = c;
1238 } 1250 }
1239 1251
1240 if (outputcnt) 1252 if (outputcnt)
1241 *output = 0; 1253 *output = 0;
1242 else 1254 else
1243 *(output - 1) = 0; 1255 *(output - 1) = 0;
1244 1256
1245 #ifdef DEBUG_PARSER 1257 #ifdef DEBUG_PARSER
1246 printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n", 1258 printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
1247 strlen (output_start), output_start); 1259 strlen (output_start), output_start);
1248 #endif 1260 #endif
1249 } 1261 }
1250 1262
1251 /**************************************************************************** 1263 /****************************************************************************
1252 * returns: 1264 * returns:
1253 * 1 - command executed, repeatable 1265 * 1 - command executed, repeatable
1254 * 0 - command executed but not repeatable, interrupted commands are 1266 * 0 - command executed but not repeatable, interrupted commands are
1255 * always considered not repeatable 1267 * always considered not repeatable
1256 * -1 - not executed (unrecognized, bootd recursion or too many args) 1268 * -1 - not executed (unrecognized, bootd recursion or too many args)
1257 * (If cmd is NULL or "" or longer than CONFIG_SYS_CBSIZE-1 it is 1269 * (If cmd is NULL or "" or longer than CONFIG_SYS_CBSIZE-1 it is
1258 * considered unrecognized) 1270 * considered unrecognized)
1259 * 1271 *
1260 * WARNING: 1272 * WARNING:
1261 * 1273 *
1262 * We must create a temporary copy of the command since the command we get 1274 * We must create a temporary copy of the command since the command we get
1263 * may be the result from getenv(), which returns a pointer directly to 1275 * may be the result from getenv(), which returns a pointer directly to
1264 * the environment data, which may change magicly when the command we run 1276 * the environment data, which may change magicly when the command we run
1265 * creates or modifies environment variables (like "bootp" does). 1277 * creates or modifies environment variables (like "bootp" does).
1266 */ 1278 */
1267 1279
1268 int run_command (const char *cmd, int flag) 1280 int run_command (const char *cmd, int flag)
1269 { 1281 {
1270 cmd_tbl_t *cmdtp; 1282 cmd_tbl_t *cmdtp;
1271 char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */ 1283 char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */
1272 char *token; /* start of token in cmdbuf */ 1284 char *token; /* start of token in cmdbuf */
1273 char *sep; /* end of token (separator) in cmdbuf */ 1285 char *sep; /* end of token (separator) in cmdbuf */
1274 char finaltoken[CONFIG_SYS_CBSIZE]; 1286 char finaltoken[CONFIG_SYS_CBSIZE];
1275 char *str = cmdbuf; 1287 char *str = cmdbuf;
1276 char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ 1288 char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
1277 int argc, inquotes; 1289 int argc, inquotes;
1278 int repeatable = 1; 1290 int repeatable = 1;
1279 int rc = 0; 1291 int rc = 0;
1280 1292
1281 #ifdef DEBUG_PARSER 1293 #ifdef DEBUG_PARSER
1282 printf ("[RUN_COMMAND] cmd[%p]=\"", cmd); 1294 printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
1283 puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */ 1295 puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */
1284 puts ("\"\n"); 1296 puts ("\"\n");
1285 #endif 1297 #endif
1286 1298
1287 clear_ctrlc(); /* forget any previous Control C */ 1299 clear_ctrlc(); /* forget any previous Control C */
1288 1300
1289 if (!cmd || !*cmd) { 1301 if (!cmd || !*cmd) {
1290 return -1; /* empty command */ 1302 return -1; /* empty command */
1291 } 1303 }
1292 1304
1293 if (strlen(cmd) >= CONFIG_SYS_CBSIZE) { 1305 if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {
1294 puts ("## Command too long!\n"); 1306 puts ("## Command too long!\n");
1295 return -1; 1307 return -1;
1296 } 1308 }
1297 1309
1298 strcpy (cmdbuf, cmd); 1310 strcpy (cmdbuf, cmd);
1299 1311
1300 /* Process separators and check for invalid 1312 /* Process separators and check for invalid
1301 * repeatable commands 1313 * repeatable commands
1302 */ 1314 */
1303 1315
1304 #ifdef DEBUG_PARSER 1316 #ifdef DEBUG_PARSER
1305 printf ("[PROCESS_SEPARATORS] %s\n", cmd); 1317 printf ("[PROCESS_SEPARATORS] %s\n", cmd);
1306 #endif 1318 #endif
1307 while (*str) { 1319 while (*str) {
1308 1320
1309 /* 1321 /*
1310 * Find separator, or string end 1322 * Find separator, or string end
1311 * Allow simple escape of ';' by writing "\;" 1323 * Allow simple escape of ';' by writing "\;"
1312 */ 1324 */
1313 for (inquotes = 0, sep = str; *sep; sep++) { 1325 for (inquotes = 0, sep = str; *sep; sep++) {
1314 if ((*sep=='\'') && 1326 if ((*sep=='\'') &&
1315 (*(sep-1) != '\\')) 1327 (*(sep-1) != '\\'))
1316 inquotes=!inquotes; 1328 inquotes=!inquotes;
1317 1329
1318 if (!inquotes && 1330 if (!inquotes &&
1319 (*sep == ';') && /* separator */ 1331 (*sep == ';') && /* separator */
1320 ( sep != str) && /* past string start */ 1332 ( sep != str) && /* past string start */
1321 (*(sep-1) != '\\')) /* and NOT escaped */ 1333 (*(sep-1) != '\\')) /* and NOT escaped */
1322 break; 1334 break;
1323 } 1335 }
1324 1336
1325 /* 1337 /*
1326 * Limit the token to data between separators 1338 * Limit the token to data between separators
1327 */ 1339 */
1328 token = str; 1340 token = str;
1329 if (*sep) { 1341 if (*sep) {
1330 str = sep + 1; /* start of command for next pass */ 1342 str = sep + 1; /* start of command for next pass */
1331 *sep = '\0'; 1343 *sep = '\0';
1332 } 1344 }
1333 else 1345 else
1334 str = sep; /* no more commands for next pass */ 1346 str = sep; /* no more commands for next pass */
1335 #ifdef DEBUG_PARSER 1347 #ifdef DEBUG_PARSER
1336 printf ("token: \"%s\"\n", token); 1348 printf ("token: \"%s\"\n", token);
1337 #endif 1349 #endif
1338 1350
1339 /* find macros in this token and replace them */ 1351 /* find macros in this token and replace them */
1340 process_macros (token, finaltoken); 1352 process_macros (token, finaltoken);
1341 1353
1342 /* Extract arguments */ 1354 /* Extract arguments */
1343 if ((argc = parse_line (finaltoken, argv)) == 0) { 1355 if ((argc = parse_line (finaltoken, argv)) == 0) {
1344 rc = -1; /* no command at all */ 1356 rc = -1; /* no command at all */
1345 continue; 1357 continue;
1346 } 1358 }
1347 1359
1348 /* Look up command in command table */ 1360 /* Look up command in command table */
1349 if ((cmdtp = find_cmd(argv[0])) == NULL) { 1361 if ((cmdtp = find_cmd(argv[0])) == NULL) {
1350 printf ("Unknown command '%s' - try 'help'\n", argv[0]); 1362 printf ("Unknown command '%s' - try 'help'\n", argv[0]);
1351 rc = -1; /* give up after bad command */ 1363 rc = -1; /* give up after bad command */
1352 continue; 1364 continue;
1353 } 1365 }
1354 1366
1355 /* found - check max args */ 1367 /* found - check max args */
1356 if (argc > cmdtp->maxargs) { 1368 if (argc > cmdtp->maxargs) {
1357 cmd_usage(cmdtp); 1369 cmd_usage(cmdtp);
1358 rc = -1; 1370 rc = -1;
1359 continue; 1371 continue;
1360 } 1372 }
1361 1373
1362 #if defined(CONFIG_CMD_BOOTD) 1374 #if defined(CONFIG_CMD_BOOTD)
1363 /* avoid "bootd" recursion */ 1375 /* avoid "bootd" recursion */
1364 if (cmdtp->cmd == do_bootd) { 1376 if (cmdtp->cmd == do_bootd) {
1365 #ifdef DEBUG_PARSER 1377 #ifdef DEBUG_PARSER
1366 printf ("[%s]\n", finaltoken); 1378 printf ("[%s]\n", finaltoken);
1367 #endif 1379 #endif
1368 if (flag & CMD_FLAG_BOOTD) { 1380 if (flag & CMD_FLAG_BOOTD) {
1369 puts ("'bootd' recursion detected\n"); 1381 puts ("'bootd' recursion detected\n");
1370 rc = -1; 1382 rc = -1;
1371 continue; 1383 continue;
1372 } else { 1384 } else {
1373 flag |= CMD_FLAG_BOOTD; 1385 flag |= CMD_FLAG_BOOTD;
1374 } 1386 }
1375 } 1387 }
1376 #endif 1388 #endif
1377 1389
1378 /* OK - call function to do the command */ 1390 /* OK - call function to do the command */
1379 if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) { 1391 if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
1380 rc = -1; 1392 rc = -1;
1381 } 1393 }
1382 1394
1383 repeatable &= cmdtp->repeatable; 1395 repeatable &= cmdtp->repeatable;
1384 1396
1385 /* Did the user stop this? */ 1397 /* Did the user stop this? */
1386 if (had_ctrlc ()) 1398 if (had_ctrlc ())
1387 return -1; /* if stopped then not repeatable */ 1399 return -1; /* if stopped then not repeatable */
1388 } 1400 }
1389 1401
1390 return rc ? rc : repeatable; 1402 return rc ? rc : repeatable;
1391 } 1403 }
1392 1404
1393 /****************************************************************************/ 1405 /****************************************************************************/
1394 1406
1395 #if defined(CONFIG_CMD_RUN) 1407 #if defined(CONFIG_CMD_RUN)
1396 int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 1408 int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
1397 { 1409 {
1398 int i; 1410 int i;
1399 1411
1400 if (argc < 2) 1412 if (argc < 2)
1401 return cmd_usage(cmdtp); 1413 return cmd_usage(cmdtp);
1402 1414
1403 for (i=1; i<argc; ++i) { 1415 for (i=1; i<argc; ++i) {
1404 char *arg; 1416 char *arg;
1405 1417
1406 if ((arg = getenv (argv[i])) == NULL) { 1418 if ((arg = getenv (argv[i])) == NULL) {
1407 printf ("## Error: \"%s\" not defined\n", argv[i]); 1419 printf ("## Error: \"%s\" not defined\n", argv[i]);
1408 return 1; 1420 return 1;
1409 } 1421 }
1410 1422
1411 if (run_command2(arg, flag) != 0) 1423 if (run_command2(arg, flag) != 0)
1412 return 1; 1424 return 1;
1413 } 1425 }
1414 return 0; 1426 return 0;
1415 } 1427 }
1416 #endif 1428 #endif
1417 1429
1 /* 1 /*
2 * Copyright 2010-2011 Calxeda, Inc. 2 * Copyright 2010-2011 Calxeda, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option) 6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version. 7 * any later version.
8 * 8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT 9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details. 12 * more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License along with 14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>. 15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include <common.h> 18 #include <common.h>
19 #include <malloc.h> 19 #include <malloc.h>
20 #include <errno.h> 20 #include <errno.h>
21 #include <linux/list.h> 21 #include <linux/list.h>
22 22
23 #include "menu.h" 23 #include "menu.h"
24 24
25 /* 25 /*
26 * Internally, each item in a menu is represented by a struct menu_item. 26 * Internally, each item in a menu is represented by a struct menu_item.
27 * 27 *
28 * These items will be alloc'd and initialized by menu_item_add and destroyed 28 * These items will be alloc'd and initialized by menu_item_add and destroyed
29 * by menu_item_destroy, and the consumer of the interface never sees that 29 * by menu_item_destroy, and the consumer of the interface never sees that
30 * this struct is used at all. 30 * this struct is used at all.
31 */ 31 */
32 struct menu_item { 32 struct menu_item {
33 char *key; 33 char *key;
34 void *data; 34 void *data;
35 struct list_head list; 35 struct list_head list;
36 }; 36 };
37 37
38 /* 38 /*
39 * The menu is composed of a list of items along with settings and callbacks 39 * The menu is composed of a list of items along with settings and callbacks
40 * provided by the user. An incomplete definition of this struct is available 40 * provided by the user. An incomplete definition of this struct is available
41 * in menu.h, but the full definition is here to prevent consumers from 41 * in menu.h, but the full definition is here to prevent consumers from
42 * relying on its contents. 42 * relying on its contents.
43 */ 43 */
44 struct menu { 44 struct menu {
45 struct menu_item *default_item; 45 struct menu_item *default_item;
46 int timeout; 46 int timeout;
47 char *title; 47 char *title;
48 int prompt; 48 int prompt;
49 void (*item_data_print)(void *); 49 void (*item_data_print)(void *);
50 struct list_head items; 50 struct list_head items;
51 }; 51 };
52 52
53 /* 53 /*
54 * An iterator function for menu items. callback will be called for each item 54 * An iterator function for menu items. callback will be called for each item
55 * in m, with m, a pointer to the item, and extra being passed to callback. If 55 * in m, with m, a pointer to the item, and extra being passed to callback. If
56 * callback returns a value other than NULL, iteration stops and the value 56 * callback returns a value other than NULL, iteration stops and the value
57 * return by callback is returned from menu_items_iter. This allows it to be 57 * return by callback is returned from menu_items_iter. This allows it to be
58 * used for search type operations. It is also safe for callback to remove the 58 * used for search type operations. It is also safe for callback to remove the
59 * item from the list of items. 59 * item from the list of items.
60 */ 60 */
61 static inline void *menu_items_iter(struct menu *m, 61 static inline void *menu_items_iter(struct menu *m,
62 void *(*callback)(struct menu *, struct menu_item *, void *), 62 void *(*callback)(struct menu *, struct menu_item *, void *),
63 void *extra) 63 void *extra)
64 { 64 {
65 struct list_head *pos, *n; 65 struct list_head *pos, *n;
66 struct menu_item *item; 66 struct menu_item *item;
67 void *ret; 67 void *ret;
68 68
69 list_for_each_safe(pos, n, &m->items) { 69 list_for_each_safe(pos, n, &m->items) {
70 item = list_entry(pos, struct menu_item, list); 70 item = list_entry(pos, struct menu_item, list);
71 71
72 ret = callback(m, item, extra); 72 ret = callback(m, item, extra);
73 73
74 if (ret) 74 if (ret)
75 return ret; 75 return ret;
76 } 76 }
77 77
78 return NULL; 78 return NULL;
79 } 79 }
80 80
81 /* 81 /*
82 * Print a menu_item. If the consumer provided an item_data_print function 82 * Print a menu_item. If the consumer provided an item_data_print function
83 * when creating the menu, call it with a pointer to the item's private data. 83 * when creating the menu, call it with a pointer to the item's private data.
84 * Otherwise, print the key of the item. 84 * Otherwise, print the key of the item.
85 */ 85 */
86 static inline void *menu_item_print(struct menu *m, 86 static inline void *menu_item_print(struct menu *m,
87 struct menu_item *item, 87 struct menu_item *item,
88 void *extra) 88 void *extra)
89 { 89 {
90 if (!m->item_data_print) { 90 if (!m->item_data_print) {
91 puts(item->key); 91 puts(item->key);
92 putc('\n'); 92 putc('\n');
93 } else { 93 } else {
94 m->item_data_print(item->data); 94 m->item_data_print(item->data);
95 } 95 }
96 96
97 return NULL; 97 return NULL;
98 } 98 }
99 99
100 /* 100 /*
101 * Free the memory used by a menu item. This includes the memory used by its 101 * Free the memory used by a menu item. This includes the memory used by its
102 * key. 102 * key.
103 */ 103 */
104 static inline void *menu_item_destroy(struct menu *m, 104 static inline void *menu_item_destroy(struct menu *m,
105 struct menu_item *item, 105 struct menu_item *item,
106 void *extra) 106 void *extra)
107 { 107 {
108 if (item->key) 108 if (item->key)
109 free(item->key); 109 free(item->key);
110 110
111 free(item); 111 free(item);
112 112
113 return NULL; 113 return NULL;
114 } 114 }
115 115
116 /* 116 /*
117 * Display a menu so the user can make a choice of an item. First display its 117 * Display a menu so the user can make a choice of an item. First display its
118 * title, if any, and then each item in the menu. 118 * title, if any, and then each item in the menu.
119 */ 119 */
120 static inline void menu_display(struct menu *m) 120 static inline void menu_display(struct menu *m)
121 { 121 {
122 if (m->title) { 122 if (m->title) {
123 puts(m->title); 123 puts(m->title);
124 putc('\n'); 124 putc('\n');
125 } 125 }
126 126
127 menu_items_iter(m, menu_item_print, NULL); 127 menu_items_iter(m, menu_item_print, NULL);
128 } 128 }
129 129
130 /* 130 /*
131 * Check if an item's key matches a provided string, pointed to by extra. If 131 * Check if an item's key matches a provided string, pointed to by extra. If
132 * extra is NULL, an item with a NULL key will match. Otherwise, the item's 132 * extra is NULL, an item with a NULL key will match. Otherwise, the item's
133 * key has to match according to strcmp. 133 * key has to match according to strcmp.
134 * 134 *
135 * This is called via menu_items_iter, so it returns a pointer to the item if 135 * This is called via menu_items_iter, so it returns a pointer to the item if
136 * the key matches, and returns NULL otherwise. 136 * the key matches, and returns NULL otherwise.
137 */ 137 */
138 static inline void *menu_item_key_match(struct menu *m, 138 static inline void *menu_item_key_match(struct menu *m,
139 struct menu_item *item, void *extra) 139 struct menu_item *item, void *extra)
140 { 140 {
141 char *item_key = extra; 141 char *item_key = extra;
142 142
143 if (!item_key || !item->key) { 143 if (!item_key || !item->key) {
144 if (item_key == item->key) 144 if (item_key == item->key)
145 return item; 145 return item;
146 146
147 return NULL; 147 return NULL;
148 } 148 }
149 149
150 if (strcmp(item->key, item_key) == 0) 150 if (strcmp(item->key, item_key) == 0)
151 return item; 151 return item;
152 152
153 return NULL; 153 return NULL;
154 } 154 }
155 155
156 /* 156 /*
157 * Find the first item with a key matching item_key, if any exists. 157 * Find the first item with a key matching item_key, if any exists.
158 */ 158 */
159 static inline struct menu_item *menu_item_by_key(struct menu *m, 159 static inline struct menu_item *menu_item_by_key(struct menu *m,
160 char *item_key) 160 char *item_key)
161 { 161 {
162 return menu_items_iter(m, menu_item_key_match, item_key); 162 return menu_items_iter(m, menu_item_key_match, item_key);
163 } 163 }
164 164
165 /* 165 /*
166 * Wait for the user to hit a key according to the timeout set for the menu. 166 * Wait for the user to hit a key according to the timeout set for the menu.
167 * Returns 1 if the user hit a key, or 0 if the timeout expired. 167 * Returns 1 if the user hit a key, or 0 if the timeout expired.
168 */ 168 */
169 static inline int menu_interrupted(struct menu *m) 169 static inline int menu_interrupted(struct menu *m)
170 { 170 {
171 if (!m->timeout) 171 if (!m->timeout)
172 return 0; 172 return 0;
173 173
174 if (abortboot(m->timeout/10)) 174 if (abortboot(m->timeout/10))
175 return 1; 175 return 1;
176 176
177 return 0; 177 return 0;
178 } 178 }
179 179
180 /* 180 /*
181 * Checks whether or not the default menu item should be used without 181 * Checks whether or not the default menu item should be used without
182 * prompting for a user choice. If the menu is set to always prompt, or the 182 * prompting for a user choice. If the menu is set to always prompt, or the
183 * user hits a key during the timeout period, return 0. Otherwise, return 1 to 183 * user hits a key during the timeout period, return 0. Otherwise, return 1 to
184 * indicate we should use the default menu item. 184 * indicate we should use the default menu item.
185 */ 185 */
186 static inline int menu_use_default(struct menu *m) 186 static inline int menu_use_default(struct menu *m)
187 { 187 {
188 return !m->prompt && !menu_interrupted(m); 188 return !m->prompt && !menu_interrupted(m);
189 } 189 }
190 190
191 /* 191 /*
192 * Set *choice to point to the default item's data, if any default item was 192 * Set *choice to point to the default item's data, if any default item was
193 * set, and returns 1. If no default item was set, returns -ENOENT. 193 * set, and returns 1. If no default item was set, returns -ENOENT.
194 */ 194 */
195 static inline int menu_default_choice(struct menu *m, void **choice) 195 static inline int menu_default_choice(struct menu *m, void **choice)
196 { 196 {
197 if (m->default_item) { 197 if (m->default_item) {
198 *choice = m->default_item->data; 198 *choice = m->default_item->data;
199 return 1; 199 return 1;
200 } 200 }
201 201
202 return -ENOENT; 202 return -ENOENT;
203 } 203 }
204 204
205 /* 205 /*
206 * Displays the menu and asks the user to choose an item. *choice will point 206 * Displays the menu and asks the user to choose an item. *choice will point
207 * to the private data of the item the user chooses. The user makes a choice 207 * to the private data of the item the user chooses. The user makes a choice
208 * by inputting a string matching the key of an item. Invalid choices will 208 * by inputting a string matching the key of an item. Invalid choices will
209 * cause the user to be prompted again, repeatedly, until the user makes a 209 * cause the user to be prompted again, repeatedly, until the user makes a
210 * valid choice. The user can exit the menu without making a choice via ^c. 210 * valid choice. The user can exit the menu without making a choice via ^c.
211 * 211 *
212 * Returns 1 if the user made a choice, or -EINTR if they bail via ^c. 212 * Returns 1 if the user made a choice, or -EINTR if they bail via ^c.
213 */ 213 */
214 static inline int menu_interactive_choice(struct menu *m, void **choice) 214 static inline int menu_interactive_choice(struct menu *m, void **choice)
215 { 215 {
216 char cbuf[CONFIG_SYS_CBSIZE]; 216 char cbuf[CONFIG_SYS_CBSIZE];
217 struct menu_item *choice_item = NULL; 217 struct menu_item *choice_item = NULL;
218 int readret; 218 int readret;
219 219
220 while (!choice_item) { 220 while (!choice_item) {
221 cbuf[0] = '\0'; 221 cbuf[0] = '\0';
222 222
223 menu_display(m); 223 menu_display(m);
224 224
225 readret = readline_into_buffer("Enter choice: ", cbuf); 225 readret = readline_into_buffer("Enter choice: ", cbuf,
226 m->timeout);
226 227
227 if (readret >= 0) { 228 if (readret >= 0) {
228 choice_item = menu_item_by_key(m, cbuf); 229 choice_item = menu_item_by_key(m, cbuf);
229 230
230 if (!choice_item) 231 if (!choice_item)
231 printf("%s not found\n", cbuf); 232 printf("%s not found\n", cbuf);
232 } else { 233 } else {
233 puts("^C\n"); 234 puts("^C\n");
234 return -EINTR; 235 return -EINTR;
235 } 236 }
236 } 237 }
237 238
238 *choice = choice_item->data; 239 *choice = choice_item->data;
239 240
240 return 1; 241 return 1;
241 } 242 }
242 243
243 /* 244 /*
244 * menu_default_set() - Sets the default choice for the menu. This is safe to 245 * menu_default_set() - Sets the default choice for the menu. This is safe to
245 * call more than once on a menu. 246 * call more than once on a menu.
246 * 247 *
247 * m - Points to a menu created by menu_create(). 248 * m - Points to a menu created by menu_create().
248 * 249 *
249 * item_key - Points to a string that, when compared using strcmp, matches the 250 * item_key - Points to a string that, when compared using strcmp, matches the
250 * key for an existing item in the menu. 251 * key for an existing item in the menu.
251 * 252 *
252 * Returns 1 if successful, -EINVAL if m is NULL, or -ENOENT if no item with a 253 * Returns 1 if successful, -EINVAL if m is NULL, or -ENOENT if no item with a
253 * key matching item_key is found. 254 * key matching item_key is found.
254 */ 255 */
255 int menu_default_set(struct menu *m, char *item_key) 256 int menu_default_set(struct menu *m, char *item_key)
256 { 257 {
257 struct menu_item *item; 258 struct menu_item *item;
258 259
259 if (!m) 260 if (!m)
260 return -EINVAL; 261 return -EINVAL;
261 262
262 item = menu_item_by_key(m, item_key); 263 item = menu_item_by_key(m, item_key);
263 264
264 if (!item) 265 if (!item)
265 return -ENOENT; 266 return -ENOENT;
266 267
267 m->default_item = item; 268 m->default_item = item;
268 269
269 return 1; 270 return 1;
270 } 271 }
271 272
272 /* 273 /*
273 * menu_get_choice() - Returns the user's selected menu entry, or the default 274 * menu_get_choice() - Returns the user's selected menu entry, or the default
274 * if the menu is set to not prompt or the timeout expires. This is safe to 275 * if the menu is set to not prompt or the timeout expires. This is safe to
275 * call more than once. 276 * call more than once.
276 * 277 *
277 * m - Points to a menu created by menu_create(). 278 * m - Points to a menu created by menu_create().
278 * 279 *
279 * choice - Points to a location that will store a pointer to the selected 280 * choice - Points to a location that will store a pointer to the selected
280 * menu item. If no item is selected or there is an error, no value will be 281 * menu item. If no item is selected or there is an error, no value will be
281 * written at the location it points to. 282 * written at the location it points to.
282 * 283 *
283 * Returns 1 if successful, -EINVAL if m or choice is NULL, -ENOENT if no 284 * Returns 1 if successful, -EINVAL if m or choice is NULL, -ENOENT if no
284 * default has been set and the menu is set to not prompt or the timeout 285 * default has been set and the menu is set to not prompt or the timeout
285 * expires, or -EINTR if the user exits the menu via ^c. 286 * expires, or -EINTR if the user exits the menu via ^c.
286 */ 287 */
287 int menu_get_choice(struct menu *m, void **choice) 288 int menu_get_choice(struct menu *m, void **choice)
288 { 289 {
289 if (!m || !choice) 290 if (!m || !choice)
290 return -EINVAL; 291 return -EINVAL;
291 292
292 if (menu_use_default(m)) 293 if (menu_use_default(m))
293 return menu_default_choice(m, choice); 294 return menu_default_choice(m, choice);
294 295
295 return menu_interactive_choice(m, choice); 296 return menu_interactive_choice(m, choice);
296 } 297 }
297 298
298 /* 299 /*
299 * menu_item_add() - Adds or replaces a menu item. Note that this replaces the 300 * menu_item_add() - Adds or replaces a menu item. Note that this replaces the
300 * data of an item if it already exists, but doesn't change the order of the 301 * data of an item if it already exists, but doesn't change the order of the
301 * item. 302 * item.
302 * 303 *
303 * m - Points to a menu created by menu_create(). 304 * m - Points to a menu created by menu_create().
304 * 305 *
305 * item_key - Points to a string that will uniquely identify the item. The 306 * item_key - Points to a string that will uniquely identify the item. The
306 * string will be copied to internal storage, and is safe to discard after 307 * string will be copied to internal storage, and is safe to discard after
307 * passing to menu_item_add. 308 * passing to menu_item_add.
308 * 309 *
309 * item_data - An opaque pointer associated with an item. It is never 310 * item_data - An opaque pointer associated with an item. It is never
310 * dereferenced internally, but will be passed to the item_data_print, and 311 * dereferenced internally, but will be passed to the item_data_print, and
311 * will be returned from menu_get_choice if the menu item is selected. 312 * will be returned from menu_get_choice if the menu item is selected.
312 * 313 *
313 * Returns 1 if successful, -EINVAL if m is NULL, or -ENOMEM if there is 314 * Returns 1 if successful, -EINVAL if m is NULL, or -ENOMEM if there is
314 * insufficient memory to add the menu item. 315 * insufficient memory to add the menu item.
315 */ 316 */
316 int menu_item_add(struct menu *m, char *item_key, void *item_data) 317 int menu_item_add(struct menu *m, char *item_key, void *item_data)
317 { 318 {
318 struct menu_item *item; 319 struct menu_item *item;
319 320
320 if (!m) 321 if (!m)
321 return -EINVAL; 322 return -EINVAL;
322 323
323 item = menu_item_by_key(m, item_key); 324 item = menu_item_by_key(m, item_key);
324 325
325 if (item) { 326 if (item) {
326 item->data = item_data; 327 item->data = item_data;
327 return 1; 328 return 1;
328 } 329 }
329 330
330 item = malloc(sizeof *item); 331 item = malloc(sizeof *item);
331 if (!item) 332 if (!item)
332 return -ENOMEM; 333 return -ENOMEM;
333 334
334 item->key = strdup(item_key); 335 item->key = strdup(item_key);
335 336
336 if (!item->key) { 337 if (!item->key) {
337 free(item); 338 free(item);
338 return -ENOMEM; 339 return -ENOMEM;
339 } 340 }
340 341
341 item->data = item_data; 342 item->data = item_data;
342 343
343 list_add_tail(&item->list, &m->items); 344 list_add_tail(&item->list, &m->items);
344 345
345 return 1; 346 return 1;
346 } 347 }
347 348
348 /* 349 /*
349 * menu_create() - Creates a menu handle with default settings 350 * menu_create() - Creates a menu handle with default settings
350 * 351 *
351 * title - If not NULL, points to a string that will be displayed before the 352 * title - If not NULL, points to a string that will be displayed before the
352 * list of menu items. It will be copied to internal storage, and is safe to 353 * list of menu items. It will be copied to internal storage, and is safe to
353 * discard after passing to menu_create(). 354 * discard after passing to menu_create().
354 * 355 *
355 * timeout - A delay in seconds to wait for user input. If 0, timeout is 356 * timeout - A delay in seconds to wait for user input. If 0, timeout is
356 * disabled, and the default choice will be returned unless prompt is 1. 357 * disabled, and the default choice will be returned unless prompt is 1.
357 * 358 *
358 * prompt - If 0, don't ask for user input unless there is an interrupted 359 * prompt - If 0, don't ask for user input unless there is an interrupted
359 * timeout. If 1, the user will be prompted for input regardless of the value 360 * timeout. If 1, the user will be prompted for input regardless of the value
360 * of timeout. 361 * of timeout.
361 * 362 *
362 * item_data_print - If not NULL, will be called for each item when the menu 363 * item_data_print - If not NULL, will be called for each item when the menu
363 * is displayed, with the pointer to the item's data passed as the argument. 364 * is displayed, with the pointer to the item's data passed as the argument.
364 * If NULL, each item's key will be printed instead. Since an item's key is 365 * If NULL, each item's key will be printed instead. Since an item's key is
365 * what must be entered to select an item, the item_data_print function should 366 * what must be entered to select an item, the item_data_print function should
366 * make it obvious what the key for each entry is. 367 * make it obvious what the key for each entry is.
367 * 368 *
368 * Returns a pointer to the menu if successful, or NULL if there is 369 * Returns a pointer to the menu if successful, or NULL if there is
369 * insufficient memory available to create the menu. 370 * insufficient memory available to create the menu.
370 */ 371 */
371 struct menu *menu_create(char *title, int timeout, int prompt, 372 struct menu *menu_create(char *title, int timeout, int prompt,
372 void (*item_data_print)(void *)) 373 void (*item_data_print)(void *))
373 { 374 {
374 struct menu *m; 375 struct menu *m;
375 376
376 m = malloc(sizeof *m); 377 m = malloc(sizeof *m);
377 378
378 if (!m) 379 if (!m)
379 return NULL; 380 return NULL;
380 381
381 m->default_item = NULL; 382 m->default_item = NULL;
382 m->prompt = prompt; 383 m->prompt = prompt;
383 m->timeout = timeout; 384 m->timeout = timeout;
384 m->item_data_print = item_data_print; 385 m->item_data_print = item_data_print;
385 386
386 if (title) { 387 if (title) {
387 m->title = strdup(title); 388 m->title = strdup(title);
388 if (!m->title) { 389 if (!m->title) {
389 free(m); 390 free(m);
390 return NULL; 391 return NULL;
391 } 392 }
392 } else 393 } else
393 m->title = NULL; 394 m->title = NULL;
394 395
395 396
396 INIT_LIST_HEAD(&m->items); 397 INIT_LIST_HEAD(&m->items);
397 398
398 return m; 399 return m;
399 } 400 }
400 401
401 /* 402 /*
402 * menu_destroy() - frees the memory used by a menu and its items. 403 * menu_destroy() - frees the memory used by a menu and its items.
403 * 404 *
404 * m - Points to a menu created by menu_create(). 405 * m - Points to a menu created by menu_create().
405 * 406 *
406 * Returns 1 if successful, or -EINVAL if m is NULL. 407 * Returns 1 if successful, or -EINVAL if m is NULL.
407 */ 408 */
408 int menu_destroy(struct menu *m) 409 int menu_destroy(struct menu *m)
409 { 410 {
410 if (!m) 411 if (!m)
411 return -EINVAL; 412 return -EINVAL;
412 413
413 menu_items_iter(m, menu_item_destroy, NULL); 414 menu_items_iter(m, menu_item_destroy, NULL);
414 415
415 if (m->title) 416 if (m->title)
416 free(m->title); 417 free(m->title);
417 418
418 free(m); 419 free(m);
419 420
420 return 1; 421 return 1;
421 } 422 }
422 423
1 /* 1 /*
2 * (C) Copyright 2000-2009 2 * (C) Copyright 2000-2009
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 * 4 *
5 * See file CREDITS for list of people who contributed to this 5 * See file CREDITS for list of people who contributed to this
6 * project. 6 * project.
7 * 7 *
8 * This program is free software; you can redistribute it and/or 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 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of 10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version. 11 * the License, or (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 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 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA 21 * MA 02111-1307 USA
22 */ 22 */
23 23
24 #ifndef __COMMON_H_ 24 #ifndef __COMMON_H_
25 #define __COMMON_H_ 1 25 #define __COMMON_H_ 1
26 26
27 #undef _LINUX_CONFIG_H 27 #undef _LINUX_CONFIG_H
28 #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ 28 #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
29 29
30 #ifndef __ASSEMBLY__ /* put C only stuff in this section */ 30 #ifndef __ASSEMBLY__ /* put C only stuff in this section */
31 31
32 typedef unsigned char uchar; 32 typedef unsigned char uchar;
33 typedef volatile unsigned long vu_long; 33 typedef volatile unsigned long vu_long;
34 typedef volatile unsigned short vu_short; 34 typedef volatile unsigned short vu_short;
35 typedef volatile unsigned char vu_char; 35 typedef volatile unsigned char vu_char;
36 36
37 #include <config.h> 37 #include <config.h>
38 #include <asm-offsets.h> 38 #include <asm-offsets.h>
39 #include <linux/bitops.h> 39 #include <linux/bitops.h>
40 #include <linux/types.h> 40 #include <linux/types.h>
41 #include <linux/string.h> 41 #include <linux/string.h>
42 #include <asm/ptrace.h> 42 #include <asm/ptrace.h>
43 #include <stdarg.h> 43 #include <stdarg.h>
44 #if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000)) 44 #if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000))
45 #include <pci.h> 45 #include <pci.h>
46 #endif 46 #endif
47 #if defined(CONFIG_8xx) 47 #if defined(CONFIG_8xx)
48 #include <asm/8xx_immap.h> 48 #include <asm/8xx_immap.h>
49 #if defined(CONFIG_MPC852) || defined(CONFIG_MPC852T) || \ 49 #if defined(CONFIG_MPC852) || defined(CONFIG_MPC852T) || \
50 defined(CONFIG_MPC859) || defined(CONFIG_MPC859T) || \ 50 defined(CONFIG_MPC859) || defined(CONFIG_MPC859T) || \
51 defined(CONFIG_MPC859DSL) || \ 51 defined(CONFIG_MPC859DSL) || \
52 defined(CONFIG_MPC866) || defined(CONFIG_MPC866T) || \ 52 defined(CONFIG_MPC866) || defined(CONFIG_MPC866T) || \
53 defined(CONFIG_MPC866P) 53 defined(CONFIG_MPC866P)
54 # define CONFIG_MPC866_FAMILY 1 54 # define CONFIG_MPC866_FAMILY 1
55 #elif defined(CONFIG_MPC870) \ 55 #elif defined(CONFIG_MPC870) \
56 || defined(CONFIG_MPC875) \ 56 || defined(CONFIG_MPC875) \
57 || defined(CONFIG_MPC880) \ 57 || defined(CONFIG_MPC880) \
58 || defined(CONFIG_MPC885) 58 || defined(CONFIG_MPC885)
59 # define CONFIG_MPC885_FAMILY 1 59 # define CONFIG_MPC885_FAMILY 1
60 #endif 60 #endif
61 #if defined(CONFIG_MPC860) \ 61 #if defined(CONFIG_MPC860) \
62 || defined(CONFIG_MPC860T) \ 62 || defined(CONFIG_MPC860T) \
63 || defined(CONFIG_MPC866_FAMILY) \ 63 || defined(CONFIG_MPC866_FAMILY) \
64 || defined(CONFIG_MPC885_FAMILY) 64 || defined(CONFIG_MPC885_FAMILY)
65 # define CONFIG_MPC86x 1 65 # define CONFIG_MPC86x 1
66 #endif 66 #endif
67 #elif defined(CONFIG_5xx) 67 #elif defined(CONFIG_5xx)
68 #include <asm/5xx_immap.h> 68 #include <asm/5xx_immap.h>
69 #elif defined(CONFIG_MPC5xxx) 69 #elif defined(CONFIG_MPC5xxx)
70 #include <mpc5xxx.h> 70 #include <mpc5xxx.h>
71 #elif defined(CONFIG_MPC512X) 71 #elif defined(CONFIG_MPC512X)
72 #include <asm/immap_512x.h> 72 #include <asm/immap_512x.h>
73 #elif defined(CONFIG_MPC8220) 73 #elif defined(CONFIG_MPC8220)
74 #include <asm/immap_8220.h> 74 #include <asm/immap_8220.h>
75 #elif defined(CONFIG_8260) 75 #elif defined(CONFIG_8260)
76 #if defined(CONFIG_MPC8247) \ 76 #if defined(CONFIG_MPC8247) \
77 || defined(CONFIG_MPC8248) \ 77 || defined(CONFIG_MPC8248) \
78 || defined(CONFIG_MPC8271) \ 78 || defined(CONFIG_MPC8271) \
79 || defined(CONFIG_MPC8272) 79 || defined(CONFIG_MPC8272)
80 #define CONFIG_MPC8272_FAMILY 1 80 #define CONFIG_MPC8272_FAMILY 1
81 #endif 81 #endif
82 #if defined(CONFIG_MPC8272_FAMILY) 82 #if defined(CONFIG_MPC8272_FAMILY)
83 #define CONFIG_MPC8260 1 83 #define CONFIG_MPC8260 1
84 #endif 84 #endif
85 #include <asm/immap_8260.h> 85 #include <asm/immap_8260.h>
86 #endif 86 #endif
87 #ifdef CONFIG_MPC86xx 87 #ifdef CONFIG_MPC86xx
88 #include <mpc86xx.h> 88 #include <mpc86xx.h>
89 #include <asm/immap_86xx.h> 89 #include <asm/immap_86xx.h>
90 #endif 90 #endif
91 #ifdef CONFIG_MPC85xx 91 #ifdef CONFIG_MPC85xx
92 #include <mpc85xx.h> 92 #include <mpc85xx.h>
93 #include <asm/immap_85xx.h> 93 #include <asm/immap_85xx.h>
94 #endif 94 #endif
95 #ifdef CONFIG_MPC83xx 95 #ifdef CONFIG_MPC83xx
96 #include <mpc83xx.h> 96 #include <mpc83xx.h>
97 #include <asm/immap_83xx.h> 97 #include <asm/immap_83xx.h>
98 #endif 98 #endif
99 #ifdef CONFIG_4xx 99 #ifdef CONFIG_4xx
100 #include <asm/ppc4xx.h> 100 #include <asm/ppc4xx.h>
101 #endif 101 #endif
102 #ifdef CONFIG_HYMOD 102 #ifdef CONFIG_HYMOD
103 #include <board/hymod/hymod.h> 103 #include <board/hymod/hymod.h>
104 #endif 104 #endif
105 #ifdef CONFIG_ARM 105 #ifdef CONFIG_ARM
106 #define asmlinkage /* nothing */ 106 #define asmlinkage /* nothing */
107 #endif 107 #endif
108 #ifdef CONFIG_BLACKFIN 108 #ifdef CONFIG_BLACKFIN
109 #include <asm/blackfin.h> 109 #include <asm/blackfin.h>
110 #endif 110 #endif
111 #ifdef CONFIG_SOC_DA8XX 111 #ifdef CONFIG_SOC_DA8XX
112 #include <asm/arch/hardware.h> 112 #include <asm/arch/hardware.h>
113 #endif 113 #endif
114 114
115 #include <part.h> 115 #include <part.h>
116 #include <flash.h> 116 #include <flash.h>
117 #include <image.h> 117 #include <image.h>
118 118
119 #ifdef DEBUG 119 #ifdef DEBUG
120 #define _DEBUG 1 120 #define _DEBUG 1
121 #else 121 #else
122 #define _DEBUG 0 122 #define _DEBUG 0
123 #endif 123 #endif
124 124
125 /* 125 /*
126 * Output a debug text when condition "cond" is met. The "cond" should be 126 * Output a debug text when condition "cond" is met. The "cond" should be
127 * computed by a preprocessor in the best case, allowing for the best 127 * computed by a preprocessor in the best case, allowing for the best
128 * optimization. 128 * optimization.
129 */ 129 */
130 #define debug_cond(cond, fmt, args...) \ 130 #define debug_cond(cond, fmt, args...) \
131 do { \ 131 do { \
132 if (cond) \ 132 if (cond) \
133 printf(fmt, ##args); \ 133 printf(fmt, ##args); \
134 } while (0) 134 } while (0)
135 135
136 #define debug(fmt, args...) \ 136 #define debug(fmt, args...) \
137 debug_cond(_DEBUG, fmt, ##args) 137 debug_cond(_DEBUG, fmt, ##args)
138 138
139 /* 139 /*
140 * An assertion is run-time check done in debug mode only. If DEBUG is not 140 * An assertion is run-time check done in debug mode only. If DEBUG is not
141 * defined then it is skipped. If DEBUG is defined and the assertion fails, 141 * defined then it is skipped. If DEBUG is defined and the assertion fails,
142 * then it calls panic*( which may or may not reset/halt U-Boot (see 142 * then it calls panic*( which may or may not reset/halt U-Boot (see
143 * CONFIG_PANIC_HANG), It is hoped that all failing assertions are found 143 * CONFIG_PANIC_HANG), It is hoped that all failing assertions are found
144 * before release, and after release it is hoped that they don't matter. But 144 * before release, and after release it is hoped that they don't matter. But
145 * in any case these failing assertions cannot be fixed with a reset (which 145 * in any case these failing assertions cannot be fixed with a reset (which
146 * may just do the same assertion again). 146 * may just do the same assertion again).
147 */ 147 */
148 void __assert_fail(const char *assertion, const char *file, unsigned line, 148 void __assert_fail(const char *assertion, const char *file, unsigned line,
149 const char *function); 149 const char *function);
150 #define assert(x) \ 150 #define assert(x) \
151 ({ if (!(x) && _DEBUG) \ 151 ({ if (!(x) && _DEBUG) \
152 __assert_fail(#x, __FILE__, __LINE__, __func__); }) 152 __assert_fail(#x, __FILE__, __LINE__, __func__); })
153 153
154 #define error(fmt, args...) do { \ 154 #define error(fmt, args...) do { \
155 printf("ERROR: " fmt "\nat %s:%d/%s()\n", \ 155 printf("ERROR: " fmt "\nat %s:%d/%s()\n", \
156 ##args, __FILE__, __LINE__, __func__); \ 156 ##args, __FILE__, __LINE__, __func__); \
157 } while (0) 157 } while (0)
158 158
159 #ifndef BUG 159 #ifndef BUG
160 #define BUG() do { \ 160 #define BUG() do { \
161 printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ 161 printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
162 panic("BUG!"); \ 162 panic("BUG!"); \
163 } while (0) 163 } while (0)
164 #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) 164 #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
165 #endif /* BUG */ 165 #endif /* BUG */
166 166
167 /* Force a compilation error if condition is true */ 167 /* Force a compilation error if condition is true */
168 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 168 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
169 169
170 typedef void (interrupt_handler_t)(void *); 170 typedef void (interrupt_handler_t)(void *);
171 171
172 #include <asm/u-boot.h> /* boot information for Linux kernel */ 172 #include <asm/u-boot.h> /* boot information for Linux kernel */
173 #include <asm/global_data.h> /* global data used for startup functions */ 173 #include <asm/global_data.h> /* global data used for startup functions */
174 174
175 /* 175 /*
176 * enable common handling for all TQM8xxL/M boards: 176 * enable common handling for all TQM8xxL/M boards:
177 * - CONFIG_TQM8xxM will be defined for all TQM8xxM boards 177 * - CONFIG_TQM8xxM will be defined for all TQM8xxM boards
178 * - CONFIG_TQM8xxL will be defined for all TQM8xxL _and_ TQM8xxM boards 178 * - CONFIG_TQM8xxL will be defined for all TQM8xxL _and_ TQM8xxM boards
179 * and for the TQM885D board 179 * and for the TQM885D board
180 */ 180 */
181 #if defined(CONFIG_TQM823M) || defined(CONFIG_TQM850M) || \ 181 #if defined(CONFIG_TQM823M) || defined(CONFIG_TQM850M) || \
182 defined(CONFIG_TQM855M) || defined(CONFIG_TQM860M) || \ 182 defined(CONFIG_TQM855M) || defined(CONFIG_TQM860M) || \
183 defined(CONFIG_TQM862M) || defined(CONFIG_TQM866M) 183 defined(CONFIG_TQM862M) || defined(CONFIG_TQM866M)
184 # ifndef CONFIG_TQM8xxM 184 # ifndef CONFIG_TQM8xxM
185 # define CONFIG_TQM8xxM 185 # define CONFIG_TQM8xxM
186 # endif 186 # endif
187 #endif 187 #endif
188 #if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L) || \ 188 #if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L) || \
189 defined(CONFIG_TQM855L) || defined(CONFIG_TQM860L) || \ 189 defined(CONFIG_TQM855L) || defined(CONFIG_TQM860L) || \
190 defined(CONFIG_TQM862L) || defined(CONFIG_TQM8xxM) || \ 190 defined(CONFIG_TQM862L) || defined(CONFIG_TQM8xxM) || \
191 defined(CONFIG_TQM885D) 191 defined(CONFIG_TQM885D)
192 # ifndef CONFIG_TQM8xxL 192 # ifndef CONFIG_TQM8xxL
193 # define CONFIG_TQM8xxL 193 # define CONFIG_TQM8xxL
194 # endif 194 # endif
195 #endif 195 #endif
196 196
197 #ifndef CONFIG_SERIAL_MULTI 197 #ifndef CONFIG_SERIAL_MULTI
198 198
199 #if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) \ 199 #if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) \
200 || defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \ 200 || defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
201 || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4) 201 || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
202 202
203 #define CONFIG_SERIAL_MULTI 1 203 #define CONFIG_SERIAL_MULTI 1
204 204
205 #endif 205 #endif
206 206
207 #endif /* CONFIG_SERIAL_MULTI */ 207 #endif /* CONFIG_SERIAL_MULTI */
208 208
209 /* 209 /*
210 * General Purpose Utilities 210 * General Purpose Utilities
211 */ 211 */
212 #define min(X, Y) \ 212 #define min(X, Y) \
213 ({ typeof (X) __x = (X); \ 213 ({ typeof (X) __x = (X); \
214 typeof (Y) __y = (Y); \ 214 typeof (Y) __y = (Y); \
215 (__x < __y) ? __x : __y; }) 215 (__x < __y) ? __x : __y; })
216 216
217 #define max(X, Y) \ 217 #define max(X, Y) \
218 ({ typeof (X) __x = (X); \ 218 ({ typeof (X) __x = (X); \
219 typeof (Y) __y = (Y); \ 219 typeof (Y) __y = (Y); \
220 (__x > __y) ? __x : __y; }) 220 (__x > __y) ? __x : __y; })
221 221
222 #define MIN(x, y) min(x, y) 222 #define MIN(x, y) min(x, y)
223 #define MAX(x, y) max(x, y) 223 #define MAX(x, y) max(x, y)
224 224
225 #if defined(CONFIG_ENV_IS_EMBEDDED) 225 #if defined(CONFIG_ENV_IS_EMBEDDED)
226 #define TOTAL_MALLOC_LEN CONFIG_SYS_MALLOC_LEN 226 #define TOTAL_MALLOC_LEN CONFIG_SYS_MALLOC_LEN
227 #elif ( ((CONFIG_ENV_ADDR+CONFIG_ENV_SIZE) < CONFIG_SYS_MONITOR_BASE) || \ 227 #elif ( ((CONFIG_ENV_ADDR+CONFIG_ENV_SIZE) < CONFIG_SYS_MONITOR_BASE) || \
228 (CONFIG_ENV_ADDR >= (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)) ) || \ 228 (CONFIG_ENV_ADDR >= (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)) ) || \
229 defined(CONFIG_ENV_IS_IN_NVRAM) 229 defined(CONFIG_ENV_IS_IN_NVRAM)
230 #define TOTAL_MALLOC_LEN (CONFIG_SYS_MALLOC_LEN + CONFIG_ENV_SIZE) 230 #define TOTAL_MALLOC_LEN (CONFIG_SYS_MALLOC_LEN + CONFIG_ENV_SIZE)
231 #else 231 #else
232 #define TOTAL_MALLOC_LEN CONFIG_SYS_MALLOC_LEN 232 #define TOTAL_MALLOC_LEN CONFIG_SYS_MALLOC_LEN
233 #endif 233 #endif
234 234
235 /** 235 /**
236 * container_of - cast a member of a structure out to the containing structure 236 * container_of - cast a member of a structure out to the containing structure
237 * @ptr: the pointer to the member. 237 * @ptr: the pointer to the member.
238 * @type: the type of the container struct this is embedded in. 238 * @type: the type of the container struct this is embedded in.
239 * @member: the name of the member within the struct. 239 * @member: the name of the member within the struct.
240 * 240 *
241 */ 241 */
242 #define container_of(ptr, type, member) ({ \ 242 #define container_of(ptr, type, member) ({ \
243 const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 243 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
244 (type *)( (char *)__mptr - offsetof(type,member) );}) 244 (type *)( (char *)__mptr - offsetof(type,member) );})
245 245
246 /* 246 /*
247 * Function Prototypes 247 * Function Prototypes
248 */ 248 */
249 249
250 void hang (void) __attribute__ ((noreturn)); 250 void hang (void) __attribute__ ((noreturn));
251 251
252 int timer_init(void); 252 int timer_init(void);
253 int cpu_init(void); 253 int cpu_init(void);
254 254
255 /* */ 255 /* */
256 phys_size_t initdram (int); 256 phys_size_t initdram (int);
257 int display_options (void); 257 int display_options (void);
258 void print_size(unsigned long long, const char *); 258 void print_size(unsigned long long, const char *);
259 int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen); 259 int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen);
260 260
261 /* common/main.c */ 261 /* common/main.c */
262 void main_loop (void); 262 void main_loop (void);
263 int run_command (const char *cmd, int flag); 263 int run_command (const char *cmd, int flag);
264 #ifdef CONFIG_CMD_PXE 264 #ifdef CONFIG_CMD_PXE
265 int run_command2(const char *cmd, int flag); 265 int run_command2(const char *cmd, int flag);
266 #endif 266 #endif
267 int readline (const char *const prompt); 267 int readline (const char *const prompt);
268 int readline_into_buffer (const char *const prompt, char * buffer); 268 int readline_into_buffer(const char *const prompt, char *buffer,
269 int timeout);
269 int parse_line (char *, char *[]); 270 int parse_line (char *, char *[]);
270 void init_cmd_timeout(void); 271 void init_cmd_timeout(void);
271 void reset_cmd_timeout(void); 272 void reset_cmd_timeout(void);
272 #ifdef CONFIG_MENU 273 #ifdef CONFIG_MENU
273 int abortboot(int bootdelay); 274 int abortboot(int bootdelay);
274 #endif 275 #endif
275 extern char console_buffer[]; 276 extern char console_buffer[];
276 277
277 /* arch/$(ARCH)/lib/board.c */ 278 /* arch/$(ARCH)/lib/board.c */
278 void board_init_f (ulong) __attribute__ ((noreturn)); 279 void board_init_f (ulong) __attribute__ ((noreturn));
279 void board_init_r (gd_t *, ulong) __attribute__ ((noreturn)); 280 void board_init_r (gd_t *, ulong) __attribute__ ((noreturn));
280 int checkboard (void); 281 int checkboard (void);
281 int checkflash (void); 282 int checkflash (void);
282 int checkdram (void); 283 int checkdram (void);
283 int last_stage_init(void); 284 int last_stage_init(void);
284 extern ulong monitor_flash_len; 285 extern ulong monitor_flash_len;
285 int mac_read_from_eeprom(void); 286 int mac_read_from_eeprom(void);
286 extern u8 _binary_dt_dtb_start[]; /* embedded device tree blob */ 287 extern u8 _binary_dt_dtb_start[]; /* embedded device tree blob */
287 288
288 /* 289 /*
289 * Called when console output is requested before the console is available. 290 * Called when console output is requested before the console is available.
290 * The board should do its best to get the character out to the user any way 291 * The board should do its best to get the character out to the user any way
291 * it can. 292 * it can.
292 */ 293 */
293 void board_pre_console_putc(int ch); 294 void board_pre_console_putc(int ch);
294 295
295 /* common/flash.c */ 296 /* common/flash.c */
296 void flash_perror (int); 297 void flash_perror (int);
297 298
298 /* common/cmd_source.c */ 299 /* common/cmd_source.c */
299 int source (ulong addr, const char *fit_uname); 300 int source (ulong addr, const char *fit_uname);
300 301
301 extern ulong load_addr; /* Default Load Address */ 302 extern ulong load_addr; /* Default Load Address */
302 extern ulong save_addr; /* Default Save Address */ 303 extern ulong save_addr; /* Default Save Address */
303 extern ulong save_size; /* Default Save Size */ 304 extern ulong save_size; /* Default Save Size */
304 305
305 /* common/cmd_doc.c */ 306 /* common/cmd_doc.c */
306 void doc_probe(unsigned long physadr); 307 void doc_probe(unsigned long physadr);
307 308
308 /* common/cmd_net.c */ 309 /* common/cmd_net.c */
309 int do_tftpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); 310 int do_tftpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
310 311
311 /* common/cmd_nvedit.c */ 312 /* common/cmd_nvedit.c */
312 int env_init (void); 313 int env_init (void);
313 void env_relocate (void); 314 void env_relocate (void);
314 int envmatch (uchar *, int); 315 int envmatch (uchar *, int);
315 char *getenv (const char *); 316 char *getenv (const char *);
316 int getenv_f (const char *name, char *buf, unsigned len); 317 int getenv_f (const char *name, char *buf, unsigned len);
317 ulong getenv_ulong(const char *name, int base, ulong default_val); 318 ulong getenv_ulong(const char *name, int base, ulong default_val);
318 int saveenv (void); 319 int saveenv (void);
319 #ifdef CONFIG_PPC /* ARM version to be fixed! */ 320 #ifdef CONFIG_PPC /* ARM version to be fixed! */
320 int inline setenv (const char *, const char *); 321 int inline setenv (const char *, const char *);
321 #else 322 #else
322 int setenv (const char *, const char *); 323 int setenv (const char *, const char *);
323 int setenv_ulong(const char *varname, ulong value); 324 int setenv_ulong(const char *varname, ulong value);
324 int setenv_addr(const char *varname, const void *addr); 325 int setenv_addr(const char *varname, const void *addr);
325 #endif /* CONFIG_PPC */ 326 #endif /* CONFIG_PPC */
326 #ifdef CONFIG_ARM 327 #ifdef CONFIG_ARM
327 # include <asm/mach-types.h> 328 # include <asm/mach-types.h>
328 # include <asm/setup.h> 329 # include <asm/setup.h>
329 # include <asm/u-boot-arm.h> /* ARM version to be fixed! */ 330 # include <asm/u-boot-arm.h> /* ARM version to be fixed! */
330 #endif /* CONFIG_ARM */ 331 #endif /* CONFIG_ARM */
331 #ifdef CONFIG_X86 /* x86 version to be fixed! */ 332 #ifdef CONFIG_X86 /* x86 version to be fixed! */
332 # include <asm/u-boot-x86.h> 333 # include <asm/u-boot-x86.h>
333 #endif /* CONFIG_X86 */ 334 #endif /* CONFIG_X86 */
334 #ifdef CONFIG_SANDBOX 335 #ifdef CONFIG_SANDBOX
335 # include <asm/u-boot-sandbox.h> /* TODO(sjg) what needs to be fixed? */ 336 # include <asm/u-boot-sandbox.h> /* TODO(sjg) what needs to be fixed? */
336 #endif 337 #endif
337 #ifdef CONFIG_NDS32 338 #ifdef CONFIG_NDS32
338 # include <asm/mach-types.h> 339 # include <asm/mach-types.h>
339 # include <asm/u-boot-nds32.h> 340 # include <asm/u-boot-nds32.h>
340 #endif /* CONFIG_NDS32 */ 341 #endif /* CONFIG_NDS32 */
341 342
342 #ifdef CONFIG_AUTO_COMPLETE 343 #ifdef CONFIG_AUTO_COMPLETE
343 int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf); 344 int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf);
344 #endif 345 #endif
345 int get_env_id (void); 346 int get_env_id (void);
346 347
347 void pci_init (void); 348 void pci_init (void);
348 void pci_init_board(void); 349 void pci_init_board(void);
349 void pciinfo (int, int); 350 void pciinfo (int, int);
350 351
351 #if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000)) 352 #if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000))
352 int pci_pre_init (struct pci_controller *); 353 int pci_pre_init (struct pci_controller *);
353 int is_pci_host (struct pci_controller *); 354 int is_pci_host (struct pci_controller *);
354 #endif 355 #endif
355 356
356 #if defined(CONFIG_PCI) && (defined(CONFIG_440) || defined(CONFIG_405EX)) 357 #if defined(CONFIG_PCI) && (defined(CONFIG_440) || defined(CONFIG_405EX))
357 # if defined(CONFIG_SYS_PCI_TARGET_INIT) 358 # if defined(CONFIG_SYS_PCI_TARGET_INIT)
358 void pci_target_init (struct pci_controller *); 359 void pci_target_init (struct pci_controller *);
359 # endif 360 # endif
360 # if defined(CONFIG_SYS_PCI_MASTER_INIT) 361 # if defined(CONFIG_SYS_PCI_MASTER_INIT)
361 void pci_master_init (struct pci_controller *); 362 void pci_master_init (struct pci_controller *);
362 # endif 363 # endif
363 #if defined(CONFIG_440SPE) || \ 364 #if defined(CONFIG_440SPE) || \
364 defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ 365 defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
365 defined(CONFIG_405EX) 366 defined(CONFIG_405EX)
366 void pcie_setup_hoses(int busno); 367 void pcie_setup_hoses(int busno);
367 #endif 368 #endif
368 #endif 369 #endif
369 370
370 int misc_init_f (void); 371 int misc_init_f (void);
371 int misc_init_r (void); 372 int misc_init_r (void);
372 373
373 /* common/exports.c */ 374 /* common/exports.c */
374 void jumptable_init(void); 375 void jumptable_init(void);
375 376
376 /* common/kallsysm.c */ 377 /* common/kallsysm.c */
377 const char *symbol_lookup(unsigned long addr, unsigned long *caddr); 378 const char *symbol_lookup(unsigned long addr, unsigned long *caddr);
378 379
379 /* api/api.c */ 380 /* api/api.c */
380 void api_init (void); 381 void api_init (void);
381 382
382 /* common/memsize.c */ 383 /* common/memsize.c */
383 long get_ram_size (long *, long); 384 long get_ram_size (long *, long);
384 385
385 /* $(BOARD)/$(BOARD).c */ 386 /* $(BOARD)/$(BOARD).c */
386 void reset_phy (void); 387 void reset_phy (void);
387 void fdc_hw_init (void); 388 void fdc_hw_init (void);
388 389
389 /* $(BOARD)/eeprom.c */ 390 /* $(BOARD)/eeprom.c */
390 void eeprom_init (void); 391 void eeprom_init (void);
391 #ifndef CONFIG_SPI 392 #ifndef CONFIG_SPI
392 int eeprom_probe (unsigned dev_addr, unsigned offset); 393 int eeprom_probe (unsigned dev_addr, unsigned offset);
393 #endif 394 #endif
394 int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt); 395 int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt);
395 int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt); 396 int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt);
396 #ifdef CONFIG_LWMON 397 #ifdef CONFIG_LWMON
397 extern uchar pic_read (uchar reg); 398 extern uchar pic_read (uchar reg);
398 extern void pic_write (uchar reg, uchar val); 399 extern void pic_write (uchar reg, uchar val);
399 #endif 400 #endif
400 401
401 /* 402 /*
402 * Set this up regardless of board 403 * Set this up regardless of board
403 * type, to prevent errors. 404 * type, to prevent errors.
404 */ 405 */
405 #if defined(CONFIG_SPI) || !defined(CONFIG_SYS_I2C_EEPROM_ADDR) 406 #if defined(CONFIG_SPI) || !defined(CONFIG_SYS_I2C_EEPROM_ADDR)
406 # define CONFIG_SYS_DEF_EEPROM_ADDR 0 407 # define CONFIG_SYS_DEF_EEPROM_ADDR 0
407 #else 408 #else
408 #if !defined(CONFIG_ENV_EEPROM_IS_ON_I2C) 409 #if !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
409 # define CONFIG_SYS_DEF_EEPROM_ADDR CONFIG_SYS_I2C_EEPROM_ADDR 410 # define CONFIG_SYS_DEF_EEPROM_ADDR CONFIG_SYS_I2C_EEPROM_ADDR
410 #endif 411 #endif
411 #endif /* CONFIG_SPI || !defined(CONFIG_SYS_I2C_EEPROM_ADDR) */ 412 #endif /* CONFIG_SPI || !defined(CONFIG_SYS_I2C_EEPROM_ADDR) */
412 413
413 #if defined(CONFIG_SPI) 414 #if defined(CONFIG_SPI)
414 extern void spi_init_f (void); 415 extern void spi_init_f (void);
415 extern void spi_init_r (void); 416 extern void spi_init_r (void);
416 extern ssize_t spi_read (uchar *, int, uchar *, int); 417 extern ssize_t spi_read (uchar *, int, uchar *, int);
417 extern ssize_t spi_write (uchar *, int, uchar *, int); 418 extern ssize_t spi_write (uchar *, int, uchar *, int);
418 #endif 419 #endif
419 420
420 #ifdef CONFIG_RPXCLASSIC 421 #ifdef CONFIG_RPXCLASSIC
421 void rpxclassic_init (void); 422 void rpxclassic_init (void);
422 #endif 423 #endif
423 424
424 void rpxlite_init (void); 425 void rpxlite_init (void);
425 426
426 #ifdef CONFIG_MBX 427 #ifdef CONFIG_MBX
427 /* $(BOARD)/mbx8xx.c */ 428 /* $(BOARD)/mbx8xx.c */
428 void mbx_init (void); 429 void mbx_init (void);
429 void board_serial_init (void); 430 void board_serial_init (void);
430 void board_ether_init (void); 431 void board_ether_init (void);
431 #endif 432 #endif
432 433
433 #ifdef CONFIG_HERMES 434 #ifdef CONFIG_HERMES
434 /* $(BOARD)/hermes.c */ 435 /* $(BOARD)/hermes.c */
435 void hermes_start_lxt980 (int speed); 436 void hermes_start_lxt980 (int speed);
436 #endif 437 #endif
437 438
438 #ifdef CONFIG_EVB64260 439 #ifdef CONFIG_EVB64260
439 void evb64260_init(void); 440 void evb64260_init(void);
440 void debug_led(int, int); 441 void debug_led(int, int);
441 void display_mem_map(void); 442 void display_mem_map(void);
442 void perform_soft_reset(void); 443 void perform_soft_reset(void);
443 #endif 444 #endif
444 445
445 /* $(BOARD)/$(BOARD).c */ 446 /* $(BOARD)/$(BOARD).c */
446 int board_early_init_f (void); 447 int board_early_init_f (void);
447 int board_late_init (void); 448 int board_late_init (void);
448 int board_postclk_init (void); /* after clocks/timebase, before env/serial */ 449 int board_postclk_init (void); /* after clocks/timebase, before env/serial */
449 int board_early_init_r (void); 450 int board_early_init_r (void);
450 void board_poweroff (void); 451 void board_poweroff (void);
451 452
452 #if defined(CONFIG_SYS_DRAM_TEST) 453 #if defined(CONFIG_SYS_DRAM_TEST)
453 int testdram(void); 454 int testdram(void);
454 #endif /* CONFIG_SYS_DRAM_TEST */ 455 #endif /* CONFIG_SYS_DRAM_TEST */
455 456
456 /* $(CPU)/start.S */ 457 /* $(CPU)/start.S */
457 #if defined(CONFIG_5xx) || \ 458 #if defined(CONFIG_5xx) || \
458 defined(CONFIG_8xx) 459 defined(CONFIG_8xx)
459 uint get_immr (uint); 460 uint get_immr (uint);
460 #endif 461 #endif
461 uint get_pir (void); 462 uint get_pir (void);
462 #if defined(CONFIG_MPC5xxx) 463 #if defined(CONFIG_MPC5xxx)
463 uint get_svr (void); 464 uint get_svr (void);
464 #endif 465 #endif
465 uint get_pvr (void); 466 uint get_pvr (void);
466 uint get_svr (void); 467 uint get_svr (void);
467 uint rd_ic_cst (void); 468 uint rd_ic_cst (void);
468 void wr_ic_cst (uint); 469 void wr_ic_cst (uint);
469 void wr_ic_adr (uint); 470 void wr_ic_adr (uint);
470 uint rd_dc_cst (void); 471 uint rd_dc_cst (void);
471 void wr_dc_cst (uint); 472 void wr_dc_cst (uint);
472 void wr_dc_adr (uint); 473 void wr_dc_adr (uint);
473 int icache_status (void); 474 int icache_status (void);
474 void icache_enable (void); 475 void icache_enable (void);
475 void icache_disable(void); 476 void icache_disable(void);
476 int dcache_status (void); 477 int dcache_status (void);
477 void dcache_enable (void); 478 void dcache_enable (void);
478 void dcache_disable(void); 479 void dcache_disable(void);
479 void mmu_disable(void); 480 void mmu_disable(void);
480 void relocate_code (ulong, gd_t *, ulong) __attribute__ ((noreturn)); 481 void relocate_code (ulong, gd_t *, ulong) __attribute__ ((noreturn));
481 ulong get_endaddr (void); 482 ulong get_endaddr (void);
482 void trap_init (ulong); 483 void trap_init (ulong);
483 #if defined (CONFIG_4xx) || \ 484 #if defined (CONFIG_4xx) || \
484 defined (CONFIG_MPC5xxx) || \ 485 defined (CONFIG_MPC5xxx) || \
485 defined (CONFIG_74xx_7xx) || \ 486 defined (CONFIG_74xx_7xx) || \
486 defined (CONFIG_74x) || \ 487 defined (CONFIG_74x) || \
487 defined (CONFIG_75x) || \ 488 defined (CONFIG_75x) || \
488 defined (CONFIG_74xx) || \ 489 defined (CONFIG_74xx) || \
489 defined (CONFIG_MPC8220) || \ 490 defined (CONFIG_MPC8220) || \
490 defined (CONFIG_MPC85xx) || \ 491 defined (CONFIG_MPC85xx) || \
491 defined (CONFIG_MPC86xx) || \ 492 defined (CONFIG_MPC86xx) || \
492 defined (CONFIG_MPC83xx) 493 defined (CONFIG_MPC83xx)
493 unsigned char in8(unsigned int); 494 unsigned char in8(unsigned int);
494 void out8(unsigned int, unsigned char); 495 void out8(unsigned int, unsigned char);
495 unsigned short in16(unsigned int); 496 unsigned short in16(unsigned int);
496 unsigned short in16r(unsigned int); 497 unsigned short in16r(unsigned int);
497 void out16(unsigned int, unsigned short value); 498 void out16(unsigned int, unsigned short value);
498 void out16r(unsigned int, unsigned short value); 499 void out16r(unsigned int, unsigned short value);
499 unsigned long in32(unsigned int); 500 unsigned long in32(unsigned int);
500 unsigned long in32r(unsigned int); 501 unsigned long in32r(unsigned int);
501 void out32(unsigned int, unsigned long value); 502 void out32(unsigned int, unsigned long value);
502 void out32r(unsigned int, unsigned long value); 503 void out32r(unsigned int, unsigned long value);
503 void ppcDcbf(unsigned long value); 504 void ppcDcbf(unsigned long value);
504 void ppcDcbi(unsigned long value); 505 void ppcDcbi(unsigned long value);
505 void ppcSync(void); 506 void ppcSync(void);
506 void ppcDcbz(unsigned long value); 507 void ppcDcbz(unsigned long value);
507 #endif 508 #endif
508 #if defined (CONFIG_MICROBLAZE) 509 #if defined (CONFIG_MICROBLAZE)
509 unsigned short in16(unsigned int); 510 unsigned short in16(unsigned int);
510 void out16(unsigned int, unsigned short value); 511 void out16(unsigned int, unsigned short value);
511 #endif 512 #endif
512 513
513 #if defined (CONFIG_MPC83xx) 514 #if defined (CONFIG_MPC83xx)
514 void ppcDWload(unsigned int *addr, unsigned int *ret); 515 void ppcDWload(unsigned int *addr, unsigned int *ret);
515 void ppcDWstore(unsigned int *addr, unsigned int *value); 516 void ppcDWstore(unsigned int *addr, unsigned int *value);
516 void disable_addr_trans(void); 517 void disable_addr_trans(void);
517 void enable_addr_trans(void); 518 void enable_addr_trans(void);
518 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) 519 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
519 void ddr_enable_ecc(unsigned int dram_size); 520 void ddr_enable_ecc(unsigned int dram_size);
520 #endif 521 #endif
521 #endif 522 #endif
522 523
523 /* $(CPU)/cpu.c */ 524 /* $(CPU)/cpu.c */
524 static inline int cpumask_next(int cpu, unsigned int mask) 525 static inline int cpumask_next(int cpu, unsigned int mask)
525 { 526 {
526 for (cpu++; !((1 << cpu) & mask); cpu++) 527 for (cpu++; !((1 << cpu) & mask); cpu++)
527 ; 528 ;
528 529
529 return cpu; 530 return cpu;
530 } 531 }
531 532
532 #define for_each_cpu(iter, cpu, num_cpus, mask) \ 533 #define for_each_cpu(iter, cpu, num_cpus, mask) \
533 for (iter = 0, cpu = cpumask_next(-1, mask); \ 534 for (iter = 0, cpu = cpumask_next(-1, mask); \
534 iter < num_cpus; \ 535 iter < num_cpus; \
535 iter++, cpu = cpumask_next(cpu, mask)) \ 536 iter++, cpu = cpumask_next(cpu, mask)) \
536 537
537 int cpu_numcores (void); 538 int cpu_numcores (void);
538 u32 cpu_mask (void); 539 u32 cpu_mask (void);
539 int is_core_valid (unsigned int); 540 int is_core_valid (unsigned int);
540 int probecpu (void); 541 int probecpu (void);
541 int checkcpu (void); 542 int checkcpu (void);
542 int checkicache (void); 543 int checkicache (void);
543 int checkdcache (void); 544 int checkdcache (void);
544 void upmconfig (unsigned int, unsigned int *, unsigned int); 545 void upmconfig (unsigned int, unsigned int *, unsigned int);
545 ulong get_tbclk (void); 546 ulong get_tbclk (void);
546 void reset_cpu (ulong addr); 547 void reset_cpu (ulong addr);
547 #if defined (CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) 548 #if defined (CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP)
548 void ft_cpu_setup(void *blob, bd_t *bd); 549 void ft_cpu_setup(void *blob, bd_t *bd);
549 #ifdef CONFIG_PCI 550 #ifdef CONFIG_PCI
550 void ft_pci_setup(void *blob, bd_t *bd); 551 void ft_pci_setup(void *blob, bd_t *bd);
551 #endif 552 #endif
552 #endif 553 #endif
553 554
554 555
555 /* $(CPU)/serial.c */ 556 /* $(CPU)/serial.c */
556 int serial_init (void); 557 int serial_init (void);
557 void serial_setbrg (void); 558 void serial_setbrg (void);
558 void serial_putc (const char); 559 void serial_putc (const char);
559 void serial_putc_raw(const char); 560 void serial_putc_raw(const char);
560 void serial_puts (const char *); 561 void serial_puts (const char *);
561 int serial_getc (void); 562 int serial_getc (void);
562 int serial_tstc (void); 563 int serial_tstc (void);
563 564
564 void _serial_setbrg (const int); 565 void _serial_setbrg (const int);
565 void _serial_putc (const char, const int); 566 void _serial_putc (const char, const int);
566 void _serial_putc_raw(const char, const int); 567 void _serial_putc_raw(const char, const int);
567 void _serial_puts (const char *, const int); 568 void _serial_puts (const char *, const int);
568 int _serial_getc (const int); 569 int _serial_getc (const int);
569 int _serial_tstc (const int); 570 int _serial_tstc (const int);
570 571
571 /* $(CPU)/speed.c */ 572 /* $(CPU)/speed.c */
572 int get_clocks (void); 573 int get_clocks (void);
573 int get_clocks_866 (void); 574 int get_clocks_866 (void);
574 int sdram_adjust_866 (void); 575 int sdram_adjust_866 (void);
575 int adjust_sdram_tbs_8xx (void); 576 int adjust_sdram_tbs_8xx (void);
576 #if defined(CONFIG_8260) 577 #if defined(CONFIG_8260)
577 int prt_8260_clks (void); 578 int prt_8260_clks (void);
578 #elif defined(CONFIG_MPC5xxx) 579 #elif defined(CONFIG_MPC5xxx)
579 int prt_mpc5xxx_clks (void); 580 int prt_mpc5xxx_clks (void);
580 #endif 581 #endif
581 #if defined(CONFIG_MPC512X) 582 #if defined(CONFIG_MPC512X)
582 int prt_mpc512xxx_clks (void); 583 int prt_mpc512xxx_clks (void);
583 #endif 584 #endif
584 #if defined(CONFIG_MPC8220) 585 #if defined(CONFIG_MPC8220)
585 int prt_mpc8220_clks (void); 586 int prt_mpc8220_clks (void);
586 #endif 587 #endif
587 #ifdef CONFIG_4xx 588 #ifdef CONFIG_4xx
588 ulong get_OPB_freq (void); 589 ulong get_OPB_freq (void);
589 ulong get_PCI_freq (void); 590 ulong get_PCI_freq (void);
590 #endif 591 #endif
591 #if defined(CONFIG_S3C24X0) || \ 592 #if defined(CONFIG_S3C24X0) || \
592 defined(CONFIG_LH7A40X) || \ 593 defined(CONFIG_LH7A40X) || \
593 defined(CONFIG_S3C6400) || \ 594 defined(CONFIG_S3C6400) || \
594 defined(CONFIG_EP93XX) 595 defined(CONFIG_EP93XX)
595 ulong get_FCLK (void); 596 ulong get_FCLK (void);
596 ulong get_HCLK (void); 597 ulong get_HCLK (void);
597 ulong get_PCLK (void); 598 ulong get_PCLK (void);
598 ulong get_UCLK (void); 599 ulong get_UCLK (void);
599 #endif 600 #endif
600 #if defined(CONFIG_LH7A40X) 601 #if defined(CONFIG_LH7A40X)
601 ulong get_PLLCLK (void); 602 ulong get_PLLCLK (void);
602 #endif 603 #endif
603 #if defined CONFIG_INCA_IP 604 #if defined CONFIG_INCA_IP
604 uint incaip_get_cpuclk (void); 605 uint incaip_get_cpuclk (void);
605 #endif 606 #endif
606 #if defined(CONFIG_IMX) 607 #if defined(CONFIG_IMX)
607 ulong get_systemPLLCLK(void); 608 ulong get_systemPLLCLK(void);
608 ulong get_FCLK(void); 609 ulong get_FCLK(void);
609 ulong get_HCLK(void); 610 ulong get_HCLK(void);
610 ulong get_BCLK(void); 611 ulong get_BCLK(void);
611 ulong get_PERCLK1(void); 612 ulong get_PERCLK1(void);
612 ulong get_PERCLK2(void); 613 ulong get_PERCLK2(void);
613 ulong get_PERCLK3(void); 614 ulong get_PERCLK3(void);
614 #endif 615 #endif
615 ulong get_bus_freq (ulong); 616 ulong get_bus_freq (ulong);
616 int get_serial_clock(void); 617 int get_serial_clock(void);
617 618
618 #if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) 619 #if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx)
619 ulong get_ddr_freq(ulong); 620 ulong get_ddr_freq(ulong);
620 #endif 621 #endif
621 #if defined(CONFIG_MPC85xx) 622 #if defined(CONFIG_MPC85xx)
622 typedef MPC85xx_SYS_INFO sys_info_t; 623 typedef MPC85xx_SYS_INFO sys_info_t;
623 void get_sys_info ( sys_info_t * ); 624 void get_sys_info ( sys_info_t * );
624 #endif 625 #endif
625 #if defined(CONFIG_MPC86xx) 626 #if defined(CONFIG_MPC86xx)
626 typedef MPC86xx_SYS_INFO sys_info_t; 627 typedef MPC86xx_SYS_INFO sys_info_t;
627 void get_sys_info ( sys_info_t * ); 628 void get_sys_info ( sys_info_t * );
628 static inline ulong get_ddr_freq(ulong dummy) 629 static inline ulong get_ddr_freq(ulong dummy)
629 { 630 {
630 return get_bus_freq(dummy); 631 return get_bus_freq(dummy);
631 } 632 }
632 #endif 633 #endif
633 634
634 #if defined(CONFIG_4xx) || defined(CONFIG_IOP480) 635 #if defined(CONFIG_4xx) || defined(CONFIG_IOP480)
635 # if defined(CONFIG_440) 636 # if defined(CONFIG_440)
636 # if defined(CONFIG_440SPE) 637 # if defined(CONFIG_440SPE)
637 unsigned long determine_sysper(void); 638 unsigned long determine_sysper(void);
638 unsigned long determine_pci_clock_per(void); 639 unsigned long determine_pci_clock_per(void);
639 # endif 640 # endif
640 # endif 641 # endif
641 typedef PPC4xx_SYS_INFO sys_info_t; 642 typedef PPC4xx_SYS_INFO sys_info_t;
642 int ppc440spe_revB(void); 643 int ppc440spe_revB(void);
643 void get_sys_info ( sys_info_t * ); 644 void get_sys_info ( sys_info_t * );
644 #endif 645 #endif
645 646
646 /* $(CPU)/cpu_init.c */ 647 /* $(CPU)/cpu_init.c */
647 #if defined(CONFIG_8xx) || defined(CONFIG_8260) 648 #if defined(CONFIG_8xx) || defined(CONFIG_8260)
648 void cpu_init_f (volatile immap_t *immr); 649 void cpu_init_f (volatile immap_t *immr);
649 #endif 650 #endif
650 #if defined(CONFIG_4xx) || defined(CONFIG_MPC85xx) || defined(CONFIG_MCF52x2) ||defined(CONFIG_MPC86xx) 651 #if defined(CONFIG_4xx) || defined(CONFIG_MPC85xx) || defined(CONFIG_MCF52x2) ||defined(CONFIG_MPC86xx)
651 void cpu_init_f (void); 652 void cpu_init_f (void);
652 #endif 653 #endif
653 654
654 int cpu_init_r (void); 655 int cpu_init_r (void);
655 #if defined(CONFIG_8260) 656 #if defined(CONFIG_8260)
656 int prt_8260_rsr (void); 657 int prt_8260_rsr (void);
657 #elif defined(CONFIG_MPC83xx) 658 #elif defined(CONFIG_MPC83xx)
658 int prt_83xx_rsr (void); 659 int prt_83xx_rsr (void);
659 #endif 660 #endif
660 661
661 /* $(CPU)/interrupts.c */ 662 /* $(CPU)/interrupts.c */
662 int interrupt_init (void); 663 int interrupt_init (void);
663 void timer_interrupt (struct pt_regs *); 664 void timer_interrupt (struct pt_regs *);
664 void external_interrupt (struct pt_regs *); 665 void external_interrupt (struct pt_regs *);
665 void irq_install_handler(int, interrupt_handler_t *, void *); 666 void irq_install_handler(int, interrupt_handler_t *, void *);
666 void irq_free_handler (int); 667 void irq_free_handler (int);
667 void reset_timer (void); 668 void reset_timer (void);
668 ulong get_timer (ulong base); 669 ulong get_timer (ulong base);
669 void enable_interrupts (void); 670 void enable_interrupts (void);
670 int disable_interrupts (void); 671 int disable_interrupts (void);
671 672
672 /* $(CPU)/.../commproc.c */ 673 /* $(CPU)/.../commproc.c */
673 int dpram_init (void); 674 int dpram_init (void);
674 uint dpram_base(void); 675 uint dpram_base(void);
675 uint dpram_base_align(uint align); 676 uint dpram_base_align(uint align);
676 uint dpram_alloc(uint size); 677 uint dpram_alloc(uint size);
677 uint dpram_alloc_align(uint size,uint align); 678 uint dpram_alloc_align(uint size,uint align);
678 void bootcount_store (ulong); 679 void bootcount_store (ulong);
679 ulong bootcount_load (void); 680 ulong bootcount_load (void);
680 #define BOOTCOUNT_MAGIC 0xB001C041 681 #define BOOTCOUNT_MAGIC 0xB001C041
681 682
682 /* $(CPU)/.../<eth> */ 683 /* $(CPU)/.../<eth> */
683 void mii_init (void); 684 void mii_init (void);
684 685
685 /* $(CPU)/.../lcd.c */ 686 /* $(CPU)/.../lcd.c */
686 ulong lcd_setmem (ulong); 687 ulong lcd_setmem (ulong);
687 688
688 /* $(CPU)/.../video.c */ 689 /* $(CPU)/.../video.c */
689 ulong video_setmem (ulong); 690 ulong video_setmem (ulong);
690 691
691 /* arch/$(ARCH)/lib/cache.c */ 692 /* arch/$(ARCH)/lib/cache.c */
692 void enable_caches(void); 693 void enable_caches(void);
693 void flush_cache (unsigned long, unsigned long); 694 void flush_cache (unsigned long, unsigned long);
694 void flush_dcache_all(void); 695 void flush_dcache_all(void);
695 void flush_dcache_range(unsigned long start, unsigned long stop); 696 void flush_dcache_range(unsigned long start, unsigned long stop);
696 void invalidate_dcache_range(unsigned long start, unsigned long stop); 697 void invalidate_dcache_range(unsigned long start, unsigned long stop);
697 void invalidate_dcache_all(void); 698 void invalidate_dcache_all(void);
698 void invalidate_icache_all(void); 699 void invalidate_icache_all(void);
699 700
700 /* arch/$(ARCH)/lib/ticks.S */ 701 /* arch/$(ARCH)/lib/ticks.S */
701 unsigned long long get_ticks(void); 702 unsigned long long get_ticks(void);
702 void wait_ticks (unsigned long); 703 void wait_ticks (unsigned long);
703 704
704 /* arch/$(ARCH)/lib/time.c */ 705 /* arch/$(ARCH)/lib/time.c */
705 void __udelay (unsigned long); 706 void __udelay (unsigned long);
706 ulong usec2ticks (unsigned long usec); 707 ulong usec2ticks (unsigned long usec);
707 ulong ticks2usec (unsigned long ticks); 708 ulong ticks2usec (unsigned long ticks);
708 int init_timebase (void); 709 int init_timebase (void);
709 710
710 /* lib/gunzip.c */ 711 /* lib/gunzip.c */
711 int gunzip(void *, int, unsigned char *, unsigned long *); 712 int gunzip(void *, int, unsigned char *, unsigned long *);
712 int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp, 713 int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
713 int stoponerr, int offset); 714 int stoponerr, int offset);
714 715
715 /* lib/net_utils.c */ 716 /* lib/net_utils.c */
716 #include <net.h> 717 #include <net.h>
717 static inline IPaddr_t getenv_IPaddr (char *var) 718 static inline IPaddr_t getenv_IPaddr (char *var)
718 { 719 {
719 return (string_to_ip(getenv(var))); 720 return (string_to_ip(getenv(var)));
720 } 721 }
721 722
722 /* lib/qsort.c */ 723 /* lib/qsort.c */
723 void qsort(void *base, size_t nmemb, size_t size, 724 void qsort(void *base, size_t nmemb, size_t size,
724 int(*compar)(const void *, const void *)); 725 int(*compar)(const void *, const void *));
725 int strcmp_compar(const void *, const void *); 726 int strcmp_compar(const void *, const void *);
726 727
727 /* lib/time.c */ 728 /* lib/time.c */
728 void udelay (unsigned long); 729 void udelay (unsigned long);
729 void mdelay(unsigned long); 730 void mdelay(unsigned long);
730 731
731 /* lib/uuid.c */ 732 /* lib/uuid.c */
732 void uuid_str_to_bin(const char *uuid, unsigned char *out); 733 void uuid_str_to_bin(const char *uuid, unsigned char *out);
733 int uuid_str_valid(const char *uuid); 734 int uuid_str_valid(const char *uuid);
734 735
735 /* lib/vsprintf.c */ 736 /* lib/vsprintf.c */
736 #include <vsprintf.h> 737 #include <vsprintf.h>
737 738
738 /* lib/strmhz.c */ 739 /* lib/strmhz.c */
739 char * strmhz(char *buf, unsigned long hz); 740 char * strmhz(char *buf, unsigned long hz);
740 741
741 /* lib/crc32.c */ 742 /* lib/crc32.c */
742 #include <u-boot/crc.h> 743 #include <u-boot/crc.h>
743 744
744 /* common/console.c */ 745 /* common/console.c */
745 int console_init_f(void); /* Before relocation; uses the serial stuff */ 746 int console_init_f(void); /* Before relocation; uses the serial stuff */
746 int console_init_r(void); /* After relocation; uses the console stuff */ 747 int console_init_r(void); /* After relocation; uses the console stuff */
747 int console_assign(int file, const char *devname); /* Assign the console */ 748 int console_assign(int file, const char *devname); /* Assign the console */
748 int ctrlc (void); 749 int ctrlc (void);
749 int had_ctrlc (void); /* have we had a Control-C since last clear? */ 750 int had_ctrlc (void); /* have we had a Control-C since last clear? */
750 void clear_ctrlc (void); /* clear the Control-C condition */ 751 void clear_ctrlc (void); /* clear the Control-C condition */
751 int disable_ctrlc (int); /* 1 to disable, 0 to enable Control-C detect */ 752 int disable_ctrlc (int); /* 1 to disable, 0 to enable Control-C detect */
752 753
753 /* 754 /*
754 * STDIO based functions (can always be used) 755 * STDIO based functions (can always be used)
755 */ 756 */
756 /* serial stuff */ 757 /* serial stuff */
757 int serial_printf (const char *fmt, ...) 758 int serial_printf (const char *fmt, ...)
758 __attribute__ ((format (__printf__, 1, 2))); 759 __attribute__ ((format (__printf__, 1, 2)));
759 /* stdin */ 760 /* stdin */
760 int getc(void); 761 int getc(void);
761 int tstc(void); 762 int tstc(void);
762 763
763 /* stdout */ 764 /* stdout */
764 void putc(const char c); 765 void putc(const char c);
765 void puts(const char *s); 766 void puts(const char *s);
766 int printf(const char *fmt, ...) 767 int printf(const char *fmt, ...)
767 __attribute__ ((format (__printf__, 1, 2))); 768 __attribute__ ((format (__printf__, 1, 2)));
768 int vprintf(const char *fmt, va_list args); 769 int vprintf(const char *fmt, va_list args);
769 770
770 /* stderr */ 771 /* stderr */
771 #define eputc(c) fputc(stderr, c) 772 #define eputc(c) fputc(stderr, c)
772 #define eputs(s) fputs(stderr, s) 773 #define eputs(s) fputs(stderr, s)
773 #define eprintf(fmt,args...) fprintf(stderr,fmt ,##args) 774 #define eprintf(fmt,args...) fprintf(stderr,fmt ,##args)
774 775
775 /* 776 /*
776 * FILE based functions (can only be used AFTER relocation!) 777 * FILE based functions (can only be used AFTER relocation!)
777 */ 778 */
778 #define stdin 0 779 #define stdin 0
779 #define stdout 1 780 #define stdout 1
780 #define stderr 2 781 #define stderr 2
781 #define MAX_FILES 3 782 #define MAX_FILES 3
782 783
783 int fprintf(int file, const char *fmt, ...) 784 int fprintf(int file, const char *fmt, ...)
784 __attribute__ ((format (__printf__, 2, 3))); 785 __attribute__ ((format (__printf__, 2, 3)));
785 void fputs(int file, const char *s); 786 void fputs(int file, const char *s);
786 void fputc(int file, const char c); 787 void fputc(int file, const char c);
787 int ftstc(int file); 788 int ftstc(int file);
788 int fgetc(int file); 789 int fgetc(int file);
789 790
790 /* 791 /*
791 * CONSOLE multiplexing. 792 * CONSOLE multiplexing.
792 */ 793 */
793 #ifdef CONFIG_CONSOLE_MUX 794 #ifdef CONFIG_CONSOLE_MUX
794 #include <iomux.h> 795 #include <iomux.h>
795 #endif 796 #endif
796 797
797 int pcmcia_init (void); 798 int pcmcia_init (void);
798 799
799 #ifdef CONFIG_STATUS_LED 800 #ifdef CONFIG_STATUS_LED
800 # include <status_led.h> 801 # include <status_led.h>
801 #endif 802 #endif
802 /* 803 /*
803 * Board-specific Platform code can reimplement show_boot_progress () if needed 804 * Board-specific Platform code can reimplement show_boot_progress () if needed
804 */ 805 */
805 void show_boot_progress(int val); 806 void show_boot_progress(int val);
806 807
807 /* Multicore arch functions */ 808 /* Multicore arch functions */
808 #ifdef CONFIG_MP 809 #ifdef CONFIG_MP
809 int cpu_status(int nr); 810 int cpu_status(int nr);
810 int cpu_reset(int nr); 811 int cpu_reset(int nr);
811 int cpu_disable(int nr); 812 int cpu_disable(int nr);
812 int cpu_release(int nr, int argc, char * const argv[]); 813 int cpu_release(int nr, int argc, char * const argv[]);
813 #endif 814 #endif
814 815
815 #endif /* __ASSEMBLY__ */ 816 #endif /* __ASSEMBLY__ */
816 817
817 #ifdef CONFIG_PPC 818 #ifdef CONFIG_PPC
818 /* 819 /*
819 * Has to be included outside of the #ifndef __ASSEMBLY__ section. 820 * Has to be included outside of the #ifndef __ASSEMBLY__ section.
820 * Otherwise might lead to compilation errors in assembler files. 821 * Otherwise might lead to compilation errors in assembler files.
821 */ 822 */
822 #include <asm/cache.h> 823 #include <asm/cache.h>
823 #endif 824 #endif
824 825
825 /* Put only stuff here that the assembler can digest */ 826 /* Put only stuff here that the assembler can digest */
826 827
827 #ifdef CONFIG_POST 828 #ifdef CONFIG_POST
828 #define CONFIG_HAS_POST 829 #define CONFIG_HAS_POST
829 #ifndef CONFIG_POST_ALT_LIST 830 #ifndef CONFIG_POST_ALT_LIST
830 #define CONFIG_POST_STD_LIST 831 #define CONFIG_POST_STD_LIST
831 #endif 832 #endif
832 #endif 833 #endif
833 834
834 #ifdef CONFIG_INIT_CRITICAL 835 #ifdef CONFIG_INIT_CRITICAL
835 #error CONFIG_INIT_CRITICAL is deprecated! 836 #error CONFIG_INIT_CRITICAL is deprecated!
836 #error Read section CONFIG_SKIP_LOWLEVEL_INIT in README. 837 #error Read section CONFIG_SKIP_LOWLEVEL_INIT in README.
837 #endif 838 #endif
838 839
839 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 840 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
840 841
841 #define ROUND(a,b) (((a) + (b) - 1) & ~((b) - 1)) 842 #define ROUND(a,b) (((a) + (b) - 1) & ~((b) - 1))
842 #define DIV_ROUND(n,d) (((n) + ((d)/2)) / (d)) 843 #define DIV_ROUND(n,d) (((n) + ((d)/2)) / (d))
843 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 844 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
844 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) 845 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
845 846
846 #define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1) 847 #define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1)
847 #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 848 #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
848 849
849 /* 850 /*
850 * ARCH_DMA_MINALIGN is defined in asm/cache.h for each architecture. It 851 * ARCH_DMA_MINALIGN is defined in asm/cache.h for each architecture. It
851 * is used to align DMA buffers. 852 * is used to align DMA buffers.
852 */ 853 */
853 #ifndef __ASSEMBLY__ 854 #ifndef __ASSEMBLY__
854 #include <asm/cache.h> 855 #include <asm/cache.h>
855 #endif 856 #endif
856 857
857 /* 858 /*
858 * The ALLOC_CACHE_ALIGN_BUFFER macro is used to allocate a buffer on the 859 * The ALLOC_CACHE_ALIGN_BUFFER macro is used to allocate a buffer on the
859 * stack that meets the minimum architecture alignment requirements for DMA. 860 * stack that meets the minimum architecture alignment requirements for DMA.
860 * Such a buffer is useful for DMA operations where flushing and invalidating 861 * Such a buffer is useful for DMA operations where flushing and invalidating
861 * the cache before and after a read and/or write operation is required for 862 * the cache before and after a read and/or write operation is required for
862 * correct operations. 863 * correct operations.
863 * 864 *
864 * When called the macro creates an array on the stack that is sized such 865 * When called the macro creates an array on the stack that is sized such
865 * that: 866 * that:
866 * 867 *
867 * 1) The beginning of the array can be advanced enough to be aligned. 868 * 1) The beginning of the array can be advanced enough to be aligned.
868 * 869 *
869 * 2) The size of the aligned portion of the array is a multiple of the minimum 870 * 2) The size of the aligned portion of the array is a multiple of the minimum
870 * architecture alignment required for DMA. 871 * architecture alignment required for DMA.
871 * 872 *
872 * 3) The aligned portion contains enough space for the original number of 873 * 3) The aligned portion contains enough space for the original number of
873 * elements requested. 874 * elements requested.
874 * 875 *
875 * The macro then creates a pointer to the aligned portion of this array and 876 * The macro then creates a pointer to the aligned portion of this array and
876 * assigns to the pointer the address of the first element in the aligned 877 * assigns to the pointer the address of the first element in the aligned
877 * portion of the array. 878 * portion of the array.
878 * 879 *
879 * Calling the macro as: 880 * Calling the macro as:
880 * 881 *
881 * ALLOC_CACHE_ALIGN_BUFFER(uint32_t, buffer, 1024); 882 * ALLOC_CACHE_ALIGN_BUFFER(uint32_t, buffer, 1024);
882 * 883 *
883 * Will result in something similar to saying: 884 * Will result in something similar to saying:
884 * 885 *
885 * uint32_t buffer[1024]; 886 * uint32_t buffer[1024];
886 * 887 *
887 * The following differences exist: 888 * The following differences exist:
888 * 889 *
889 * 1) The resulting buffer is guaranteed to be aligned to the value of 890 * 1) The resulting buffer is guaranteed to be aligned to the value of
890 * ARCH_DMA_MINALIGN. 891 * ARCH_DMA_MINALIGN.
891 * 892 *
892 * 2) The buffer variable created by the macro is a pointer to the specified 893 * 2) The buffer variable created by the macro is a pointer to the specified
893 * type, and NOT an array of the specified type. This can be very important 894 * type, and NOT an array of the specified type. This can be very important
894 * if you want the address of the buffer, which you probably do, to pass it 895 * if you want the address of the buffer, which you probably do, to pass it
895 * to the DMA hardware. The value of &buffer is different in the two cases. 896 * to the DMA hardware. The value of &buffer is different in the two cases.
896 * In the macro case it will be the address of the pointer, not the address 897 * In the macro case it will be the address of the pointer, not the address
897 * of the space reserved for the buffer. However, in the second case it 898 * of the space reserved for the buffer. However, in the second case it
898 * would be the address of the buffer. So if you are replacing hard coded 899 * would be the address of the buffer. So if you are replacing hard coded
899 * stack buffers with this macro you need to make sure you remove the & from 900 * stack buffers with this macro you need to make sure you remove the & from
900 * the locations where you are taking the address of the buffer. 901 * the locations where you are taking the address of the buffer.
901 * 902 *
902 * Note that the size parameter is the number of array elements to allocate, 903 * Note that the size parameter is the number of array elements to allocate,
903 * not the number of bytes. 904 * not the number of bytes.
904 * 905 *
905 * This macro can not be used outside of function scope, or for the creation 906 * This macro can not be used outside of function scope, or for the creation
906 * of a function scoped static buffer. It can not be used to create a cache 907 * of a function scoped static buffer. It can not be used to create a cache
907 * line aligned global buffer. 908 * line aligned global buffer.
908 */ 909 */
909 #define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \ 910 #define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
910 char __##name[ROUND(size * sizeof(type), ARCH_DMA_MINALIGN) + \ 911 char __##name[ROUND(size * sizeof(type), ARCH_DMA_MINALIGN) + \
911 ARCH_DMA_MINALIGN - 1]; \ 912 ARCH_DMA_MINALIGN - 1]; \
912 \ 913 \
913 type *name = (type *) ALIGN((uintptr_t)__##name, ARCH_DMA_MINALIGN) 914 type *name = (type *) ALIGN((uintptr_t)__##name, ARCH_DMA_MINALIGN)
914 915
915 /* Pull in stuff for the build system */ 916 /* Pull in stuff for the build system */
916 #ifdef DO_DEPS_ONLY 917 #ifdef DO_DEPS_ONLY
917 # include <environment.h> 918 # include <environment.h>
918 #endif 919 #endif
919 920
920 #endif /* __COMMON_H_ */ 921 #endif /* __COMMON_H_ */
921 922