1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <common.h>
28#include <cli.h>
29#include <command.h>
30#include <console.h>
31#include <environment.h>
32#include <search.h>
33#include <errno.h>
34#include <malloc.h>
35#include <mapmem.h>
36#include <watchdog.h>
37#include <linux/stddef.h>
38#include <asm/byteorder.h>
39#include <asm/io.h>
40
41DECLARE_GLOBAL_DATA_PTR;
42
43#if !defined(CONFIG_ENV_IS_IN_EEPROM) && \
44 !defined(CONFIG_ENV_IS_IN_FLASH) && \
45 !defined(CONFIG_ENV_IS_IN_DATAFLASH) && \
46 !defined(CONFIG_ENV_IS_IN_MMC) && \
47 !defined(CONFIG_ENV_IS_IN_FAT) && \
48 !defined(CONFIG_ENV_IS_IN_EXT4) && \
49 !defined(CONFIG_ENV_IS_IN_NAND) && \
50 !defined(CONFIG_ENV_IS_IN_NVRAM) && \
51 !defined(CONFIG_ENV_IS_IN_ONENAND) && \
52 !defined(CONFIG_ENV_IS_IN_SATA) && \
53 !defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \
54 !defined(CONFIG_ENV_IS_IN_REMOTE) && \
55 !defined(CONFIG_ENV_IS_IN_UBI) && \
56 !defined(CONFIG_ENV_IS_NOWHERE)
57# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
58SATA|SPI_FLASH|NVRAM|MMC|FAT|EXT4|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
59#endif
60
61
62
63
64#define MAX_ENV_SIZE (1 << 20)
65
66
67
68
69
70
71
72
73static int env_id = 1;
74
75int get_env_id(void)
76{
77 return env_id;
78}
79
80#ifndef CONFIG_SPL_BUILD
81
82
83
84
85
86static int env_print(char *name, int flag)
87{
88 char *res = NULL;
89 ssize_t len;
90
91 if (name) {
92 ENTRY e, *ep;
93
94 e.key = name;
95 e.data = NULL;
96 hsearch_r(e, FIND, &ep, &env_htab, flag);
97 if (ep == NULL)
98 return 0;
99 len = printf("%s=%s\n", ep->key, ep->data);
100 return len;
101 }
102
103
104 len = hexport_r(&env_htab, '\n', flag, &res, 0, 0, NULL);
105
106 if (len > 0) {
107 puts(res);
108 free(res);
109 return len;
110 }
111
112
113 printf("## Error: cannot export environment\n");
114 return 0;
115}
116
117static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,
118 char * const argv[])
119{
120 int i;
121 int rcode = 0;
122 int env_flag = H_HIDE_DOT;
123
124 if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'a') {
125 argc--;
126 argv++;
127 env_flag &= ~H_HIDE_DOT;
128 }
129
130 if (argc == 1) {
131
132 rcode = env_print(NULL, env_flag);
133 if (!rcode)
134 return 1;
135 printf("\nEnvironment size: %d/%ld bytes\n",
136 rcode, (ulong)ENV_SIZE);
137 return 0;
138 }
139
140
141 env_flag &= ~H_HIDE_DOT;
142 for (i = 1; i < argc; ++i) {
143 int rc = env_print(argv[i], env_flag);
144 if (!rc) {
145 printf("## Error: \"%s\" not defined\n", argv[i]);
146 ++rcode;
147 }
148 }
149
150 return rcode;
151}
152
153#ifdef CONFIG_CMD_GREPENV
154static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
155 int argc, char * const argv[])
156{
157 char *res = NULL;
158 int len, grep_how, grep_what;
159
160 if (argc < 2)
161 return CMD_RET_USAGE;
162
163 grep_how = H_MATCH_SUBSTR;
164 grep_what = H_MATCH_BOTH;
165
166 while (--argc > 0 && **++argv == '-') {
167 char *arg = *argv;
168 while (*++arg) {
169 switch (*arg) {
170#ifdef CONFIG_REGEX
171 case 'e':
172 grep_how = H_MATCH_REGEX;
173 break;
174#endif
175 case 'n':
176 grep_what = H_MATCH_KEY;
177 break;
178 case 'v':
179 grep_what = H_MATCH_DATA;
180 break;
181 case 'b':
182 grep_what = H_MATCH_BOTH;
183 break;
184 case '-':
185 goto DONE;
186 default:
187 return CMD_RET_USAGE;
188 }
189 }
190 }
191
192DONE:
193 len = hexport_r(&env_htab, '\n',
194 flag | grep_what | grep_how,
195 &res, 0, argc, argv);
196
197 if (len > 0) {
198 puts(res);
199 free(res);
200 }
201
202 if (len < 2)
203 return 1;
204
205 return 0;
206}
207#endif
208#endif
209
210
211
212
213
214static int _do_env_set(int flag, int argc, char * const argv[], int env_flag)
215{
216 int i, len;
217 char *name, *value, *s;
218 ENTRY e, *ep;
219
220 debug("Initial value for argc=%d\n", argc);
221 while (argc > 1 && **(argv + 1) == '-') {
222 char *arg = *++argv;
223
224 --argc;
225 while (*++arg) {
226 switch (*arg) {
227 case 'f':
228 env_flag |= H_FORCE;
229 break;
230 default:
231 return CMD_RET_USAGE;
232 }
233 }
234 }
235 debug("Final value for argc=%d\n", argc);
236 name = argv[1];
237 value = argv[2];
238
239 if (strchr(name, '=')) {
240 printf("## Error: illegal character '='"
241 "in variable name \"%s\"\n", name);
242 return 1;
243 }
244
245 env_id++;
246
247
248 if (argc < 3 || argv[2] == NULL) {
249 int rc = hdelete_r(name, &env_htab, env_flag);
250 return !rc;
251 }
252
253
254
255
256 for (i = 2, len = 0; i < argc; ++i)
257 len += strlen(argv[i]) + 1;
258
259 value = malloc(len);
260 if (value == NULL) {
261 printf("## Can't malloc %d bytes\n", len);
262 return 1;
263 }
264 for (i = 2, s = value; i < argc; ++i) {
265 char *v = argv[i];
266
267 while ((*s++ = *v++) != '\0')
268 ;
269 *(s - 1) = ' ';
270 }
271 if (s != value)
272 *--s = '\0';
273
274 e.key = name;
275 e.data = value;
276 hsearch_r(e, ENTER, &ep, &env_htab, env_flag);
277 free(value);
278 if (!ep) {
279 printf("## Error inserting \"%s\" variable, errno=%d\n",
280 name, errno);
281 return 1;
282 }
283
284 return 0;
285}
286
287int setenv(const char *varname, const char *varvalue)
288{
289 const char * const argv[4] = { "setenv", varname, varvalue, NULL };
290
291
292 if (!(gd->flags & GD_FLG_ENV_READY))
293 return 1;
294
295 if (varvalue == NULL || varvalue[0] == '\0')
296 return _do_env_set(0, 2, (char * const *)argv, H_PROGRAMMATIC);
297 else
298 return _do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC);
299}
300
301
302
303
304
305
306
307
308int setenv_ulong(const char *varname, ulong value)
309{
310
311 char *str = simple_itoa(value);
312
313 return setenv(varname, str);
314}
315
316
317
318
319
320
321
322
323int setenv_hex(const char *varname, ulong value)
324{
325 char str[17];
326
327 sprintf(str, "%lx", value);
328 return setenv(varname, str);
329}
330
331ulong getenv_hex(const char *varname, ulong default_val)
332{
333 const char *s;
334 ulong value;
335 char *endp;
336
337 s = getenv(varname);
338 if (s)
339 value = simple_strtoul(s, &endp, 16);
340 if (!s || endp == s)
341 return default_val;
342
343 return value;
344}
345
346#ifndef CONFIG_SPL_BUILD
347static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
348{
349 if (argc < 2)
350 return CMD_RET_USAGE;
351
352 return _do_env_set(flag, argc, argv, H_INTERACTIVE);
353}
354
355
356
357
358#if defined(CONFIG_CMD_ASKENV)
359int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
360{
361 char message[CONFIG_SYS_CBSIZE];
362 int i, len, pos, size;
363 char *local_args[4];
364 char *endptr;
365
366 local_args[0] = argv[0];
367 local_args[1] = argv[1];
368 local_args[2] = NULL;
369 local_args[3] = NULL;
370
371
372
373
374
375
376 if (argc == 1)
377 return CMD_RET_USAGE;
378
379
380
381
382
383
384
385 i = simple_strtoul(argv[argc - 1], &endptr, 10);
386 if (*endptr != '\0') {
387 size = CONFIG_SYS_CBSIZE - 1;
388 } else {
389 size = i;
390 --argc;
391 }
392
393 if (argc <= 2) {
394 sprintf(message, "Please enter '%s': ", argv[1]);
395 } else {
396
397 for (i = 2, pos = 0; i < argc; i++) {
398 if (pos)
399 message[pos++] = ' ';
400
401 strcpy(message + pos, argv[i]);
402 pos += strlen(argv[i]);
403 }
404 message[pos++] = ' ';
405 message[pos] = '\0';
406 }
407
408 if (size >= CONFIG_SYS_CBSIZE)
409 size = CONFIG_SYS_CBSIZE - 1;
410
411 if (size <= 0)
412 return 1;
413
414
415 len = cli_readline(message);
416
417 if (size < len)
418 console_buffer[size] = '\0';
419
420 len = 2;
421 if (console_buffer[0] != '\0') {
422 local_args[2] = console_buffer;
423 len = 3;
424 }
425
426
427 return _do_env_set(flag, len, local_args, H_INTERACTIVE);
428}
429#endif
430
431#if defined(CONFIG_CMD_ENV_CALLBACK)
432static int print_static_binding(const char *var_name, const char *callback_name,
433 void *priv)
434{
435 printf("\t%-20s %-20s\n", var_name, callback_name);
436
437 return 0;
438}
439
440static int print_active_callback(ENTRY *entry)
441{
442 struct env_clbk_tbl *clbkp;
443 int i;
444 int num_callbacks;
445
446 if (entry->callback == NULL)
447 return 0;
448
449
450 num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
451 for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
452 i < num_callbacks;
453 i++, clbkp++) {
454#if defined(CONFIG_NEEDS_MANUAL_RELOC)
455 if (entry->callback == clbkp->callback + gd->reloc_off)
456#else
457 if (entry->callback == clbkp->callback)
458#endif
459 break;
460 }
461
462 if (i == num_callbacks)
463
464 printf("\t%-20s %p\n", entry->key, entry->callback);
465 else
466 printf("\t%-20s %-20s\n", entry->key, clbkp->name);
467
468 return 0;
469}
470
471
472
473
474int do_env_callback(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
475{
476 struct env_clbk_tbl *clbkp;
477 int i;
478 int num_callbacks;
479
480
481 puts("Available callbacks:\n");
482 puts("\tCallback Name\n");
483 puts("\t-------------\n");
484 num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
485 for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
486 i < num_callbacks;
487 i++, clbkp++)
488 printf("\t%s\n", clbkp->name);
489 puts("\n");
490
491
492 puts("Static callback bindings:\n");
493 printf("\t%-20s %-20s\n", "Variable Name", "Callback Name");
494 printf("\t%-20s %-20s\n", "-------------", "-------------");
495 env_attr_walk(ENV_CALLBACK_LIST_STATIC, print_static_binding, NULL);
496 puts("\n");
497
498
499 puts("Active callback bindings:\n");
500 printf("\t%-20s %-20s\n", "Variable Name", "Callback Name");
501 printf("\t%-20s %-20s\n", "-------------", "-------------");
502 hwalk_r(&env_htab, print_active_callback);
503 return 0;
504}
505#endif
506
507#if defined(CONFIG_CMD_ENV_FLAGS)
508static int print_static_flags(const char *var_name, const char *flags,
509 void *priv)
510{
511 enum env_flags_vartype type = env_flags_parse_vartype(flags);
512 enum env_flags_varaccess access = env_flags_parse_varaccess(flags);
513
514 printf("\t%-20s %-20s %-20s\n", var_name,
515 env_flags_get_vartype_name(type),
516 env_flags_get_varaccess_name(access));
517
518 return 0;
519}
520
521static int print_active_flags(ENTRY *entry)
522{
523 enum env_flags_vartype type;
524 enum env_flags_varaccess access;
525
526 if (entry->flags == 0)
527 return 0;
528
529 type = (enum env_flags_vartype)
530 (entry->flags & ENV_FLAGS_VARTYPE_BIN_MASK);
531 access = env_flags_parse_varaccess_from_binflags(entry->flags);
532 printf("\t%-20s %-20s %-20s\n", entry->key,
533 env_flags_get_vartype_name(type),
534 env_flags_get_varaccess_name(access));
535
536 return 0;
537}
538
539
540
541
542int do_env_flags(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
543{
544
545 printf("Available variable type flags (position %d):\n",
546 ENV_FLAGS_VARTYPE_LOC);
547 puts("\tFlag\tVariable Type Name\n");
548 puts("\t----\t------------------\n");
549 env_flags_print_vartypes();
550 puts("\n");
551
552
553 printf("Available variable access flags (position %d):\n",
554 ENV_FLAGS_VARACCESS_LOC);
555 puts("\tFlag\tVariable Access Name\n");
556 puts("\t----\t--------------------\n");
557 env_flags_print_varaccess();
558 puts("\n");
559
560
561 puts("Static flags:\n");
562 printf("\t%-20s %-20s %-20s\n", "Variable Name", "Variable Type",
563 "Variable Access");
564 printf("\t%-20s %-20s %-20s\n", "-------------", "-------------",
565 "---------------");
566 env_attr_walk(ENV_FLAGS_LIST_STATIC, print_static_flags, NULL);
567 puts("\n");
568
569
570 puts("Active flags:\n");
571 printf("\t%-20s %-20s %-20s\n", "Variable Name", "Variable Type",
572 "Variable Access");
573 printf("\t%-20s %-20s %-20s\n", "-------------", "-------------",
574 "---------------");
575 hwalk_r(&env_htab, print_active_flags);
576 return 0;
577}
578#endif
579
580
581
582
583#if defined(CONFIG_CMD_EDITENV)
584static int do_env_edit(cmd_tbl_t *cmdtp, int flag, int argc,
585 char * const argv[])
586{
587 char buffer[CONFIG_SYS_CBSIZE];
588 char *init_val;
589
590 if (argc < 2)
591 return CMD_RET_USAGE;
592
593
594 if (!(gd->flags & GD_FLG_ENV_READY))
595 return 1;
596
597
598 init_val = getenv(argv[1]);
599 if (init_val)
600 snprintf(buffer, CONFIG_SYS_CBSIZE, "%s", init_val);
601 else
602 buffer[0] = '\0';
603
604 if (cli_readline_into_buffer("edit: ", buffer, 0) < 0)
605 return 1;
606
607 if (buffer[0] == '\0') {
608 const char * const _argv[3] = { "setenv", argv[1], NULL };
609
610 return _do_env_set(0, 2, (char * const *)_argv, H_INTERACTIVE);
611 } else {
612 const char * const _argv[4] = { "setenv", argv[1], buffer,
613 NULL };
614
615 return _do_env_set(0, 3, (char * const *)_argv, H_INTERACTIVE);
616 }
617}
618#endif
619#endif
620
621
622
623
624
625
626char *getenv(const char *name)
627{
628 if (gd->flags & GD_FLG_ENV_READY) {
629 ENTRY e, *ep;
630
631 WATCHDOG_RESET();
632
633 e.key = name;
634 e.data = NULL;
635 hsearch_r(e, FIND, &ep, &env_htab, 0);
636
637 return ep ? ep->data : NULL;
638 }
639
640
641 if (getenv_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)
642 return (char *)(gd->env_buf);
643
644 return NULL;
645}
646
647
648
649
650int getenv_f(const char *name, char *buf, unsigned len)
651{
652 int i, nxt;
653
654 for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
655 int val, n;
656
657 for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) {
658 if (nxt >= CONFIG_ENV_SIZE)
659 return -1;
660 }
661
662 val = envmatch((uchar *)name, i);
663 if (val < 0)
664 continue;
665
666
667 for (n = 0; n < len; ++n, ++buf) {
668 *buf = env_get_char(val++);
669 if (*buf == '\0')
670 return n;
671 }
672
673 if (n)
674 *--buf = '\0';
675
676 printf("env_buf [%d bytes] too small for value of \"%s\"\n",
677 len, name);
678
679 return n;
680 }
681
682 return -1;
683}
684
685
686
687
688
689
690
691
692
693
694ulong getenv_ulong(const char *name, int base, ulong default_val)
695{
696
697
698
699
700 const char *str = getenv(name);
701
702 return str ? simple_strtoul(str, NULL, base) : default_val;
703}
704
705#ifndef CONFIG_SPL_BUILD
706#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
707static int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc,
708 char * const argv[])
709{
710 printf("Saving Environment to %s...\n", env_name_spec);
711
712 return saveenv() ? 1 : 0;
713}
714
715U_BOOT_CMD(
716 saveenv, 1, 0, do_env_save,
717 "save environment variables to persistent storage",
718 ""
719);
720#endif
721#endif
722
723
724
725
726
727
728
729
730
731int envmatch(uchar *s1, int i2)
732{
733 if (s1 == NULL)
734 return -1;
735
736 while (*s1 == env_get_char(i2++))
737 if (*s1++ == '=')
738 return i2;
739
740 if (*s1 == '\0' && env_get_char(i2-1) == '=')
741 return i2;
742
743 return -1;
744}
745
746#ifndef CONFIG_SPL_BUILD
747static int do_env_default(cmd_tbl_t *cmdtp, int __flag,
748 int argc, char * const argv[])
749{
750 int all = 0, flag = 0;
751
752 debug("Initial value for argc=%d\n", argc);
753 while (--argc > 0 && **++argv == '-') {
754 char *arg = *argv;
755
756 while (*++arg) {
757 switch (*arg) {
758 case 'a':
759 all = 1;
760 break;
761 case 'f':
762 flag |= H_FORCE;
763 break;
764 default:
765 return cmd_usage(cmdtp);
766 }
767 }
768 }
769 debug("Final value for argc=%d\n", argc);
770 if (all && (argc == 0)) {
771
772 set_default_env("## Resetting to default environment\n");
773 return 0;
774 }
775 if (!all && (argc > 0)) {
776
777 set_default_vars(argc, argv);
778 return 0;
779 }
780
781 return cmd_usage(cmdtp);
782}
783
784static int do_env_delete(cmd_tbl_t *cmdtp, int flag,
785 int argc, char * const argv[])
786{
787 int env_flag = H_INTERACTIVE;
788 int ret = 0;
789
790 debug("Initial value for argc=%d\n", argc);
791 while (argc > 1 && **(argv + 1) == '-') {
792 char *arg = *++argv;
793
794 --argc;
795 while (*++arg) {
796 switch (*arg) {
797 case 'f':
798 env_flag |= H_FORCE;
799 break;
800 default:
801 return CMD_RET_USAGE;
802 }
803 }
804 }
805 debug("Final value for argc=%d\n", argc);
806
807 env_id++;
808
809 while (--argc > 0) {
810 char *name = *++argv;
811
812 if (!hdelete_r(name, &env_htab, env_flag))
813 ret = 1;
814 }
815
816 return ret;
817}
818
819#ifdef CONFIG_CMD_EXPORTENV
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865static int do_env_export(cmd_tbl_t *cmdtp, int flag,
866 int argc, char * const argv[])
867{
868 char buf[32];
869 ulong addr;
870 char *ptr, *cmd, *res;
871 size_t size = 0;
872 ssize_t len;
873 env_t *envp;
874 char sep = '\n';
875 int chk = 0;
876 int fmt = 0;
877
878 cmd = *argv;
879
880 while (--argc > 0 && **++argv == '-') {
881 char *arg = *argv;
882 while (*++arg) {
883 switch (*arg) {
884 case 'b':
885 if (fmt++)
886 goto sep_err;
887 sep = '\0';
888 break;
889 case 'c':
890 if (fmt++)
891 goto sep_err;
892 sep = '\0';
893 chk = 1;
894 break;
895 case 's':
896 if (--argc <= 0)
897 return cmd_usage(cmdtp);
898 size = simple_strtoul(*++argv, NULL, 16);
899 goto NXTARG;
900 case 't':
901 if (fmt++)
902 goto sep_err;
903 sep = '\n';
904 break;
905 default:
906 return CMD_RET_USAGE;
907 }
908 }
909NXTARG: ;
910 }
911
912 if (argc < 1)
913 return CMD_RET_USAGE;
914
915 addr = simple_strtoul(argv[0], NULL, 16);
916 ptr = map_sysmem(addr, size);
917
918 if (size)
919 memset(ptr, '\0', size);
920
921 argc--;
922 argv++;
923
924 if (sep) {
925 len = hexport_r(&env_htab, sep,
926 H_MATCH_KEY | H_MATCH_IDENT,
927 &ptr, size, argc, argv);
928 if (len < 0) {
929 error("Cannot export environment: errno = %d\n", errno);
930 return 1;
931 }
932 sprintf(buf, "%zX", (size_t)len);
933 setenv("filesize", buf);
934
935 return 0;
936 }
937
938 envp = (env_t *)ptr;
939
940 if (chk)
941 res = (char *)envp->data;
942 else
943 res = ptr;
944
945 len = hexport_r(&env_htab, '\0',
946 H_MATCH_KEY | H_MATCH_IDENT,
947 &res, ENV_SIZE, argc, argv);
948 if (len < 0) {
949 error("Cannot export environment: errno = %d\n", errno);
950 return 1;
951 }
952
953 if (chk) {
954 envp->crc = crc32(0, envp->data, ENV_SIZE);
955#ifdef CONFIG_ENV_ADDR_REDUND
956 envp->flags = ACTIVE_FLAG;
957#endif
958 }
959 setenv_hex("filesize", len + offsetof(env_t, data));
960
961 return 0;
962
963sep_err:
964 printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n", cmd);
965 return 1;
966}
967#endif
968
969#ifdef CONFIG_CMD_IMPORTENV
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986static int do_env_import(cmd_tbl_t *cmdtp, int flag,
987 int argc, char * const argv[])
988{
989 ulong addr;
990 char *cmd, *ptr;
991 char sep = '\n';
992 int chk = 0;
993 int fmt = 0;
994 int del = 0;
995 int crlf_is_lf = 0;
996 size_t size;
997
998 cmd = *argv;
999
1000 while (--argc > 0 && **++argv == '-') {
1001 char *arg = *argv;
1002 while (*++arg) {
1003 switch (*arg) {
1004 case 'b':
1005 if (fmt++)
1006 goto sep_err;
1007 sep = '\0';
1008 break;
1009 case 'c':
1010 if (fmt++)
1011 goto sep_err;
1012 sep = '\0';
1013 chk = 1;
1014 break;
1015 case 't':
1016 if (fmt++)
1017 goto sep_err;
1018 sep = '\n';
1019 break;
1020 case 'r':
1021 crlf_is_lf = 1;
1022 break;
1023 case 'd':
1024 del = 1;
1025 break;
1026 default:
1027 return CMD_RET_USAGE;
1028 }
1029 }
1030 }
1031
1032 if (argc < 1)
1033 return CMD_RET_USAGE;
1034
1035 if (!fmt)
1036 printf("## Warning: defaulting to text format\n");
1037
1038 if (sep != '\n' && crlf_is_lf )
1039 crlf_is_lf = 0;
1040
1041 addr = simple_strtoul(argv[0], NULL, 16);
1042 ptr = map_sysmem(addr, 0);
1043
1044 if (argc == 2) {
1045 size = simple_strtoul(argv[1], NULL, 16);
1046 } else if (argc == 1 && chk) {
1047 puts("## Error: external checksum format must pass size\n");
1048 return CMD_RET_FAILURE;
1049 } else {
1050 char *s = ptr;
1051
1052 size = 0;
1053
1054 while (size < MAX_ENV_SIZE) {
1055 if ((*s == sep) && (*(s+1) == '\0'))
1056 break;
1057 ++s;
1058 ++size;
1059 }
1060 if (size == MAX_ENV_SIZE) {
1061 printf("## Warning: Input data exceeds %d bytes"
1062 " - truncated\n", MAX_ENV_SIZE);
1063 }
1064 size += 2;
1065 printf("## Info: input data size = %zu = 0x%zX\n", size, size);
1066 }
1067
1068 if (chk) {
1069 uint32_t crc;
1070 env_t *ep = (env_t *)ptr;
1071
1072 size -= offsetof(env_t, data);
1073 memcpy(&crc, &ep->crc, sizeof(crc));
1074
1075 if (crc32(0, ep->data, size) != crc) {
1076 puts("## Error: bad CRC, import failed\n");
1077 return 1;
1078 }
1079 ptr = (char *)ep->data;
1080 }
1081
1082 if (himport_r(&env_htab, ptr, size, sep, del ? 0 : H_NOCLEAR,
1083 crlf_is_lf, 0, NULL) == 0) {
1084 error("Environment import failed: errno = %d\n", errno);
1085 return 1;
1086 }
1087 gd->flags |= GD_FLG_ENV_READY;
1088
1089 return 0;
1090
1091sep_err:
1092 printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n",
1093 cmd);
1094 return 1;
1095}
1096#endif
1097
1098#if defined(CONFIG_CMD_ENV_EXISTS)
1099static int do_env_exists(cmd_tbl_t *cmdtp, int flag, int argc,
1100 char * const argv[])
1101{
1102 ENTRY e, *ep;
1103
1104 if (argc < 2)
1105 return CMD_RET_USAGE;
1106
1107 e.key = argv[1];
1108 e.data = NULL;
1109 hsearch_r(e, FIND, &ep, &env_htab, 0);
1110
1111 return (ep == NULL) ? 1 : 0;
1112}
1113#endif
1114
1115
1116
1117
1118static cmd_tbl_t cmd_env_sub[] = {
1119#if defined(CONFIG_CMD_ASKENV)
1120 U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", ""),
1121#endif
1122 U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", ""),
1123 U_BOOT_CMD_MKENT(delete, CONFIG_SYS_MAXARGS, 0, do_env_delete, "", ""),
1124#if defined(CONFIG_CMD_EDITENV)
1125 U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", ""),
1126#endif
1127#if defined(CONFIG_CMD_ENV_CALLBACK)
1128 U_BOOT_CMD_MKENT(callbacks, 1, 0, do_env_callback, "", ""),
1129#endif
1130#if defined(CONFIG_CMD_ENV_FLAGS)
1131 U_BOOT_CMD_MKENT(flags, 1, 0, do_env_flags, "", ""),
1132#endif
1133#if defined(CONFIG_CMD_EXPORTENV)
1134 U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", ""),
1135#endif
1136#if defined(CONFIG_CMD_GREPENV)
1137 U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""),
1138#endif
1139#if defined(CONFIG_CMD_IMPORTENV)
1140 U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""),
1141#endif
1142 U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""),
1143#if defined(CONFIG_CMD_RUN)
1144 U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""),
1145#endif
1146#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
1147 U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""),
1148#endif
1149 U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""),
1150#if defined(CONFIG_CMD_ENV_EXISTS)
1151 U_BOOT_CMD_MKENT(exists, 2, 0, do_env_exists, "", ""),
1152#endif
1153};
1154
1155#if defined(CONFIG_NEEDS_MANUAL_RELOC)
1156void env_reloc(void)
1157{
1158 fixup_cmdtable(cmd_env_sub, ARRAY_SIZE(cmd_env_sub));
1159}
1160#endif
1161
1162static int do_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1163{
1164 cmd_tbl_t *cp;
1165
1166 if (argc < 2)
1167 return CMD_RET_USAGE;
1168
1169
1170 argc--;
1171 argv++;
1172
1173 cp = find_cmd_tbl(argv[0], cmd_env_sub, ARRAY_SIZE(cmd_env_sub));
1174
1175 if (cp)
1176 return cp->cmd(cmdtp, flag, argc, argv);
1177
1178 return CMD_RET_USAGE;
1179}
1180
1181#ifdef CONFIG_SYS_LONGHELP
1182static char env_help_text[] =
1183#if defined(CONFIG_CMD_ASKENV)
1184 "ask name [message] [size] - ask for environment variable\nenv "
1185#endif
1186#if defined(CONFIG_CMD_ENV_CALLBACK)
1187 "callbacks - print callbacks and their associated variables\nenv "
1188#endif
1189 "default [-f] -a - [forcibly] reset default environment\n"
1190 "env default [-f] var [...] - [forcibly] reset variable(s) to their default values\n"
1191 "env delete [-f] var [...] - [forcibly] delete variable(s)\n"
1192#if defined(CONFIG_CMD_EDITENV)
1193 "env edit name - edit environment variable\n"
1194#endif
1195#if defined(CONFIG_CMD_ENV_EXISTS)
1196 "env exists name - tests for existence of variable\n"
1197#endif
1198#if defined(CONFIG_CMD_EXPORTENV)
1199 "env export [-t | -b | -c] [-s size] addr [var ...] - export environment\n"
1200#endif
1201#if defined(CONFIG_CMD_ENV_FLAGS)
1202 "env flags - print variables that have non-default flags\n"
1203#endif
1204#if defined(CONFIG_CMD_GREPENV)
1205#ifdef CONFIG_REGEX
1206 "env grep [-e] [-n | -v | -b] string [...] - search environment\n"
1207#else
1208 "env grep [-n | -v | -b] string [...] - search environment\n"
1209#endif
1210#endif
1211#if defined(CONFIG_CMD_IMPORTENV)
1212 "env import [-d] [-t [-r] | -b | -c] addr [size] - import environment\n"
1213#endif
1214 "env print [-a | name ...] - print environment\n"
1215#if defined(CONFIG_CMD_RUN)
1216 "env run var [...] - run commands in an environment variable\n"
1217#endif
1218#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
1219 "env save - save environment\n"
1220#endif
1221 "env set [-f] name [arg ...]\n";
1222#endif
1223
1224U_BOOT_CMD(
1225 env, CONFIG_SYS_MAXARGS, 1, do_env,
1226 "environment handling commands", env_help_text
1227);
1228
1229
1230
1231
1232
1233#if defined(CONFIG_CMD_EDITENV)
1234U_BOOT_CMD_COMPLETE(
1235 editenv, 2, 0, do_env_edit,
1236 "edit environment variable",
1237 "name\n"
1238 " - edit environment variable 'name'",
1239 var_complete
1240);
1241#endif
1242
1243U_BOOT_CMD_COMPLETE(
1244 printenv, CONFIG_SYS_MAXARGS, 1, do_env_print,
1245 "print environment variables",
1246 "[-a]\n - print [all] values of all environment variables\n"
1247 "printenv name ...\n"
1248 " - print value of environment variable 'name'",
1249 var_complete
1250);
1251
1252#ifdef CONFIG_CMD_GREPENV
1253U_BOOT_CMD_COMPLETE(
1254 grepenv, CONFIG_SYS_MAXARGS, 0, do_env_grep,
1255 "search environment variables",
1256#ifdef CONFIG_REGEX
1257 "[-e] [-n | -v | -b] string ...\n"
1258#else
1259 "[-n | -v | -b] string ...\n"
1260#endif
1261 " - list environment name=value pairs matching 'string'\n"
1262#ifdef CONFIG_REGEX
1263 " \"-e\": enable regular expressions;\n"
1264#endif
1265 " \"-n\": search variable names; \"-v\": search values;\n"
1266 " \"-b\": search both names and values (default)",
1267 var_complete
1268);
1269#endif
1270
1271U_BOOT_CMD_COMPLETE(
1272 setenv, CONFIG_SYS_MAXARGS, 0, do_env_set,
1273 "set environment variables",
1274 "[-f] name value ...\n"
1275 " - [forcibly] set environment variable 'name' to 'value ...'\n"
1276 "setenv [-f] name\n"
1277 " - [forcibly] delete environment variable 'name'",
1278 var_complete
1279);
1280
1281#if defined(CONFIG_CMD_ASKENV)
1282
1283U_BOOT_CMD(
1284 askenv, CONFIG_SYS_MAXARGS, 1, do_env_ask,
1285 "get environment variables from stdin",
1286 "name [message] [size]\n"
1287 " - get environment variable 'name' from stdin (max 'size' chars)"
1288);
1289#endif
1290
1291#if defined(CONFIG_CMD_RUN)
1292U_BOOT_CMD_COMPLETE(
1293 run, CONFIG_SYS_MAXARGS, 1, do_run,
1294 "run commands in an environment variable",
1295 "var [...]\n"
1296 " - run the commands in the environment variable(s) 'var'",
1297 var_complete
1298);
1299#endif
1300#endif
1301