Blame view

cmd/nvedit.c 36 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
a68d3ed0a   wdenk   Initial revision
2
  /*
ea009d474   Wolfgang Denk   hashtable: prepar...
3
   * (C) Copyright 2000-2013
a68d3ed0a   wdenk   Initial revision
4
5
6
7
   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   *
   * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   * Andreas Heppel <aheppel@sysgo.de>
a000b7950   Kim Phillips   common: add a gre...
8
9
   *
   * Copyright 2011 Freescale Semiconductor, Inc.
a68d3ed0a   wdenk   Initial revision
10
   */
ea882baf9   Wolfgang Denk   New implementatio...
11
  /*
a68d3ed0a   wdenk   Initial revision
12
13
   * Support for persistent environment data
   *
ea882baf9   Wolfgang Denk   New implementatio...
14
15
   * The "environment" is stored on external storage as a list of '\0'
   * terminated "name=value" strings. The end of the list is marked by
fc0b5948e   Robert P. J. Day   Various, accumula...
16
   * a double '\0'. The environment is preceded by a 32 bit CRC over
ea882baf9   Wolfgang Denk   New implementatio...
17
18
   * the data part and, in case of redundant environment, a byte of
   * flags.
a68d3ed0a   wdenk   Initial revision
19
   *
ea882baf9   Wolfgang Denk   New implementatio...
20
21
22
   * This linearized representation will also be used before
   * relocation, i. e. as long as we don't have a full C runtime
   * environment. After that, we use a hash table.
a68d3ed0a   wdenk   Initial revision
23
24
25
   */
  
  #include <common.h>
18d66533a   Simon Glass   move CLI prototyp...
26
  #include <cli.h>
a68d3ed0a   wdenk   Initial revision
27
  #include <command.h>
24b852a7a   Simon Glass   Move console defi...
28
  #include <console.h>
f1f0ae6a9   Simon Glass   env: Move get_env...
29
  #include <env.h>
f3998fdc4   Simon Glass   env: Rename envir...
30
  #include <env_internal.h>
ea882baf9   Wolfgang Denk   New implementatio...
31
32
  #include <search.h>
  #include <errno.h>
246c69225   Peter Tyser   Add 'editenv' com...
33
  #include <malloc.h>
0eb25b619   Joe Hershberger   common: Make sure...
34
  #include <mapmem.h>
3db711085   Simon Glass   crc32: Use the cr...
35
  #include <u-boot/crc.h>
2a3cb0207   wdenk   Quick & Dirty fix...
36
  #include <watchdog.h>
a68d3ed0a   wdenk   Initial revision
37
38
  #include <linux/stddef.h>
  #include <asm/byteorder.h>
fd37dac9e   Simon Glass   sandbox: Support ...
39
  #include <asm/io.h>
a68d3ed0a   wdenk   Initial revision
40

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
41
  DECLARE_GLOBAL_DATA_PTR;
2643c85da   Patrick Delaunay   env: enable savee...
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
  #if	defined(CONFIG_ENV_IS_IN_EEPROM)	|| \
  	defined(CONFIG_ENV_IS_IN_FLASH)		|| \
  	defined(CONFIG_ENV_IS_IN_MMC)		|| \
  	defined(CONFIG_ENV_IS_IN_FAT)		|| \
  	defined(CONFIG_ENV_IS_IN_EXT4)		|| \
  	defined(CONFIG_ENV_IS_IN_NAND)		|| \
  	defined(CONFIG_ENV_IS_IN_NVRAM)		|| \
  	defined(CONFIG_ENV_IS_IN_ONENAND)	|| \
  	defined(CONFIG_ENV_IS_IN_SATA)		|| \
  	defined(CONFIG_ENV_IS_IN_SPI_FLASH)	|| \
  	defined(CONFIG_ENV_IS_IN_REMOTE)	|| \
  	defined(CONFIG_ENV_IS_IN_UBI)
  
  #define ENV_IS_IN_DEVICE
  
  #endif
  
  #if	!defined(ENV_IS_IN_DEVICE)		&& \
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
60
  	!defined(CONFIG_ENV_IS_NOWHERE)
7b7341d7f   Tuomas Tynkkynen   env: Drop CONFIG_...
61
  # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|\
d1b88cd32   Lothar Waßmann   cmd: nvedit: brin...
62
  NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
a68d3ed0a   wdenk   Initial revision
63
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
64
65
66
67
  /*
   * Maximum expected input data size for import command
   */
  #define	MAX_ENV_SIZE	(1 << 20)	/* 1 MiB */
a68d3ed0a   wdenk   Initial revision
68

a68d3ed0a   wdenk   Initial revision
69
  /*
ea882baf9   Wolfgang Denk   New implementatio...
70
   * This variable is incremented on each do_env_set(), so it can
f1f0ae6a9   Simon Glass   env: Move get_env...
71
   * be used via env_get_id() as an indication, if the environment
da95427ce   Heiko Schocher   netloop: updates ...
72
73
74
75
   * has changed or not. So it is possible to reread an environment
   * variable only if the environment was changed ... done so for
   * example in NetInitLoop()
   */
2f70c49e5   Heiko Schocher   netloop: speed up...
76
  static int env_id = 1;
a68d3ed0a   wdenk   Initial revision
77

f1f0ae6a9   Simon Glass   env: Move get_env...
78
  int env_get_id(void)
2f70c49e5   Heiko Schocher   netloop: speed up...
79
80
81
  {
  	return env_id;
  }
a68d3ed0a   wdenk   Initial revision
82

7ac2fe2da   Ilya Yanok   OMAP: networking ...
83
  #ifndef CONFIG_SPL_BUILD
4c94f6c54   Mike Frysinger   nvedit: speed up ...
84
  /*
ea882baf9   Wolfgang Denk   New implementatio...
85
86
87
   * Command interface: print one or all environment variables
   *
   * Returns 0 in case of error, or length of printed string
4c94f6c54   Mike Frysinger   nvedit: speed up ...
88
   */
be11235ab   Joe Hershberger   env: Hide '.' var...
89
  static int env_print(char *name, int flag)
a68d3ed0a   wdenk   Initial revision
90
  {
ea882baf9   Wolfgang Denk   New implementatio...
91
  	char *res = NULL;
22a4a6c5c   Maxime Larocque   printenv: Correct...
92
  	ssize_t len;
ea882baf9   Wolfgang Denk   New implementatio...
93
94
  
  	if (name) {		/* print a single name */
dd2408cac   Simon Glass   env: Drop the ENT...
95
  		struct env_entry e, *ep;
ea882baf9   Wolfgang Denk   New implementatio...
96
97
98
  
  		e.key = name;
  		e.data = NULL;
3f0d68074   Simon Glass   env: Drop the ACT...
99
  		hsearch_r(e, ENV_FIND, &ep, &env_htab, flag);
ea882baf9   Wolfgang Denk   New implementatio...
100
101
  		if (ep == NULL)
  			return 0;
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
102
103
  		len = printf("%s=%s
  ", ep->key, ep->data);
ea882baf9   Wolfgang Denk   New implementatio...
104
105
  		return len;
  	}
a68d3ed0a   wdenk   Initial revision
106

ea882baf9   Wolfgang Denk   New implementatio...
107
  	/* print whole list */
be11235ab   Joe Hershberger   env: Hide '.' var...
108
109
  	len = hexport_r(&env_htab, '
  ', flag, &res, 0, 0, NULL);
a68d3ed0a   wdenk   Initial revision
110

ea882baf9   Wolfgang Denk   New implementatio...
111
112
113
114
  	if (len > 0) {
  		puts(res);
  		free(res);
  		return len;
a68d3ed0a   wdenk   Initial revision
115
  	}
ea882baf9   Wolfgang Denk   New implementatio...
116
  	/* should never happen */
22a4a6c5c   Maxime Larocque   printenv: Correct...
117
118
  	printf("## Error: cannot export environment
  ");
ea882baf9   Wolfgang Denk   New implementatio...
119
  	return 0;
4c94f6c54   Mike Frysinger   nvedit: speed up ...
120
  }
a68d3ed0a   wdenk   Initial revision
121

088f1b199   Kim Phillips   common/cmd_*.c: s...
122
123
  static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,
  			char * const argv[])
4c94f6c54   Mike Frysinger   nvedit: speed up ...
124
125
126
  {
  	int i;
  	int rcode = 0;
be11235ab   Joe Hershberger   env: Hide '.' var...
127
  	int env_flag = H_HIDE_DOT;
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
128
129
130
131
  #if defined(CONFIG_CMD_NVEDIT_EFI)
  	if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e')
  		return do_env_print_efi(cmdtp, flag, --argc, ++argv);
  #endif
be11235ab   Joe Hershberger   env: Hide '.' var...
132
133
134
135
136
  	if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'a') {
  		argc--;
  		argv++;
  		env_flag &= ~H_HIDE_DOT;
  	}
a68d3ed0a   wdenk   Initial revision
137

4c94f6c54   Mike Frysinger   nvedit: speed up ...
138
139
  	if (argc == 1) {
  		/* print all env vars */
be11235ab   Joe Hershberger   env: Hide '.' var...
140
  		rcode = env_print(NULL, env_flag);
ea882baf9   Wolfgang Denk   New implementatio...
141
  		if (!rcode)
4c94f6c54   Mike Frysinger   nvedit: speed up ...
142
143
144
145
146
147
148
  			return 1;
  		printf("
  Environment size: %d/%ld bytes
  ",
  			rcode, (ulong)ENV_SIZE);
  		return 0;
  	}
a68d3ed0a   wdenk   Initial revision
149

4c94f6c54   Mike Frysinger   nvedit: speed up ...
150
  	/* print selected env vars */
be11235ab   Joe Hershberger   env: Hide '.' var...
151
  	env_flag &= ~H_HIDE_DOT;
4c94f6c54   Mike Frysinger   nvedit: speed up ...
152
  	for (i = 1; i < argc; ++i) {
be11235ab   Joe Hershberger   env: Hide '.' var...
153
  		int rc = env_print(argv[i], env_flag);
ea882baf9   Wolfgang Denk   New implementatio...
154
155
156
  		if (!rc) {
  			printf("## Error: \"%s\" not defined
  ", argv[i]);
4c94f6c54   Mike Frysinger   nvedit: speed up ...
157
  			++rcode;
a68d3ed0a   wdenk   Initial revision
158
159
  		}
  	}
4c94f6c54   Mike Frysinger   nvedit: speed up ...
160

a68d3ed0a   wdenk   Initial revision
161
162
  	return rcode;
  }
a000b7950   Kim Phillips   common: add a gre...
163
  #ifdef CONFIG_CMD_GREPENV
d09b1787a   Igor Grinberg   env: clean cmd_nv...
164
165
  static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
  		       int argc, char * const argv[])
a000b7950   Kim Phillips   common: add a gre...
166
  {
5a31ea04c   Wolfgang Denk   "env grep" - reim...
167
  	char *res = NULL;
be29df6a1   Wolfgang Denk   "env grep" - add ...
168
  	int len, grep_how, grep_what;
a000b7950   Kim Phillips   common: add a gre...
169
170
  
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
171
  		return CMD_RET_USAGE;
a000b7950   Kim Phillips   common: add a gre...
172

be29df6a1   Wolfgang Denk   "env grep" - add ...
173
174
  	grep_how  = H_MATCH_SUBSTR;	/* default: substring search	*/
  	grep_what = H_MATCH_BOTH;	/* default: grep names and values */
d87244d5a   Wolfgang Denk   "env grep" - add ...
175

9a8323311   Pierre Aubert   env: fix the env ...
176
177
  	while (--argc > 0 && **++argv == '-') {
  		char *arg = *argv;
d87244d5a   Wolfgang Denk   "env grep" - add ...
178
179
  		while (*++arg) {
  			switch (*arg) {
be29df6a1   Wolfgang Denk   "env grep" - add ...
180
181
182
183
184
  #ifdef CONFIG_REGEX
  			case 'e':		/* use regex matching */
  				grep_how  = H_MATCH_REGEX;
  				break;
  #endif
d87244d5a   Wolfgang Denk   "env grep" - add ...
185
  			case 'n':		/* grep for name */
be29df6a1   Wolfgang Denk   "env grep" - add ...
186
  				grep_what = H_MATCH_KEY;
d87244d5a   Wolfgang Denk   "env grep" - add ...
187
188
  				break;
  			case 'v':		/* grep for value */
be29df6a1   Wolfgang Denk   "env grep" - add ...
189
  				grep_what = H_MATCH_DATA;
d87244d5a   Wolfgang Denk   "env grep" - add ...
190
191
  				break;
  			case 'b':		/* grep for both */
be29df6a1   Wolfgang Denk   "env grep" - add ...
192
  				grep_what = H_MATCH_BOTH;
d87244d5a   Wolfgang Denk   "env grep" - add ...
193
194
195
196
197
198
199
200
201
202
  				break;
  			case '-':
  				goto DONE;
  			default:
  				return CMD_RET_USAGE;
  			}
  		}
  	}
  
  DONE:
5a31ea04c   Wolfgang Denk   "env grep" - reim...
203
204
  	len = hexport_r(&env_htab, '
  ',
be29df6a1   Wolfgang Denk   "env grep" - add ...
205
  			flag | grep_what | grep_how,
5a31ea04c   Wolfgang Denk   "env grep" - reim...
206
  			&res, 0, argc, argv);
a000b7950   Kim Phillips   common: add a gre...
207

5a31ea04c   Wolfgang Denk   "env grep" - reim...
208
209
210
  	if (len > 0) {
  		puts(res);
  		free(res);
a000b7950   Kim Phillips   common: add a gre...
211
  	}
5a31ea04c   Wolfgang Denk   "env grep" - reim...
212
213
214
215
  	if (len < 2)
  		return 1;
  
  	return 0;
a000b7950   Kim Phillips   common: add a gre...
216
217
  }
  #endif
7ac2fe2da   Ilya Yanok   OMAP: networking ...
218
  #endif /* CONFIG_SPL_BUILD */
a000b7950   Kim Phillips   common: add a gre...
219

ea882baf9   Wolfgang Denk   New implementatio...
220
  /*
c3f652585   Gerlando Falauto   env: unify logic ...
221
222
   * Set a new environment variable,
   * or replace or delete an existing one.
2598090b7   Joe Hershberger   env: Add environm...
223
   */
94b467b14   Joe Hershberger   env: Distinguish ...
224
  static int _do_env_set(int flag, int argc, char * const argv[], int env_flag)
c3f652585   Gerlando Falauto   env: unify logic ...
225
226
227
  {
  	int   i, len;
  	char  *name, *value, *s;
dd2408cac   Simon Glass   env: Drop the ENT...
228
  	struct env_entry e, *ep;
c3f652585   Gerlando Falauto   env: unify logic ...
229

24ab5a191   Joe Hershberger   env: Add setenv f...
230
231
  	debug("Initial value for argc=%d
  ", argc);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
232
233
234
235
236
  
  #if CONFIG_IS_ENABLED(CMD_NVEDIT_EFI)
  	if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e')
  		return do_env_set_efi(NULL, flag, --argc, ++argv);
  #endif
24ab5a191   Joe Hershberger   env: Add setenv f...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
  	while (argc > 1 && **(argv + 1) == '-') {
  		char *arg = *++argv;
  
  		--argc;
  		while (*++arg) {
  			switch (*arg) {
  			case 'f':		/* force */
  				env_flag |= H_FORCE;
  				break;
  			default:
  				return CMD_RET_USAGE;
  			}
  		}
  	}
  	debug("Final value for argc=%d
  ", argc);
c3f652585   Gerlando Falauto   env: unify logic ...
253
  	name = argv[1];
c3f652585   Gerlando Falauto   env: unify logic ...
254
255
256
257
258
259
260
261
262
  
  	if (strchr(name, '=')) {
  		printf("## Error: illegal character '='"
  		       "in variable name \"%s\"
  ", name);
  		return 1;
  	}
  
  	env_id++;
c3f652585   Gerlando Falauto   env: unify logic ...
263

a68d3ed0a   wdenk   Initial revision
264
  	/* Delete only ? */
d09b1787a   Igor Grinberg   env: clean cmd_nv...
265
  	if (argc < 3 || argv[2] == NULL) {
24ab5a191   Joe Hershberger   env: Add setenv f...
266
  		int rc = hdelete_r(name, &env_htab, env_flag);
ea882baf9   Wolfgang Denk   New implementatio...
267
  		return !rc;
a68d3ed0a   wdenk   Initial revision
268
269
270
  	}
  
  	/*
ea882baf9   Wolfgang Denk   New implementatio...
271
  	 * Insert / replace new value
a68d3ed0a   wdenk   Initial revision
272
  	 */
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
273
  	for (i = 2, len = 0; i < argc; ++i)
a68d3ed0a   wdenk   Initial revision
274
  		len += strlen(argv[i]) + 1;
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
275
276
277
  
  	value = malloc(len);
  	if (value == NULL) {
ea882baf9   Wolfgang Denk   New implementatio...
278
279
  		printf("## Can't malloc %d bytes
  ", len);
a68d3ed0a   wdenk   Initial revision
280
281
  		return 1;
  	}
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
282
  	for (i = 2, s = value; i < argc; ++i) {
ea882baf9   Wolfgang Denk   New implementatio...
283
  		char *v = argv[i];
a68d3ed0a   wdenk   Initial revision
284

ea882baf9   Wolfgang Denk   New implementatio...
285
  		while ((*s++ = *v++) != '\0')
a68d3ed0a   wdenk   Initial revision
286
  			;
d09b1787a   Igor Grinberg   env: clean cmd_nv...
287
  		*(s - 1) = ' ';
ea882baf9   Wolfgang Denk   New implementatio...
288
289
290
  	}
  	if (s != value)
  		*--s = '\0';
d09b1787a   Igor Grinberg   env: clean cmd_nv...
291
292
  	e.key	= name;
  	e.data	= value;
3f0d68074   Simon Glass   env: Drop the ACT...
293
  	hsearch_r(e, ENV_ENTER, &ep, &env_htab, env_flag);
ea882baf9   Wolfgang Denk   New implementatio...
294
295
296
297
298
299
  	free(value);
  	if (!ep) {
  		printf("## Error inserting \"%s\" variable, errno=%d
  ",
  			name, errno);
  		return 1;
a68d3ed0a   wdenk   Initial revision
300
  	}
a68d3ed0a   wdenk   Initial revision
301

a68d3ed0a   wdenk   Initial revision
302
303
  	return 0;
  }
382bee57f   Simon Glass   env: Rename seten...
304
  int env_set(const char *varname, const char *varvalue)
a68d3ed0a   wdenk   Initial revision
305
  {
84b5e8022   Wolfgang Denk   Constify getenv()...
306
  	const char * const argv[4] = { "setenv", varname, varvalue, NULL };
a7eb1d66c   Joe Hershberger   mtd: Make mtdpart...
307
308
309
  	/* before import into hashtable */
  	if (!(gd->flags & GD_FLG_ENV_READY))
  		return 1;
d09b1787a   Igor Grinberg   env: clean cmd_nv...
310
  	if (varvalue == NULL || varvalue[0] == '\0')
94b467b14   Joe Hershberger   env: Distinguish ...
311
  		return _do_env_set(0, 2, (char * const *)argv, H_PROGRAMMATIC);
9ffd451af   Jeffrey Mann   [patch] setenv(.....
312
  	else
94b467b14   Joe Hershberger   env: Distinguish ...
313
  		return _do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC);
a68d3ed0a   wdenk   Initial revision
314
  }
d67f10ce0   Simon Glass   Add setenv_ulong(...
315
316
317
  /**
   * Set an environment variable to an integer value
   *
9602286d3   Simon Glass   env: Fix minor co...
318
   * @param varname	Environment variable to set
d67f10ce0   Simon Glass   Add setenv_ulong(...
319
320
321
   * @param value		Value to set it to
   * @return 0 if ok, 1 on error
   */
018f53032   Simon Glass   env: Rename commo...
322
  int env_set_ulong(const char *varname, ulong value)
d67f10ce0   Simon Glass   Add setenv_ulong(...
323
324
325
  {
  	/* TODO: this should be unsigned */
  	char *str = simple_itoa(value);
382bee57f   Simon Glass   env: Rename seten...
326
  	return env_set(varname, str);
d67f10ce0   Simon Glass   Add setenv_ulong(...
327
328
329
  }
  
  /**
bfc599664   Simon Glass   Update set_workin...
330
   * Set an environment variable to an value in hex
d67f10ce0   Simon Glass   Add setenv_ulong(...
331
   *
9602286d3   Simon Glass   env: Fix minor co...
332
   * @param varname	Environment variable to set
bfc599664   Simon Glass   Update set_workin...
333
   * @param value		Value to set it to
d67f10ce0   Simon Glass   Add setenv_ulong(...
334
335
   * @return 0 if ok, 1 on error
   */
018f53032   Simon Glass   env: Rename commo...
336
  int env_set_hex(const char *varname, ulong value)
d67f10ce0   Simon Glass   Add setenv_ulong(...
337
338
  {
  	char str[17];
bfc599664   Simon Glass   Update set_workin...
339
  	sprintf(str, "%lx", value);
382bee57f   Simon Glass   env: Rename seten...
340
  	return env_set(varname, str);
d67f10ce0   Simon Glass   Add setenv_ulong(...
341
  }
bfebc8c96   Simon Glass   env: Rename geten...
342
  ulong env_get_hex(const char *varname, ulong default_val)
76b8f79c2   Simon Glass   Add getenv_hex() ...
343
344
345
346
  {
  	const char *s;
  	ulong value;
  	char *endp;
00caae6d4   Simon Glass   env: Rename geten...
347
  	s = env_get(varname);
76b8f79c2   Simon Glass   Add getenv_hex() ...
348
349
350
351
352
353
354
  	if (s)
  		value = simple_strtoul(s, &endp, 16);
  	if (!s || endp == s)
  		return default_val;
  
  	return value;
  }
9925f1dbc   Alex Kiernan   net: Move enetadd...
355
356
  int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr)
  {
fb8977c5b   Joe Hershberger   net: Always build...
357
  	string_to_enetaddr(env_get(name), enetaddr);
9925f1dbc   Alex Kiernan   net: Move enetadd...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  	return is_valid_ethaddr(enetaddr);
  }
  
  int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr)
  {
  	char buf[ARP_HLEN_ASCII + 1];
  
  	if (eth_env_get_enetaddr(name, (uint8_t *)buf))
  		return -EEXIST;
  
  	sprintf(buf, "%pM", enetaddr);
  
  	return env_set(name, buf);
  }
7ac2fe2da   Ilya Yanok   OMAP: networking ...
372
  #ifndef CONFIG_SPL_BUILD
088f1b199   Kim Phillips   common/cmd_*.c: s...
373
  static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
a68d3ed0a   wdenk   Initial revision
374
  {
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
375
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
376
  		return CMD_RET_USAGE;
a68d3ed0a   wdenk   Initial revision
377

94b467b14   Joe Hershberger   env: Distinguish ...
378
  	return _do_env_set(flag, argc, argv, H_INTERACTIVE);
a68d3ed0a   wdenk   Initial revision
379
  }
ea882baf9   Wolfgang Denk   New implementatio...
380
  /*
a68d3ed0a   wdenk   Initial revision
381
382
   * Prompt for environment variable
   */
c76fe4742   Jon Loeliger   common/cmd_[i-n]*...
383
  #if defined(CONFIG_CMD_ASKENV)
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
384
  int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
a68d3ed0a   wdenk   Initial revision
385
  {
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
386
  	char message[CONFIG_SYS_CBSIZE];
7d85591dd   Wolfgang Denk   env: fix "env ask...
387
  	int i, len, pos, size;
a68d3ed0a   wdenk   Initial revision
388
  	char *local_args[4];
7d85591dd   Wolfgang Denk   env: fix "env ask...
389
  	char *endptr;
a68d3ed0a   wdenk   Initial revision
390
391
392
393
394
  
  	local_args[0] = argv[0];
  	local_args[1] = argv[1];
  	local_args[2] = NULL;
  	local_args[3] = NULL;
7d85591dd   Wolfgang Denk   env: fix "env ask...
395
396
397
398
399
400
  	/*
  	 * Check the syntax:
  	 *
  	 * env_ask envname [message1 ...] [size]
  	 */
  	if (argc == 1)
4c12eeb8b   Simon Glass   Convert cmd_usage...
401
  		return CMD_RET_USAGE;
a68d3ed0a   wdenk   Initial revision
402

7d85591dd   Wolfgang Denk   env: fix "env ask...
403
404
405
406
407
408
409
410
411
412
413
414
415
  	/*
  	 * We test the last argument if it can be converted
  	 * into a decimal number.  If yes, we assume it's
  	 * the size.  Otherwise we echo it as part of the
  	 * message.
  	 */
  	i = simple_strtoul(argv[argc - 1], &endptr, 10);
  	if (*endptr != '\0') {			/* no size */
  		size = CONFIG_SYS_CBSIZE - 1;
  	} else {				/* size given */
  		size = i;
  		--argc;
  	}
a68d3ed0a   wdenk   Initial revision
416

7d85591dd   Wolfgang Denk   env: fix "env ask...
417
418
419
420
  	if (argc <= 2) {
  		sprintf(message, "Please enter '%s': ", argv[1]);
  	} else {
  		/* env_ask envname message1 ... messagen [size] */
bf52fcdef   Tom Rini   cmd/gpt.c, cmd/nv...
421
  		for (i = 2, pos = 0; i < argc && pos+1 < sizeof(message); i++) {
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
422
  			if (pos)
a68d3ed0a   wdenk   Initial revision
423
  				message[pos++] = ' ';
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
424

c667723ff   Tom Rini   cmd/nvedit.c: Upd...
425
  			strncpy(message + pos, argv[i], sizeof(message) - pos);
a68d3ed0a   wdenk   Initial revision
426
427
  			pos += strlen(argv[i]);
  		}
c667723ff   Tom Rini   cmd/nvedit.c: Upd...
428
429
430
431
432
  		if (pos < sizeof(message) - 1) {
  			message[pos++] = ' ';
  			message[pos] = '\0';
  		} else
  			message[CONFIG_SYS_CBSIZE - 1] = '\0';
a68d3ed0a   wdenk   Initial revision
433
  	}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
434
435
  	if (size >= CONFIG_SYS_CBSIZE)
  		size = CONFIG_SYS_CBSIZE - 1;
a68d3ed0a   wdenk   Initial revision
436
437
438
439
440
  
  	if (size <= 0)
  		return 1;
  
  	/* prompt for input */
e1bf824df   Simon Glass   Add cli_ prefix t...
441
  	len = cli_readline(message);
a68d3ed0a   wdenk   Initial revision
442
443
444
445
446
447
448
449
450
451
452
  
  	if (size < len)
  		console_buffer[size] = '\0';
  
  	len = 2;
  	if (console_buffer[0] != '\0') {
  		local_args[2] = console_buffer;
  		len = 3;
  	}
  
  	/* Continue calling setenv code */
94b467b14   Joe Hershberger   env: Distinguish ...
453
  	return _do_env_set(flag, len, local_args, H_INTERACTIVE);
a68d3ed0a   wdenk   Initial revision
454
  }
902531788   Jon Loeliger   common/: Remove l...
455
  #endif
a68d3ed0a   wdenk   Initial revision
456

5e2b3e0c5   Joe Hershberger   env: Add a comman...
457
  #if defined(CONFIG_CMD_ENV_CALLBACK)
cca98fd6a   Joe Hershberger   env: Allow env_at...
458
459
  static int print_static_binding(const char *var_name, const char *callback_name,
  				void *priv)
5e2b3e0c5   Joe Hershberger   env: Add a comman...
460
461
462
463
464
465
  {
  	printf("\t%-20s %-20s
  ", var_name, callback_name);
  
  	return 0;
  }
dd2408cac   Simon Glass   env: Drop the ENT...
466
  static int print_active_callback(struct env_entry *entry)
5e2b3e0c5   Joe Hershberger   env: Add a comman...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  {
  	struct env_clbk_tbl *clbkp;
  	int i;
  	int num_callbacks;
  
  	if (entry->callback == NULL)
  		return 0;
  
  	/* look up the callback in the linker-list */
  	num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
  	for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
  	     i < num_callbacks;
  	     i++, clbkp++) {
  #if defined(CONFIG_NEEDS_MANUAL_RELOC)
  		if (entry->callback == clbkp->callback + gd->reloc_off)
  #else
  		if (entry->callback == clbkp->callback)
  #endif
  			break;
  	}
  
  	if (i == num_callbacks)
  		/* this should probably never happen, but just in case... */
  		printf("\t%-20s %p
  ", entry->key, entry->callback);
  	else
  		printf("\t%-20s %-20s
  ", entry->key, clbkp->name);
  
  	return 0;
  }
  
  /*
   * Print the callbacks available and what they are bound to
   */
  int do_env_callback(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
  	struct env_clbk_tbl *clbkp;
  	int i;
  	int num_callbacks;
  
  	/* Print the available callbacks */
  	puts("Available callbacks:
  ");
  	puts("\tCallback Name
  ");
  	puts("\t-------------
  ");
  	num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
  	for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
  	     i < num_callbacks;
  	     i++, clbkp++)
  		printf("\t%s
  ", clbkp->name);
  	puts("
  ");
  
  	/* Print the static bindings that may exist */
  	puts("Static callback bindings:
  ");
  	printf("\t%-20s %-20s
  ", "Variable Name", "Callback Name");
  	printf("\t%-20s %-20s
  ", "-------------", "-------------");
cca98fd6a   Joe Hershberger   env: Allow env_at...
531
  	env_attr_walk(ENV_CALLBACK_LIST_STATIC, print_static_binding, NULL);
5e2b3e0c5   Joe Hershberger   env: Add a comman...
532
533
534
535
536
537
538
539
540
541
542
543
544
545
  	puts("
  ");
  
  	/* walk through each variable and print the callback if it has one */
  	puts("Active callback bindings:
  ");
  	printf("\t%-20s %-20s
  ", "Variable Name", "Callback Name");
  	printf("\t%-20s %-20s
  ", "-------------", "-------------");
  	hwalk_r(&env_htab, print_active_callback);
  	return 0;
  }
  #endif
fffad71bc   Joe Hershberger   env: Add a comman...
546
  #if defined(CONFIG_CMD_ENV_FLAGS)
cca98fd6a   Joe Hershberger   env: Allow env_at...
547
548
  static int print_static_flags(const char *var_name, const char *flags,
  			      void *priv)
fffad71bc   Joe Hershberger   env: Add a comman...
549
550
  {
  	enum env_flags_vartype type = env_flags_parse_vartype(flags);
267541f77   Joe Hershberger   env: Add support ...
551
  	enum env_flags_varaccess access = env_flags_parse_varaccess(flags);
fffad71bc   Joe Hershberger   env: Add a comman...
552

267541f77   Joe Hershberger   env: Add support ...
553
554
555
556
  	printf("\t%-20s %-20s %-20s
  ", var_name,
  		env_flags_get_vartype_name(type),
  		env_flags_get_varaccess_name(access));
fffad71bc   Joe Hershberger   env: Add a comman...
557
558
559
  
  	return 0;
  }
dd2408cac   Simon Glass   env: Drop the ENT...
560
  static int print_active_flags(struct env_entry *entry)
fffad71bc   Joe Hershberger   env: Add a comman...
561
562
  {
  	enum env_flags_vartype type;
267541f77   Joe Hershberger   env: Add support ...
563
  	enum env_flags_varaccess access;
fffad71bc   Joe Hershberger   env: Add a comman...
564
565
566
567
568
569
  
  	if (entry->flags == 0)
  		return 0;
  
  	type = (enum env_flags_vartype)
  		(entry->flags & ENV_FLAGS_VARTYPE_BIN_MASK);
267541f77   Joe Hershberger   env: Add support ...
570
571
572
573
574
  	access = env_flags_parse_varaccess_from_binflags(entry->flags);
  	printf("\t%-20s %-20s %-20s
  ", entry->key,
  		env_flags_get_vartype_name(type),
  		env_flags_get_varaccess_name(access));
fffad71bc   Joe Hershberger   env: Add a comman...
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
  
  	return 0;
  }
  
  /*
   * Print the flags available and what variables have flags
   */
  int do_env_flags(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
  	/* Print the available variable types */
  	printf("Available variable type flags (position %d):
  ",
  		ENV_FLAGS_VARTYPE_LOC);
  	puts("\tFlag\tVariable Type Name
  ");
  	puts("\t----\t------------------
  ");
  	env_flags_print_vartypes();
  	puts("
  ");
267541f77   Joe Hershberger   env: Add support ...
595
596
597
598
599
600
601
602
603
604
605
  	/* Print the available variable access types */
  	printf("Available variable access flags (position %d):
  ",
  		ENV_FLAGS_VARACCESS_LOC);
  	puts("\tFlag\tVariable Access Name
  ");
  	puts("\t----\t--------------------
  ");
  	env_flags_print_varaccess();
  	puts("
  ");
fffad71bc   Joe Hershberger   env: Add a comman...
606
607
608
  	/* Print the static flags that may exist */
  	puts("Static flags:
  ");
267541f77   Joe Hershberger   env: Add support ...
609
610
611
612
613
614
  	printf("\t%-20s %-20s %-20s
  ", "Variable Name", "Variable Type",
  		"Variable Access");
  	printf("\t%-20s %-20s %-20s
  ", "-------------", "-------------",
  		"---------------");
cca98fd6a   Joe Hershberger   env: Allow env_at...
615
  	env_attr_walk(ENV_FLAGS_LIST_STATIC, print_static_flags, NULL);
fffad71bc   Joe Hershberger   env: Add a comman...
616
617
618
619
620
621
  	puts("
  ");
  
  	/* walk through each variable and print the flags if non-default */
  	puts("Active flags:
  ");
267541f77   Joe Hershberger   env: Add support ...
622
623
624
625
626
627
  	printf("\t%-20s %-20s %-20s
  ", "Variable Name", "Variable Type",
  		"Variable Access");
  	printf("\t%-20s %-20s %-20s
  ", "-------------", "-------------",
  		"---------------");
fffad71bc   Joe Hershberger   env: Add a comman...
628
629
630
631
  	hwalk_r(&env_htab, print_active_flags);
  	return 0;
  }
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
632
  /*
246c69225   Peter Tyser   Add 'editenv' com...
633
634
635
   * Interactively edit an environment variable
   */
  #if defined(CONFIG_CMD_EDITENV)
088f1b199   Kim Phillips   common/cmd_*.c: s...
636
637
  static int do_env_edit(cmd_tbl_t *cmdtp, int flag, int argc,
  		       char * const argv[])
246c69225   Peter Tyser   Add 'editenv' com...
638
639
640
  {
  	char buffer[CONFIG_SYS_CBSIZE];
  	char *init_val;
246c69225   Peter Tyser   Add 'editenv' com...
641

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
642
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
643
  		return CMD_RET_USAGE;
246c69225   Peter Tyser   Add 'editenv' com...
644

94b467b14   Joe Hershberger   env: Distinguish ...
645
646
647
  	/* before import into hashtable */
  	if (!(gd->flags & GD_FLG_ENV_READY))
  		return 1;
246c69225   Peter Tyser   Add 'editenv' com...
648
  	/* Set read buffer to initial value or empty sting */
00caae6d4   Simon Glass   env: Rename geten...
649
  	init_val = env_get(argv[1]);
246c69225   Peter Tyser   Add 'editenv' com...
650
  	if (init_val)
5d49b4cdf   Peng Fan   common: nvedit: u...
651
  		snprintf(buffer, CONFIG_SYS_CBSIZE, "%s", init_val);
246c69225   Peter Tyser   Add 'editenv' com...
652
653
  	else
  		buffer[0] = '\0';
e1bf824df   Simon Glass   Add cli_ prefix t...
654
  	if (cli_readline_into_buffer("edit: ", buffer, 0) < 0)
18a3cce9f   Joe Hershberger   env: Avoid clobbe...
655
  		return 1;
246c69225   Peter Tyser   Add 'editenv' com...
656

94b467b14   Joe Hershberger   env: Distinguish ...
657
658
659
660
661
662
663
664
665
666
  	if (buffer[0] == '\0') {
  		const char * const _argv[3] = { "setenv", argv[1], NULL };
  
  		return _do_env_set(0, 2, (char * const *)_argv, H_INTERACTIVE);
  	} else {
  		const char * const _argv[4] = { "setenv", argv[1], buffer,
  			NULL };
  
  		return _do_env_set(0, 3, (char * const *)_argv, H_INTERACTIVE);
  	}
246c69225   Peter Tyser   Add 'editenv' com...
667
668
  }
  #endif /* CONFIG_CMD_EDITENV */
7ac2fe2da   Ilya Yanok   OMAP: networking ...
669
  #endif /* CONFIG_SPL_BUILD */
246c69225   Peter Tyser   Add 'editenv' com...
670

ea882baf9   Wolfgang Denk   New implementatio...
671
  /*
a68d3ed0a   wdenk   Initial revision
672
673
674
675
   * Look up variable from environment,
   * return address of storage for that variable,
   * or NULL if not found
   */
00caae6d4   Simon Glass   env: Rename geten...
676
  char *env_get(const char *name)
a68d3ed0a   wdenk   Initial revision
677
  {
d09b1787a   Igor Grinberg   env: clean cmd_nv...
678
  	if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */
dd2408cac   Simon Glass   env: Drop the ENT...
679
  		struct env_entry e, *ep;
a68d3ed0a   wdenk   Initial revision
680

91a76751a   Wolfgang Denk   Make getenv() wor...
681
  		WATCHDOG_RESET();
2a3cb0207   wdenk   Quick & Dirty fix...
682

d09b1787a   Igor Grinberg   env: clean cmd_nv...
683
684
  		e.key	= name;
  		e.data	= NULL;
3f0d68074   Simon Glass   env: Drop the ACT...
685
  		hsearch_r(e, ENV_FIND, &ep, &env_htab, 0);
91a76751a   Wolfgang Denk   Make getenv() wor...
686

f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
687
  		return ep ? ep->data : NULL;
a68d3ed0a   wdenk   Initial revision
688
  	}
ea882baf9   Wolfgang Denk   New implementatio...
689
  	/* restricted capabilities before import */
00caae6d4   Simon Glass   env: Rename geten...
690
  	if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)
ea882baf9   Wolfgang Denk   New implementatio...
691
  		return (char *)(gd->env_buf);
91a76751a   Wolfgang Denk   Make getenv() wor...
692

ea882baf9   Wolfgang Denk   New implementatio...
693
  	return NULL;
a68d3ed0a   wdenk   Initial revision
694
  }
ea882baf9   Wolfgang Denk   New implementatio...
695
  /*
1ac2cb974   Patrice Chotard   cmd: Migrate from...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
   * Like env_get, but prints an error if envvar isn't defined in the
   * environment.  It always returns what env_get does, so it can be used in
   * place of env_get without changing error handling otherwise.
   */
  char *from_env(const char *envvar)
  {
  	char *ret;
  
  	ret = env_get(envvar);
  
  	if (!ret)
  		printf("missing environment variable: %s
  ", envvar);
  
  	return ret;
  }
  
  /*
ea882baf9   Wolfgang Denk   New implementatio...
714
715
   * Look up variable from environment for restricted C runtime env.
   */
00caae6d4   Simon Glass   env: Rename geten...
716
  int env_get_f(const char *name, char *buf, unsigned len)
a68d3ed0a   wdenk   Initial revision
717
  {
87c7fb396   Simon Goldschmidt   cmd: nvedit: env_...
718
  	int i, nxt, c;
a68d3ed0a   wdenk   Initial revision
719

d09b1787a   Igor Grinberg   env: clean cmd_nv...
720
  	for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
a68d3ed0a   wdenk   Initial revision
721
  		int val, n;
87c7fb396   Simon Goldschmidt   cmd: nvedit: env_...
722
723
724
  		for (nxt = i; (c = env_get_char(nxt)) != '\0'; ++nxt) {
  			if (c < 0)
  				return c;
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
725
726
  			if (nxt >= CONFIG_ENV_SIZE)
  				return -1;
a68d3ed0a   wdenk   Initial revision
727
  		}
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
728

b9ca02c2d   Simon Glass   env: Move envmatc...
729
  		val = env_match((uchar *)name, i);
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
730
  		if (val < 0)
a68d3ed0a   wdenk   Initial revision
731
  			continue;
9ed4a9582   Wolfgang Denk   getenv_f(): fix h...
732

a68d3ed0a   wdenk   Initial revision
733
  		/* found; copy out */
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
734
  		for (n = 0; n < len; ++n, ++buf) {
87c7fb396   Simon Goldschmidt   cmd: nvedit: env_...
735
736
737
738
  			c = env_get_char(val++);
  			if (c < 0)
  				return c;
  			*buf = c;
d09b1787a   Igor Grinberg   env: clean cmd_nv...
739
  			if (*buf == '\0')
9ed4a9582   Wolfgang Denk   getenv_f(): fix h...
740
741
742
743
744
  				return n;
  		}
  
  		if (n)
  			*--buf = '\0';
82919517f   Heinrich Schuchardt   cmd: nvedit: use ...
745
746
747
  		printf("env_buf [%u bytes] too small for value of \"%s\"
  ",
  		       len, name);
9ed4a9582   Wolfgang Denk   getenv_f(): fix h...
748
749
  
  		return n;
a68d3ed0a   wdenk   Initial revision
750
  	}
d09b1787a   Igor Grinberg   env: clean cmd_nv...
751

f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
752
  	return -1;
a68d3ed0a   wdenk   Initial revision
753
  }
4a9b41310   Simon Glass   Add getenv_ulong(...
754
755
756
  /**
   * Decode the integer value of an environment variable and return it.
   *
919d25c92   Shyam Saini   u-boot: Fix sever...
757
   * @param name		Name of environment variable
4a9b41310   Simon Glass   Add getenv_ulong(...
758
759
760
761
762
   * @param base		Number base to use (normally 10, or 16 for hex)
   * @param default_val	Default value to return if the variable is not
   *			found
   * @return the decoded value, or default_val if not found
   */
bfebc8c96   Simon Glass   env: Rename geten...
763
  ulong env_get_ulong(const char *name, int base, ulong default_val)
4a9b41310   Simon Glass   Add getenv_ulong(...
764
765
  {
  	/*
00caae6d4   Simon Glass   env: Rename geten...
766
  	 * We can use env_get() here, even before relocation, since the
4a9b41310   Simon Glass   Add getenv_ulong(...
767
768
  	 * environment variable value is an integer and thus short.
  	 */
00caae6d4   Simon Glass   env: Rename geten...
769
  	const char *str = env_get(name);
4a9b41310   Simon Glass   Add getenv_ulong(...
770
771
772
  
  	return str ? simple_strtoul(str, NULL, base) : default_val;
  }
7ac2fe2da   Ilya Yanok   OMAP: networking ...
773
  #ifndef CONFIG_SPL_BUILD
2643c85da   Patrick Delaunay   env: enable savee...
774
  #if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
088f1b199   Kim Phillips   common/cmd_*.c: s...
775
776
  static int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc,
  		       char * const argv[])
a68d3ed0a   wdenk   Initial revision
777
  {
01510091d   Simon Glass   env: Drop saveenv...
778
  	return env_save() ? 1 : 0;
a68d3ed0a   wdenk   Initial revision
779
  }
8bde7f776   wdenk   * Code cleanup:
780

ba69dc26a   Mike Frysinger   saveenv: standard...
781
  U_BOOT_CMD(
ea882baf9   Wolfgang Denk   New implementatio...
782
  	saveenv, 1, 0,	do_env_save,
2fb2604d5   Peter Tyser   Command usage cle...
783
  	"save environment variables to persistent storage",
a89c33db9   Wolfgang Denk   General help mess...
784
  	""
ba69dc26a   Mike Frysinger   saveenv: standard...
785
  );
cd121bdb6   Frank Wunderlich   env: register era...
786
787
788
789
790
791
792
793
794
795
796
797
798
799
  
  #if defined(CONFIG_CMD_ERASEENV)
  static int do_env_erase(cmd_tbl_t *cmdtp, int flag, int argc,
  			char * const argv[])
  {
  	return env_erase() ? 1 : 0;
  }
  
  U_BOOT_CMD(
  	eraseenv, 1, 0,	do_env_erase,
  	"erase environment variables from persistent storage",
  	""
  );
  #endif
a68d3ed0a   wdenk   Initial revision
800
  #endif
7ac2fe2da   Ilya Yanok   OMAP: networking ...
801
  #endif /* CONFIG_SPL_BUILD */
a68d3ed0a   wdenk   Initial revision
802

b9ca02c2d   Simon Glass   env: Move envmatc...
803
  int env_match(uchar *s1, int i2)
a68d3ed0a   wdenk   Initial revision
804
  {
586197dfe   Joe Hershberger   env: Check for NU...
805
806
  	if (s1 == NULL)
  		return -1;
a68d3ed0a   wdenk   Initial revision
807
808
  	while (*s1 == env_get_char(i2++))
  		if (*s1++ == '=')
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
809
  			return i2;
d09b1787a   Igor Grinberg   env: clean cmd_nv...
810

a68d3ed0a   wdenk   Initial revision
811
  	if (*s1 == '\0' && env_get_char(i2-1) == '=')
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
812
  		return i2;
d09b1787a   Igor Grinberg   env: clean cmd_nv...
813

f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
814
  	return -1;
a68d3ed0a   wdenk   Initial revision
815
  }
8bde7f776   wdenk   * Code cleanup:
816

7ac2fe2da   Ilya Yanok   OMAP: networking ...
817
  #ifndef CONFIG_SPL_BUILD
30091494e   Yaniv Levinsky   cmd: nvedit: rena...
818
  static int do_env_default(cmd_tbl_t *cmdtp, int flag,
d09b1787a   Igor Grinberg   env: clean cmd_nv...
819
  			  int argc, char * const argv[])
ea882baf9   Wolfgang Denk   New implementatio...
820
  {
5a04264ec   Yaniv Levinsky   cmd: nvedit: set ...
821
  	int all = 0, env_flag = H_INTERACTIVE;
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
822

b64b7c3df   Gerlando Falauto   env: make "env de...
823
824
825
826
827
828
829
830
831
832
833
  	debug("Initial value for argc=%d
  ", argc);
  	while (--argc > 0 && **++argv == '-') {
  		char *arg = *argv;
  
  		while (*++arg) {
  			switch (*arg) {
  			case 'a':		/* default all */
  				all = 1;
  				break;
  			case 'f':		/* force */
30091494e   Yaniv Levinsky   cmd: nvedit: rena...
834
  				env_flag |= H_FORCE;
b64b7c3df   Gerlando Falauto   env: make "env de...
835
836
837
838
839
840
841
842
843
844
  				break;
  			default:
  				return cmd_usage(cmdtp);
  			}
  		}
  	}
  	debug("Final value for argc=%d
  ", argc);
  	if (all && (argc == 0)) {
  		/* Reset the whole environment */
0ac7d722e   Simon Glass   env: Move get/set...
845
846
  		env_set_default("## Resetting to default environment
  ",
c5d548a9f   Yaniv Levinsky   env: common: acce...
847
  				env_flag);
b64b7c3df   Gerlando Falauto   env: make "env de...
848
849
850
851
  		return 0;
  	}
  	if (!all && (argc > 0)) {
  		/* Reset individual variables */
0b9d8a055   Simon Glass   env: Move set_def...
852
  		env_set_default_vars(argc, argv, env_flag);
b64b7c3df   Gerlando Falauto   env: make "env de...
853
854
855
856
  		return 0;
  	}
  
  	return cmd_usage(cmdtp);
ea882baf9   Wolfgang Denk   New implementatio...
857
  }
d09b1787a   Igor Grinberg   env: clean cmd_nv...
858
859
  static int do_env_delete(cmd_tbl_t *cmdtp, int flag,
  			 int argc, char * const argv[])
ea882baf9   Wolfgang Denk   New implementatio...
860
  {
9d8d661d7   Joe Hershberger   env: Implement th...
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
  	int env_flag = H_INTERACTIVE;
  	int ret = 0;
  
  	debug("Initial value for argc=%d
  ", argc);
  	while (argc > 1 && **(argv + 1) == '-') {
  		char *arg = *++argv;
  
  		--argc;
  		while (*++arg) {
  			switch (*arg) {
  			case 'f':		/* force */
  				env_flag |= H_FORCE;
  				break;
  			default:
  				return CMD_RET_USAGE;
  			}
  		}
  	}
  	debug("Final value for argc=%d
  ", argc);
  
  	env_id++;
  
  	while (--argc > 0) {
  		char *name = *++argv;
  
  		if (!hdelete_r(name, &env_htab, env_flag))
  			ret = 1;
  	}
  
  	return ret;
ea882baf9   Wolfgang Denk   New implementatio...
893
  }
0c79cda01   Mike Frysinger   env: make import/...
894
  #ifdef CONFIG_CMD_EXPORTENV
ea882baf9   Wolfgang Denk   New implementatio...
895
  /*
37f2fe747   Wolfgang Denk   env: allow to exp...
896
   * env export [-t | -b | -c] [-s size] addr [var ...]
ea882baf9   Wolfgang Denk   New implementatio...
897
898
899
900
901
902
903
904
905
   *	-t:	export as text format; if size is given, data will be
   *		padded with '\0' bytes; if not, one terminating '\0'
   *		will be added (which is included in the "filesize"
   *		setting so you can for exmple copy this to flash and
   *		keep the termination).
   *	-b:	export as binary format (name=value pairs separated by
   *		'\0', list end marked by double "\0\0")
   *	-c:	export as checksum protected environment format as
   *		used for example by "saveenv" command
37f2fe747   Wolfgang Denk   env: allow to exp...
906
907
   *	-s size:
   *		size of output buffer
ea882baf9   Wolfgang Denk   New implementatio...
908
   *	addr:	memory address where environment gets stored
37f2fe747   Wolfgang Denk   env: allow to exp...
909
910
911
   *	var...	List of variable names that get included into the
   *		export. Without arguments, the whole environment gets
   *		exported.
ea882baf9   Wolfgang Denk   New implementatio...
912
913
914
915
   *
   * With "-c" and size is NOT given, then the export command will
   * format the data as currently used for the persistent storage,
   * i. e. it will use CONFIG_ENV_SECT_SIZE as output block size and
fc0b5948e   Robert P. J. Day   Various, accumula...
916
   * prepend a valid CRC32 checksum and, in case of redundant
ea882baf9   Wolfgang Denk   New implementatio...
917
918
919
920
921
922
923
924
   * environment, a "current" redundancy flag. If size is given, this
   * value will be used instead of CONFIG_ENV_SECT_SIZE; again, CRC32
   * checksum and redundancy flag will be inserted.
   *
   * With "-b" and "-t", always only the real data (including a
   * terminating '\0' byte) will be written; here the optional size
   * argument will be used to make sure not to overflow the user
   * provided buffer; the command will abort if the size is not
fc0b5948e   Robert P. J. Day   Various, accumula...
925
   * sufficient. Any remaining space will be '\0' padded.
ea882baf9   Wolfgang Denk   New implementatio...
926
927
928
929
   *
   * On successful return, the variable "filesize" will be set.
   * Note that filesize includes the trailing/terminating '\0' byte(s).
   *
fc0b5948e   Robert P. J. Day   Various, accumula...
930
   * Usage scenario:  create a text snapshot/backup of the current settings:
ea882baf9   Wolfgang Denk   New implementatio...
931
932
933
934
935
936
937
938
939
   *
   *	=> env export -t 100000
   *	=> era ${backup_addr} +${filesize}
   *	=> cp.b 100000 ${backup_addr} ${filesize}
   *
   * Re-import this snapshot, deleting all other settings:
   *
   *	=> env import -d -t ${backup_addr}
   */
d09b1787a   Igor Grinberg   env: clean cmd_nv...
940
941
  static int do_env_export(cmd_tbl_t *cmdtp, int flag,
  			 int argc, char * const argv[])
ea882baf9   Wolfgang Denk   New implementatio...
942
943
  {
  	char	buf[32];
fd37dac9e   Simon Glass   sandbox: Support ...
944
945
  	ulong	addr;
  	char	*ptr, *cmd, *res;
37f2fe747   Wolfgang Denk   env: allow to exp...
946
  	size_t	size = 0;
ea882baf9   Wolfgang Denk   New implementatio...
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
  	ssize_t	len;
  	env_t	*envp;
  	char	sep = '
  ';
  	int	chk = 0;
  	int	fmt = 0;
  
  	cmd = *argv;
  
  	while (--argc > 0 && **++argv == '-') {
  		char *arg = *argv;
  		while (*++arg) {
  			switch (*arg) {
  			case 'b':		/* raw binary format */
  				if (fmt++)
  					goto sep_err;
  				sep = '\0';
  				break;
  			case 'c':		/* external checksum format */
  				if (fmt++)
  					goto sep_err;
  				sep = '\0';
  				chk = 1;
  				break;
37f2fe747   Wolfgang Denk   env: allow to exp...
971
972
973
974
975
  			case 's':		/* size given */
  				if (--argc <= 0)
  					return cmd_usage(cmdtp);
  				size = simple_strtoul(*++argv, NULL, 16);
  				goto NXTARG;
ea882baf9   Wolfgang Denk   New implementatio...
976
977
978
979
980
981
982
  			case 't':		/* text format */
  				if (fmt++)
  					goto sep_err;
  				sep = '
  ';
  				break;
  			default:
4c12eeb8b   Simon Glass   Convert cmd_usage...
983
  				return CMD_RET_USAGE;
ea882baf9   Wolfgang Denk   New implementatio...
984
985
  			}
  		}
37f2fe747   Wolfgang Denk   env: allow to exp...
986
  NXTARG:		;
ea882baf9   Wolfgang Denk   New implementatio...
987
  	}
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
988
  	if (argc < 1)
4c12eeb8b   Simon Glass   Convert cmd_usage...
989
  		return CMD_RET_USAGE;
8bde7f776   wdenk   * Code cleanup:
990

fd37dac9e   Simon Glass   sandbox: Support ...
991
992
  	addr = simple_strtoul(argv[0], NULL, 16);
  	ptr = map_sysmem(addr, size);
ea882baf9   Wolfgang Denk   New implementatio...
993

37f2fe747   Wolfgang Denk   env: allow to exp...
994
  	if (size)
fd37dac9e   Simon Glass   sandbox: Support ...
995
  		memset(ptr, '\0', size);
37f2fe747   Wolfgang Denk   env: allow to exp...
996
997
998
  
  	argc--;
  	argv++;
ea882baf9   Wolfgang Denk   New implementatio...
999
1000
  
  	if (sep) {		/* export as text file */
ea009d474   Wolfgang Denk   hashtable: prepar...
1001
1002
  		len = hexport_r(&env_htab, sep,
  				H_MATCH_KEY | H_MATCH_IDENT,
fd37dac9e   Simon Glass   sandbox: Support ...
1003
  				&ptr, size, argc, argv);
ea882baf9   Wolfgang Denk   New implementatio...
1004
  		if (len < 0) {
6c90f6233   Quentin Schulz   env: add the same...
1005
1006
1007
  			pr_err("## Error: Cannot export environment: errno = %d
  ",
  			       errno);
ea882baf9   Wolfgang Denk   New implementatio...
1008
1009
  			return 1;
  		}
8c3aff525   Andreas Bießmann   cmd_nvedit: use e...
1010
  		sprintf(buf, "%zX", (size_t)len);
382bee57f   Simon Glass   env: Rename seten...
1011
  		env_set("filesize", buf);
ea882baf9   Wolfgang Denk   New implementatio...
1012
1013
1014
  
  		return 0;
  	}
fd37dac9e   Simon Glass   sandbox: Support ...
1015
  	envp = (env_t *)ptr;
ea882baf9   Wolfgang Denk   New implementatio...
1016
1017
1018
1019
  
  	if (chk)		/* export as checksum protected block */
  		res = (char *)envp->data;
  	else			/* export as raw binary data */
fd37dac9e   Simon Glass   sandbox: Support ...
1020
  		res = ptr;
ea882baf9   Wolfgang Denk   New implementatio...
1021

ea009d474   Wolfgang Denk   hashtable: prepar...
1022
1023
1024
  	len = hexport_r(&env_htab, '\0',
  			H_MATCH_KEY | H_MATCH_IDENT,
  			&res, ENV_SIZE, argc, argv);
ea882baf9   Wolfgang Denk   New implementatio...
1025
  	if (len < 0) {
6c90f6233   Quentin Schulz   env: add the same...
1026
1027
1028
  		pr_err("## Error: Cannot export environment: errno = %d
  ",
  		       errno);
ea882baf9   Wolfgang Denk   New implementatio...
1029
1030
1031
1032
  		return 1;
  	}
  
  	if (chk) {
d71b029d1   Neil Stainton   cmd: env: Fix CRC...
1033
1034
  		envp->crc = crc32(0, envp->data,
  				size ? size - offsetof(env_t, data) : ENV_SIZE);
ea882baf9   Wolfgang Denk   New implementatio...
1035
  #ifdef CONFIG_ENV_ADDR_REDUND
d3716dd64   Simon Glass   env: Rename the r...
1036
  		envp->flags = ENV_REDUND_ACTIVE;
ea882baf9   Wolfgang Denk   New implementatio...
1037
1038
  #endif
  	}
018f53032   Simon Glass   env: Rename commo...
1039
  	env_set_hex("filesize", len + offsetof(env_t, data));
ea882baf9   Wolfgang Denk   New implementatio...
1040
1041
1042
1043
  
  	return 0;
  
  sep_err:
6c90f6233   Quentin Schulz   env: add the same...
1044
1045
1046
  	printf("## Error: %s: only one of \"-b\", \"-c\" or \"-t\" allowed
  ",
  	       cmd);
ea882baf9   Wolfgang Denk   New implementatio...
1047
1048
  	return 1;
  }
0c79cda01   Mike Frysinger   env: make import/...
1049
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
1050

0c79cda01   Mike Frysinger   env: make import/...
1051
  #ifdef CONFIG_CMD_IMPORTENV
ea882baf9   Wolfgang Denk   New implementatio...
1052
  /*
eaf734724   Quentin Schulz   cmd: nvedit: env ...
1053
1054
1055
1056
1057
   * env import [-d] [-t [-r] | -b | -c] addr [size] [var ...]
   *	-d:	delete existing environment before importing if no var is
   *		passed; if vars are passed, if one var is in the current
   *		environment but not in the environment at addr, delete var from
   *		current environment;
fc0b5948e   Robert P. J. Day   Various, accumula...
1058
   *		otherwise overwrite / append to existing definitions
ea882baf9   Wolfgang Denk   New implementatio...
1059
1060
   *	-t:	assume text format; either "size" must be given or the
   *		text data must be '\0' terminated
ecd1446fe   Alexander Holler   Add option -r to ...
1061
1062
1063
1064
   *	-r:	handle CRLF like LF, that means exported variables with
   *		a content which ends with \r won't get imported. Used
   *		to import text files created with editors which are using CRLF
   *		for line endings. Only effective in addition to -t.
ea882baf9   Wolfgang Denk   New implementatio...
1065
1066
1067
1068
1069
   *	-b:	assume binary format ('\0' separated, "\0\0" terminated)
   *	-c:	assume checksum protected environment format
   *	addr:	memory address to read from
   *	size:	length of input data; if missing, proper '\0'
   *		termination is mandatory
eaf734724   Quentin Schulz   cmd: nvedit: env ...
1070
1071
1072
1073
1074
   *		if var is set and size should be missing (i.e. '\0'
   *		termination), set size to '-'
   *	var...	List of the names of the only variables that get imported from
   *		the environment at address 'addr'. Without arguments, the whole
   *		environment gets imported.
ea882baf9   Wolfgang Denk   New implementatio...
1075
   */
d09b1787a   Igor Grinberg   env: clean cmd_nv...
1076
1077
  static int do_env_import(cmd_tbl_t *cmdtp, int flag,
  			 int argc, char * const argv[])
ea882baf9   Wolfgang Denk   New implementatio...
1078
  {
fd37dac9e   Simon Glass   sandbox: Support ...
1079
1080
  	ulong	addr;
  	char	*cmd, *ptr;
ea882baf9   Wolfgang Denk   New implementatio...
1081
1082
1083
1084
1085
  	char	sep = '
  ';
  	int	chk = 0;
  	int	fmt = 0;
  	int	del = 0;
ecd1446fe   Alexander Holler   Add option -r to ...
1086
  	int	crlf_is_lf = 0;
eaf734724   Quentin Schulz   cmd: nvedit: env ...
1087
  	int	wl = 0;
ea882baf9   Wolfgang Denk   New implementatio...
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
  	size_t	size;
  
  	cmd = *argv;
  
  	while (--argc > 0 && **++argv == '-') {
  		char *arg = *argv;
  		while (*++arg) {
  			switch (*arg) {
  			case 'b':		/* raw binary format */
  				if (fmt++)
  					goto sep_err;
  				sep = '\0';
  				break;
  			case 'c':		/* external checksum format */
  				if (fmt++)
  					goto sep_err;
  				sep = '\0';
  				chk = 1;
  				break;
  			case 't':		/* text format */
  				if (fmt++)
  					goto sep_err;
  				sep = '
  ';
  				break;
ecd1446fe   Alexander Holler   Add option -r to ...
1113
1114
1115
  			case 'r':		/* handle CRLF like LF */
  				crlf_is_lf = 1;
  				break;
ea882baf9   Wolfgang Denk   New implementatio...
1116
1117
1118
1119
  			case 'd':
  				del = 1;
  				break;
  			default:
4c12eeb8b   Simon Glass   Convert cmd_usage...
1120
  				return CMD_RET_USAGE;
ea882baf9   Wolfgang Denk   New implementatio...
1121
1122
1123
  			}
  		}
  	}
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
1124
  	if (argc < 1)
4c12eeb8b   Simon Glass   Convert cmd_usage...
1125
  		return CMD_RET_USAGE;
ea882baf9   Wolfgang Denk   New implementatio...
1126
1127
1128
1129
  
  	if (!fmt)
  		printf("## Warning: defaulting to text format
  ");
ecd1446fe   Alexander Holler   Add option -r to ...
1130
1131
1132
  	if (sep != '
  ' && crlf_is_lf )
  		crlf_is_lf = 0;
fd37dac9e   Simon Glass   sandbox: Support ...
1133
1134
  	addr = simple_strtoul(argv[0], NULL, 16);
  	ptr = map_sysmem(addr, 0);
ea882baf9   Wolfgang Denk   New implementatio...
1135

eaf734724   Quentin Schulz   cmd: nvedit: env ...
1136
  	if (argc >= 2 && strcmp(argv[1], "-")) {
ea882baf9   Wolfgang Denk   New implementatio...
1137
  		size = simple_strtoul(argv[1], NULL, 16);
eaf734724   Quentin Schulz   cmd: nvedit: env ...
1138
  	} else if (chk) {
3775dcd9c   Tom Rini   cmd_nvedit: Make ...
1139
1140
1141
  		puts("## Error: external checksum format must pass size
  ");
  		return CMD_RET_FAILURE;
ea882baf9   Wolfgang Denk   New implementatio...
1142
  	} else {
fd37dac9e   Simon Glass   sandbox: Support ...
1143
  		char *s = ptr;
ea882baf9   Wolfgang Denk   New implementatio...
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
  
  		size = 0;
  
  		while (size < MAX_ENV_SIZE) {
  			if ((*s == sep) && (*(s+1) == '\0'))
  				break;
  			++s;
  			++size;
  		}
  		if (size == MAX_ENV_SIZE) {
  			printf("## Warning: Input data exceeds %d bytes"
  				" - truncated
  ", MAX_ENV_SIZE);
  		}
d3f80c77c   Horst Kronstorfer   common/cmd_nvedit...
1158
  		size += 2;
79afc88d2   Simon Glass   Fix warnings in c...
1159
1160
  		printf("## Info: input data size = %zu = 0x%zX
  ", size, size);
ea882baf9   Wolfgang Denk   New implementatio...
1161
  	}
eaf734724   Quentin Schulz   cmd: nvedit: env ...
1162
1163
  	if (argc > 2)
  		wl = 1;
ea882baf9   Wolfgang Denk   New implementatio...
1164
1165
  	if (chk) {
  		uint32_t crc;
fd37dac9e   Simon Glass   sandbox: Support ...
1166
  		env_t *ep = (env_t *)ptr;
ea882baf9   Wolfgang Denk   New implementatio...
1167
1168
1169
1170
1171
1172
1173
1174
1175
  
  		size -= offsetof(env_t, data);
  		memcpy(&crc, &ep->crc, sizeof(crc));
  
  		if (crc32(0, ep->data, size) != crc) {
  			puts("## Error: bad CRC, import failed
  ");
  			return 1;
  		}
fd37dac9e   Simon Glass   sandbox: Support ...
1176
  		ptr = (char *)ep->data;
ea882baf9   Wolfgang Denk   New implementatio...
1177
  	}
eaf734724   Quentin Schulz   cmd: nvedit: env ...
1178
1179
  	if (!himport_r(&env_htab, ptr, size, sep, del ? 0 : H_NOCLEAR,
  		       crlf_is_lf, wl ? argc - 2 : 0, wl ? &argv[2] : NULL)) {
6c90f6233   Quentin Schulz   env: add the same...
1180
1181
1182
  		pr_err("## Error: Environment import failed: errno = %d
  ",
  		       errno);
ea882baf9   Wolfgang Denk   New implementatio...
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
  		return 1;
  	}
  	gd->flags |= GD_FLG_ENV_READY;
  
  	return 0;
  
  sep_err:
  	printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed
  ",
  		cmd);
  	return 1;
  }
0c79cda01   Mike Frysinger   env: make import/...
1195
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
1196

8e92120b3   Leo Ruan   cmd: nvedit: Add ...
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
  #if defined(CONFIG_CMD_NVEDIT_INFO)
  /*
   * print_env_info - print environment information
   */
  static int print_env_info(void)
  {
  	const char *value;
  
  	/* print environment validity value */
  	switch (gd->env_valid) {
  	case ENV_INVALID:
  		value = "invalid";
  		break;
  	case ENV_VALID:
  		value = "valid";
  		break;
  	case ENV_REDUND:
  		value = "redundant";
  		break;
  	default:
  		value = "unknown";
  		break;
  	}
  	printf("env_valid = %s
  ", value);
  
  	/* print environment ready flag */
  	value = gd->flags & GD_FLG_ENV_READY ? "true" : "false";
  	printf("env_ready = %s
  ", value);
  
  	/* print environment using default flag */
  	value = gd->flags & GD_FLG_ENV_DEFAULT ? "true" : "false";
  	printf("env_use_default = %s
  ", value);
  
  	return CMD_RET_SUCCESS;
  }
  
  #define ENV_INFO_IS_DEFAULT	BIT(0) /* default environment bit mask */
  #define ENV_INFO_IS_PERSISTED	BIT(1) /* environment persistence bit mask */
  
  /*
   * env info - display environment information
   * env info [-d] - evaluate whether default environment is used
   * env info [-p] - evaluate whether environment can be persisted
   */
  static int do_env_info(cmd_tbl_t *cmdtp, int flag,
  		       int argc, char * const argv[])
  {
  	int eval_flags = 0;
  	int eval_results = 0;
  
  	/* display environment information */
  	if (argc <= 1)
  		return print_env_info();
  
  	/* process options */
  	while (--argc > 0 && **++argv == '-') {
  		char *arg = *argv;
  
  		while (*++arg) {
  			switch (*arg) {
  			case 'd':
  				eval_flags |= ENV_INFO_IS_DEFAULT;
  				break;
  			case 'p':
  				eval_flags |= ENV_INFO_IS_PERSISTED;
  				break;
  			default:
  				return CMD_RET_USAGE;
  			}
  		}
  	}
  
  	/* evaluate whether default environment is used */
  	if (eval_flags & ENV_INFO_IS_DEFAULT) {
  		if (gd->flags & GD_FLG_ENV_DEFAULT) {
  			printf("Default environment is used
  ");
  			eval_results |= ENV_INFO_IS_DEFAULT;
  		} else {
  			printf("Environment was loaded from persistent storage
  ");
  		}
  	}
  
  	/* evaluate whether environment can be persisted */
  	if (eval_flags & ENV_INFO_IS_PERSISTED) {
  #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
  		printf("Environment can be persisted
  ");
  		eval_results |= ENV_INFO_IS_PERSISTED;
  #else
  		printf("Environment cannot be persisted
  ");
  #endif
  	}
  
  	/* The result of evaluations is combined with AND */
  	if (eval_flags != eval_results)
  		return CMD_RET_FAILURE;
  
  	return CMD_RET_SUCCESS;
  }
  #endif
88733e2c6   Andrew Ruder   cmd_nvedit.c: Add...
1303
1304
1305
1306
  #if defined(CONFIG_CMD_ENV_EXISTS)
  static int do_env_exists(cmd_tbl_t *cmdtp, int flag, int argc,
  		       char * const argv[])
  {
dd2408cac   Simon Glass   env: Drop the ENT...
1307
  	struct env_entry e, *ep;
88733e2c6   Andrew Ruder   cmd_nvedit.c: Add...
1308
1309
1310
1311
1312
1313
  
  	if (argc < 2)
  		return CMD_RET_USAGE;
  
  	e.key = argv[1];
  	e.data = NULL;
3f0d68074   Simon Glass   env: Drop the ACT...
1314
  	hsearch_r(e, ENV_FIND, &ep, &env_htab, 0);
88733e2c6   Andrew Ruder   cmd_nvedit.c: Add...
1315
1316
1317
1318
  
  	return (ep == NULL) ? 1 : 0;
  }
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
1319
1320
1321
1322
1323
1324
1325
1326
  /*
   * New command line interface: "env" command with subcommands
   */
  static cmd_tbl_t cmd_env_sub[] = {
  #if defined(CONFIG_CMD_ASKENV)
  	U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", ""),
  #endif
  	U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", ""),
9d8d661d7   Joe Hershberger   env: Implement th...
1327
  	U_BOOT_CMD_MKENT(delete, CONFIG_SYS_MAXARGS, 0, do_env_delete, "", ""),
ea882baf9   Wolfgang Denk   New implementatio...
1328
1329
1330
  #if defined(CONFIG_CMD_EDITENV)
  	U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", ""),
  #endif
5e2b3e0c5   Joe Hershberger   env: Add a comman...
1331
1332
1333
  #if defined(CONFIG_CMD_ENV_CALLBACK)
  	U_BOOT_CMD_MKENT(callbacks, 1, 0, do_env_callback, "", ""),
  #endif
fffad71bc   Joe Hershberger   env: Add a comman...
1334
1335
1336
  #if defined(CONFIG_CMD_ENV_FLAGS)
  	U_BOOT_CMD_MKENT(flags, 1, 0, do_env_flags, "", ""),
  #endif
0c79cda01   Mike Frysinger   env: make import/...
1337
  #if defined(CONFIG_CMD_EXPORTENV)
ea882baf9   Wolfgang Denk   New implementatio...
1338
  	U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", ""),
0c79cda01   Mike Frysinger   env: make import/...
1339
  #endif
a000b7950   Kim Phillips   common: add a gre...
1340
1341
1342
  #if defined(CONFIG_CMD_GREPENV)
  	U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""),
  #endif
0c79cda01   Mike Frysinger   env: make import/...
1343
  #if defined(CONFIG_CMD_IMPORTENV)
ea882baf9   Wolfgang Denk   New implementatio...
1344
  	U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""),
0c79cda01   Mike Frysinger   env: make import/...
1345
  #endif
8e92120b3   Leo Ruan   cmd: nvedit: Add ...
1346
1347
1348
  #if defined(CONFIG_CMD_NVEDIT_INFO)
  	U_BOOT_CMD_MKENT(info, 2, 0, do_env_info, "", ""),
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
1349
1350
1351
1352
  	U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""),
  #if defined(CONFIG_CMD_RUN)
  	U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""),
  #endif
2643c85da   Patrick Delaunay   env: enable savee...
1353
  #if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
ea882baf9   Wolfgang Denk   New implementatio...
1354
  	U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""),
cd121bdb6   Frank Wunderlich   env: register era...
1355
1356
1357
  #if defined(CONFIG_CMD_ERASEENV)
  	U_BOOT_CMD_MKENT(erase, 1, 0, do_env_erase, "", ""),
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
1358
1359
  #endif
  	U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""),
88733e2c6   Andrew Ruder   cmd_nvedit.c: Add...
1360
1361
1362
  #if defined(CONFIG_CMD_ENV_EXISTS)
  	U_BOOT_CMD_MKENT(exists, 2, 0, do_env_exists, "", ""),
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
1363
  };
2e5167cca   Wolfgang Denk   Replace CONFIG_RE...
1364
  #if defined(CONFIG_NEEDS_MANUAL_RELOC)
60f7da1f4   Heiko Schocher   env: fix cmd_env_...
1365
1366
1367
1368
1369
  void env_reloc(void)
  {
  	fixup_cmdtable(cmd_env_sub, ARRAY_SIZE(cmd_env_sub));
  }
  #endif
f3c615b8a   Macpaul Lin   cmd_nvedit.c: cle...
1370
  static int do_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
ea882baf9   Wolfgang Denk   New implementatio...
1371
1372
  {
  	cmd_tbl_t *cp;
5904da021   Thomas Weber   Common/cmd_nvedit...
1373
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
1374
  		return CMD_RET_USAGE;
5904da021   Thomas Weber   Common/cmd_nvedit...
1375

ea882baf9   Wolfgang Denk   New implementatio...
1376
1377
1378
1379
1380
1381
1382
1383
  	/* drop initial "env" arg */
  	argc--;
  	argv++;
  
  	cp = find_cmd_tbl(argv[0], cmd_env_sub, ARRAY_SIZE(cmd_env_sub));
  
  	if (cp)
  		return cp->cmd(cmdtp, flag, argc, argv);
4c12eeb8b   Simon Glass   Convert cmd_usage...
1384
  	return CMD_RET_USAGE;
ea882baf9   Wolfgang Denk   New implementatio...
1385
  }
088f1b199   Kim Phillips   common/cmd_*.c: s...
1386
1387
  #ifdef CONFIG_SYS_LONGHELP
  static char env_help_text[] =
ea882baf9   Wolfgang Denk   New implementatio...
1388
1389
1390
1391
  #if defined(CONFIG_CMD_ASKENV)
  	"ask name [message] [size] - ask for environment variable
  env "
  #endif
5e2b3e0c5   Joe Hershberger   env: Add a comman...
1392
1393
1394
1395
  #if defined(CONFIG_CMD_ENV_CALLBACK)
  	"callbacks - print callbacks and their associated variables
  env "
  #endif
b64b7c3df   Gerlando Falauto   env: make "env de...
1396
1397
1398
1399
  	"default [-f] -a - [forcibly] reset default environment
  "
  	"env default [-f] var [...] - [forcibly] reset variable(s) to their default values
  "
9d8d661d7   Joe Hershberger   env: Implement th...
1400
1401
  	"env delete [-f] var [...] - [forcibly] delete variable(s)
  "
ea882baf9   Wolfgang Denk   New implementatio...
1402
1403
1404
1405
  #if defined(CONFIG_CMD_EDITENV)
  	"env edit name - edit environment variable
  "
  #endif
88733e2c6   Andrew Ruder   cmd_nvedit.c: Add...
1406
1407
1408
1409
  #if defined(CONFIG_CMD_ENV_EXISTS)
  	"env exists name - tests for existence of variable
  "
  #endif
4796bc4bb   Benoît Thébaudeau   env import/export...
1410
  #if defined(CONFIG_CMD_EXPORTENV)
37f2fe747   Wolfgang Denk   env: allow to exp...
1411
1412
  	"env export [-t | -b | -c] [-s size] addr [var ...] - export environment
  "
4796bc4bb   Benoît Thébaudeau   env import/export...
1413
  #endif
fffad71bc   Joe Hershberger   env: Add a comman...
1414
1415
1416
1417
  #if defined(CONFIG_CMD_ENV_FLAGS)
  	"env flags - print variables that have non-default flags
  "
  #endif
a000b7950   Kim Phillips   common: add a gre...
1418
  #if defined(CONFIG_CMD_GREPENV)
be29df6a1   Wolfgang Denk   "env grep" - add ...
1419
1420
1421
1422
  #ifdef CONFIG_REGEX
  	"env grep [-e] [-n | -v | -b] string [...] - search environment
  "
  #else
d87244d5a   Wolfgang Denk   "env grep" - add ...
1423
1424
  	"env grep [-n | -v | -b] string [...] - search environment
  "
a000b7950   Kim Phillips   common: add a gre...
1425
  #endif
be29df6a1   Wolfgang Denk   "env grep" - add ...
1426
  #endif
4796bc4bb   Benoît Thébaudeau   env import/export...
1427
  #if defined(CONFIG_CMD_IMPORTENV)
eaf734724   Quentin Schulz   cmd: nvedit: env ...
1428
1429
  	"env import [-d] [-t [-r] | -b | -c] addr [size] [var ...] - import environment
  "
4796bc4bb   Benoît Thébaudeau   env import/export...
1430
  #endif
8e92120b3   Leo Ruan   cmd: nvedit: Add ...
1431
1432
1433
1434
1435
1436
1437
1438
  #if defined(CONFIG_CMD_NVEDIT_INFO)
  	"env info - display environment information
  "
  	"env info [-d] - whether default environment is used
  "
  	"env info [-p] - whether environment can be persisted
  "
  #endif
be11235ab   Joe Hershberger   env: Hide '.' var...
1439
1440
  	"env print [-a | name ...] - print environment
  "
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1441
  #if defined(CONFIG_CMD_NVEDIT_EFI)
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
1442
1443
  	"env print -e [-guid guid|-all][-n] [name ...] - print UEFI environment
  "
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1444
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
1445
1446
1447
1448
  #if defined(CONFIG_CMD_RUN)
  	"env run var [...] - run commands in an environment variable
  "
  #endif
2643c85da   Patrick Delaunay   env: enable savee...
1449
  #if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
ea882baf9   Wolfgang Denk   New implementatio...
1450
1451
  	"env save - save environment
  "
cd121bdb6   Frank Wunderlich   env: register era...
1452
1453
1454
1455
  #if defined(CONFIG_CMD_ERASEENV)
  	"env erase - erase environment
  "
  #endif
d798a9b5d   Horst Kronstorfer   common/cmd_nvedit...
1456
  #endif
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1457
  #if defined(CONFIG_CMD_NVEDIT_EFI)
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
1458
1459
1460
1461
  	"env set -e [-nv][-bs][-rt][-a][-i addr,size][-v] name [arg ...]
  "
  	"    - set UEFI variable; unset if '-i' or 'arg' not specified
  "
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1462
  #endif
088f1b199   Kim Phillips   common/cmd_*.c: s...
1463
1464
1465
1466
1467
1468
1469
  	"env set [-f] name [arg ...]
  ";
  #endif
  
  U_BOOT_CMD(
  	env, CONFIG_SYS_MAXARGS, 1, do_env,
  	"environment handling commands", env_help_text
ea882baf9   Wolfgang Denk   New implementatio...
1470
1471
1472
1473
1474
  );
  
  /*
   * Old command line interface, kept for compatibility
   */
8bde7f776   wdenk   * Code cleanup:
1475

246c69225   Peter Tyser   Add 'editenv' com...
1476
  #if defined(CONFIG_CMD_EDITENV)
722b061b6   Mike Frysinger   autocomplete: rem...
1477
  U_BOOT_CMD_COMPLETE(
ea882baf9   Wolfgang Denk   New implementatio...
1478
  	editenv, 2, 0,	do_env_edit,
246c69225   Peter Tyser   Add 'editenv' com...
1479
1480
1481
  	"edit environment variable",
  	"name
  "
722b061b6   Mike Frysinger   autocomplete: rem...
1482
1483
  	"    - edit environment variable 'name'",
  	var_complete
246c69225   Peter Tyser   Add 'editenv' com...
1484
1485
  );
  #endif
722b061b6   Mike Frysinger   autocomplete: rem...
1486
  U_BOOT_CMD_COMPLETE(
ea882baf9   Wolfgang Denk   New implementatio...
1487
  	printenv, CONFIG_SYS_MAXARGS, 1,	do_env_print,
2fb2604d5   Peter Tyser   Command usage cle...
1488
  	"print environment variables",
be11235ab   Joe Hershberger   env: Hide '.' var...
1489
1490
1491
  	"[-a]
      - print [all] values of all environment variables
  "
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1492
  #if defined(CONFIG_CMD_NVEDIT_EFI)
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
1493
1494
  	"printenv -e [-guid guid|-all][-n] [name ...]
  "
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1495
1496
  	"    - print UEFI variable 'name' or all the variables
  "
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
1497
1498
  	"      \"-n\": suppress dumping variable's value
  "
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1499
  #endif
8bde7f776   wdenk   * Code cleanup:
1500
1501
  	"printenv name ...
  "
722b061b6   Mike Frysinger   autocomplete: rem...
1502
1503
  	"    - print value of environment variable 'name'",
  	var_complete
8bde7f776   wdenk   * Code cleanup:
1504
  );
a000b7950   Kim Phillips   common: add a gre...
1505
1506
1507
1508
  #ifdef CONFIG_CMD_GREPENV
  U_BOOT_CMD_COMPLETE(
  	grepenv, CONFIG_SYS_MAXARGS, 0,  do_env_grep,
  	"search environment variables",
be29df6a1   Wolfgang Denk   "env grep" - add ...
1509
1510
1511
1512
  #ifdef CONFIG_REGEX
  	"[-e] [-n | -v | -b] string ...
  "
  #else
d87244d5a   Wolfgang Denk   "env grep" - add ...
1513
1514
  	"[-n | -v | -b] string ...
  "
be29df6a1   Wolfgang Denk   "env grep" - add ...
1515
  #endif
d87244d5a   Wolfgang Denk   "env grep" - add ...
1516
1517
  	"    - list environment name=value pairs matching 'string'
  "
be29df6a1   Wolfgang Denk   "env grep" - add ...
1518
1519
1520
1521
  #ifdef CONFIG_REGEX
  	"      \"-e\": enable regular expressions;
  "
  #endif
d87244d5a   Wolfgang Denk   "env grep" - add ...
1522
1523
1524
  	"      \"-n\": search variable names; \"-v\": search values;
  "
  	"      \"-b\": search both names and values (default)",
a000b7950   Kim Phillips   common: add a gre...
1525
1526
1527
  	var_complete
  );
  #endif
722b061b6   Mike Frysinger   autocomplete: rem...
1528
  U_BOOT_CMD_COMPLETE(
ea882baf9   Wolfgang Denk   New implementatio...
1529
  	setenv, CONFIG_SYS_MAXARGS, 0,	do_env_set,
2fb2604d5   Peter Tyser   Command usage cle...
1530
  	"set environment variables",
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1531
  #if defined(CONFIG_CMD_NVEDIT_EFI)
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
1532
1533
1534
1535
  	"-e [-guid guid][-nv][-bs][-rt][-a][-v]
  "
  	"        [-i addr,size name], or [name [value ...]]
  "
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1536
1537
  	"    - set UEFI variable 'name' to 'value' ...'
  "
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
  	"      \"-guid\": set vendor guid
  "
  	"      \"-nv\": set non-volatile attribute
  "
  	"      \"-bs\": set boot-service attribute
  "
  	"      \"-rt\": set runtime attribute
  "
  	"      \"-a\": append-write
  "
  	"      \"-i addr,size\": use <addr,size> as variable's value
  "
  	"      \"-v\": verbose message
  "
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1552
1553
1554
1555
1556
  	"    - delete UEFI variable 'name' if 'value' not specified
  "
  #endif
  	"setenv [-f] name value ...
  "
24ab5a191   Joe Hershberger   env: Add setenv f...
1557
1558
1559
1560
1561
  	"    - [forcibly] set environment variable 'name' to 'value ...'
  "
  	"setenv [-f] name
  "
  	"    - [forcibly] delete environment variable 'name'",
722b061b6   Mike Frysinger   autocomplete: rem...
1562
  	var_complete
8bde7f776   wdenk   * Code cleanup:
1563
  );
c76fe4742   Jon Loeliger   common/cmd_[i-n]*...
1564
  #if defined(CONFIG_CMD_ASKENV)
8bde7f776   wdenk   * Code cleanup:
1565

0d4983930   wdenk   Patch by Kenneth ...
1566
  U_BOOT_CMD(
ea882baf9   Wolfgang Denk   New implementatio...
1567
  	askenv,	CONFIG_SYS_MAXARGS,	1,	do_env_ask,
2fb2604d5   Peter Tyser   Command usage cle...
1568
  	"get environment variables from stdin",
8bde7f776   wdenk   * Code cleanup:
1569
1570
  	"name [message] [size]
  "
7d85591dd   Wolfgang Denk   env: fix "env ask...
1571
  	"    - get environment variable 'name' from stdin (max 'size' chars)"
8bde7f776   wdenk   * Code cleanup:
1572
  );
902531788   Jon Loeliger   common/: Remove l...
1573
  #endif
8bde7f776   wdenk   * Code cleanup:
1574

c76fe4742   Jon Loeliger   common/cmd_[i-n]*...
1575
  #if defined(CONFIG_CMD_RUN)
722b061b6   Mike Frysinger   autocomplete: rem...
1576
  U_BOOT_CMD_COMPLETE(
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
1577
  	run,	CONFIG_SYS_MAXARGS,	1,	do_run,
2fb2604d5   Peter Tyser   Command usage cle...
1578
  	"run commands in an environment variable",
8bde7f776   wdenk   * Code cleanup:
1579
1580
  	"var [...]
  "
722b061b6   Mike Frysinger   autocomplete: rem...
1581
1582
  	"    - run the commands in the environment variable(s) 'var'",
  	var_complete
8bde7f776   wdenk   * Code cleanup:
1583
  );
902531788   Jon Loeliger   common/: Remove l...
1584
  #endif
7ac2fe2da   Ilya Yanok   OMAP: networking ...
1585
  #endif /* CONFIG_SPL_BUILD */