nvedit.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000-2013
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. *
  6. * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  7. * Andreas Heppel <aheppel@sysgo.de>
  8. *
  9. * Copyright 2011 Freescale Semiconductor, Inc.
  10. */
  11. /*
  12. * Support for persistent environment data
  13. *
  14. * The "environment" is stored on external storage as a list of '\0'
  15. * terminated "name=value" strings. The end of the list is marked by
  16. * a double '\0'. The environment is preceded by a 32 bit CRC over
  17. * the data part and, in case of redundant environment, a byte of
  18. * flags.
  19. *
  20. * This linearized representation will also be used before
  21. * relocation, i. e. as long as we don't have a full C runtime
  22. * environment. After that, we use a hash table.
  23. */
  24. #include <common.h>
  25. #include <cli.h>
  26. #include <command.h>
  27. #include <console.h>
  28. #include <env.h>
  29. #include <env_internal.h>
  30. #include <net.h>
  31. #include <search.h>
  32. #include <errno.h>
  33. #include <malloc.h>
  34. #include <mapmem.h>
  35. #include <u-boot/crc.h>
  36. #include <watchdog.h>
  37. #include <linux/stddef.h>
  38. #include <asm/byteorder.h>
  39. #include <asm/io.h>
  40. DECLARE_GLOBAL_DATA_PTR;
  41. #if defined(CONFIG_ENV_IS_IN_EEPROM) || \
  42. defined(CONFIG_ENV_IS_IN_FLASH) || \
  43. defined(CONFIG_ENV_IS_IN_MMC) || \
  44. defined(CONFIG_ENV_IS_IN_FAT) || \
  45. defined(CONFIG_ENV_IS_IN_EXT4) || \
  46. defined(CONFIG_ENV_IS_IN_NAND) || \
  47. defined(CONFIG_ENV_IS_IN_NVRAM) || \
  48. defined(CONFIG_ENV_IS_IN_ONENAND) || \
  49. defined(CONFIG_ENV_IS_IN_SATA) || \
  50. defined(CONFIG_ENV_IS_IN_SPI_FLASH) || \
  51. defined(CONFIG_ENV_IS_IN_REMOTE) || \
  52. defined(CONFIG_ENV_IS_IN_UBI)
  53. #define ENV_IS_IN_DEVICE
  54. #endif
  55. #if !defined(ENV_IS_IN_DEVICE) && \
  56. !defined(CONFIG_ENV_IS_NOWHERE)
  57. # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|\
  58. NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
  59. #endif
  60. /*
  61. * Maximum expected input data size for import command
  62. */
  63. #define MAX_ENV_SIZE (1 << 20) /* 1 MiB */
  64. /*
  65. * This variable is incremented on each do_env_set(), so it can
  66. * be used via env_get_id() as an indication, if the environment
  67. * has changed or not. So it is possible to reread an environment
  68. * variable only if the environment was changed ... done so for
  69. * example in NetInitLoop()
  70. */
  71. static int env_id = 1;
  72. int env_get_id(void)
  73. {
  74. return env_id;
  75. }
  76. #ifndef CONFIG_SPL_BUILD
  77. /*
  78. * Command interface: print one or all environment variables
  79. *
  80. * Returns 0 in case of error, or length of printed string
  81. */
  82. static int env_print(char *name, int flag)
  83. {
  84. char *res = NULL;
  85. ssize_t len;
  86. if (name) { /* print a single name */
  87. struct env_entry e, *ep;
  88. e.key = name;
  89. e.data = NULL;
  90. hsearch_r(e, ENV_FIND, &ep, &env_htab, flag);
  91. if (ep == NULL)
  92. return 0;
  93. len = printf("%s=%s\n", ep->key, ep->data);
  94. return len;
  95. }
  96. /* print whole list */
  97. len = hexport_r(&env_htab, '\n', flag, &res, 0, 0, NULL);
  98. if (len > 0) {
  99. puts(res);
  100. free(res);
  101. return len;
  102. }
  103. /* should never happen */
  104. printf("## Error: cannot export environment\n");
  105. return 0;
  106. }
  107. static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,
  108. char * const argv[])
  109. {
  110. int i;
  111. int rcode = 0;
  112. int env_flag = H_HIDE_DOT;
  113. #if defined(CONFIG_CMD_NVEDIT_EFI)
  114. if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e')
  115. return do_env_print_efi(cmdtp, flag, --argc, ++argv);
  116. #endif
  117. if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'a') {
  118. argc--;
  119. argv++;
  120. env_flag &= ~H_HIDE_DOT;
  121. }
  122. if (argc == 1) {
  123. /* print all env vars */
  124. rcode = env_print(NULL, env_flag);
  125. if (!rcode)
  126. return 1;
  127. printf("\nEnvironment size: %d/%ld bytes\n",
  128. rcode, (ulong)ENV_SIZE);
  129. return 0;
  130. }
  131. /* print selected env vars */
  132. env_flag &= ~H_HIDE_DOT;
  133. for (i = 1; i < argc; ++i) {
  134. int rc = env_print(argv[i], env_flag);
  135. if (!rc) {
  136. printf("## Error: \"%s\" not defined\n", argv[i]);
  137. ++rcode;
  138. }
  139. }
  140. return rcode;
  141. }
  142. #ifdef CONFIG_CMD_GREPENV
  143. static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
  144. int argc, char * const argv[])
  145. {
  146. char *res = NULL;
  147. int len, grep_how, grep_what;
  148. if (argc < 2)
  149. return CMD_RET_USAGE;
  150. grep_how = H_MATCH_SUBSTR; /* default: substring search */
  151. grep_what = H_MATCH_BOTH; /* default: grep names and values */
  152. while (--argc > 0 && **++argv == '-') {
  153. char *arg = *argv;
  154. while (*++arg) {
  155. switch (*arg) {
  156. #ifdef CONFIG_REGEX
  157. case 'e': /* use regex matching */
  158. grep_how = H_MATCH_REGEX;
  159. break;
  160. #endif
  161. case 'n': /* grep for name */
  162. grep_what = H_MATCH_KEY;
  163. break;
  164. case 'v': /* grep for value */
  165. grep_what = H_MATCH_DATA;
  166. break;
  167. case 'b': /* grep for both */
  168. grep_what = H_MATCH_BOTH;
  169. break;
  170. case '-':
  171. goto DONE;
  172. default:
  173. return CMD_RET_USAGE;
  174. }
  175. }
  176. }
  177. DONE:
  178. len = hexport_r(&env_htab, '\n',
  179. flag | grep_what | grep_how,
  180. &res, 0, argc, argv);
  181. if (len > 0) {
  182. puts(res);
  183. free(res);
  184. }
  185. if (len < 2)
  186. return 1;
  187. return 0;
  188. }
  189. #endif
  190. #endif /* CONFIG_SPL_BUILD */
  191. /*
  192. * Set a new environment variable,
  193. * or replace or delete an existing one.
  194. */
  195. static int _do_env_set(int flag, int argc, char * const argv[], int env_flag)
  196. {
  197. int i, len;
  198. char *name, *value, *s;
  199. struct env_entry e, *ep;
  200. debug("Initial value for argc=%d\n", argc);
  201. #if CONFIG_IS_ENABLED(CMD_NVEDIT_EFI)
  202. if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e')
  203. return do_env_set_efi(NULL, flag, --argc, ++argv);
  204. #endif
  205. while (argc > 1 && **(argv + 1) == '-') {
  206. char *arg = *++argv;
  207. --argc;
  208. while (*++arg) {
  209. switch (*arg) {
  210. case 'f': /* force */
  211. env_flag |= H_FORCE;
  212. break;
  213. default:
  214. return CMD_RET_USAGE;
  215. }
  216. }
  217. }
  218. debug("Final value for argc=%d\n", argc);
  219. name = argv[1];
  220. if (strchr(name, '=')) {
  221. printf("## Error: illegal character '='"
  222. "in variable name \"%s\"\n", name);
  223. return 1;
  224. }
  225. env_id++;
  226. /* Delete only ? */
  227. if (argc < 3 || argv[2] == NULL) {
  228. int rc = hdelete_r(name, &env_htab, env_flag);
  229. return !rc;
  230. }
  231. /*
  232. * Insert / replace new value
  233. */
  234. for (i = 2, len = 0; i < argc; ++i)
  235. len += strlen(argv[i]) + 1;
  236. value = malloc(len);
  237. if (value == NULL) {
  238. printf("## Can't malloc %d bytes\n", len);
  239. return 1;
  240. }
  241. for (i = 2, s = value; i < argc; ++i) {
  242. char *v = argv[i];
  243. while ((*s++ = *v++) != '\0')
  244. ;
  245. *(s - 1) = ' ';
  246. }
  247. if (s != value)
  248. *--s = '\0';
  249. e.key = name;
  250. e.data = value;
  251. hsearch_r(e, ENV_ENTER, &ep, &env_htab, env_flag);
  252. free(value);
  253. if (!ep) {
  254. printf("## Error inserting \"%s\" variable, errno=%d\n",
  255. name, errno);
  256. return 1;
  257. }
  258. return 0;
  259. }
  260. int env_set(const char *varname, const char *varvalue)
  261. {
  262. const char * const argv[4] = { "setenv", varname, varvalue, NULL };
  263. /* before import into hashtable */
  264. if (!(gd->flags & GD_FLG_ENV_READY))
  265. return 1;
  266. if (varvalue == NULL || varvalue[0] == '\0')
  267. return _do_env_set(0, 2, (char * const *)argv, H_PROGRAMMATIC);
  268. else
  269. return _do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC);
  270. }
  271. /**
  272. * Set an environment variable to an integer value
  273. *
  274. * @param varname Environment variable to set
  275. * @param value Value to set it to
  276. * @return 0 if ok, 1 on error
  277. */
  278. int env_set_ulong(const char *varname, ulong value)
  279. {
  280. /* TODO: this should be unsigned */
  281. char *str = simple_itoa(value);
  282. return env_set(varname, str);
  283. }
  284. /**
  285. * Set an environment variable to an value in hex
  286. *
  287. * @param varname Environment variable to set
  288. * @param value Value to set it to
  289. * @return 0 if ok, 1 on error
  290. */
  291. int env_set_hex(const char *varname, ulong value)
  292. {
  293. char str[17];
  294. sprintf(str, "%lx", value);
  295. return env_set(varname, str);
  296. }
  297. ulong env_get_hex(const char *varname, ulong default_val)
  298. {
  299. const char *s;
  300. ulong value;
  301. char *endp;
  302. s = env_get(varname);
  303. if (s)
  304. value = simple_strtoul(s, &endp, 16);
  305. if (!s || endp == s)
  306. return default_val;
  307. return value;
  308. }
  309. int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr)
  310. {
  311. string_to_enetaddr(env_get(name), enetaddr);
  312. return is_valid_ethaddr(enetaddr);
  313. }
  314. int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr)
  315. {
  316. char buf[ARP_HLEN_ASCII + 1];
  317. if (eth_env_get_enetaddr(name, (uint8_t *)buf))
  318. return -EEXIST;
  319. sprintf(buf, "%pM", enetaddr);
  320. return env_set(name, buf);
  321. }
  322. #ifndef CONFIG_SPL_BUILD
  323. static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  324. {
  325. if (argc < 2)
  326. return CMD_RET_USAGE;
  327. return _do_env_set(flag, argc, argv, H_INTERACTIVE);
  328. }
  329. /*
  330. * Prompt for environment variable
  331. */
  332. #if defined(CONFIG_CMD_ASKENV)
  333. int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  334. {
  335. char message[CONFIG_SYS_CBSIZE];
  336. int i, len, pos, size;
  337. char *local_args[4];
  338. char *endptr;
  339. local_args[0] = argv[0];
  340. local_args[1] = argv[1];
  341. local_args[2] = NULL;
  342. local_args[3] = NULL;
  343. /*
  344. * Check the syntax:
  345. *
  346. * env_ask envname [message1 ...] [size]
  347. */
  348. if (argc == 1)
  349. return CMD_RET_USAGE;
  350. /*
  351. * We test the last argument if it can be converted
  352. * into a decimal number. If yes, we assume it's
  353. * the size. Otherwise we echo it as part of the
  354. * message.
  355. */
  356. i = simple_strtoul(argv[argc - 1], &endptr, 10);
  357. if (*endptr != '\0') { /* no size */
  358. size = CONFIG_SYS_CBSIZE - 1;
  359. } else { /* size given */
  360. size = i;
  361. --argc;
  362. }
  363. if (argc <= 2) {
  364. sprintf(message, "Please enter '%s': ", argv[1]);
  365. } else {
  366. /* env_ask envname message1 ... messagen [size] */
  367. for (i = 2, pos = 0; i < argc && pos+1 < sizeof(message); i++) {
  368. if (pos)
  369. message[pos++] = ' ';
  370. strncpy(message + pos, argv[i], sizeof(message) - pos);
  371. pos += strlen(argv[i]);
  372. }
  373. if (pos < sizeof(message) - 1) {
  374. message[pos++] = ' ';
  375. message[pos] = '\0';
  376. } else
  377. message[CONFIG_SYS_CBSIZE - 1] = '\0';
  378. }
  379. if (size >= CONFIG_SYS_CBSIZE)
  380. size = CONFIG_SYS_CBSIZE - 1;
  381. if (size <= 0)
  382. return 1;
  383. /* prompt for input */
  384. len = cli_readline(message);
  385. if (size < len)
  386. console_buffer[size] = '\0';
  387. len = 2;
  388. if (console_buffer[0] != '\0') {
  389. local_args[2] = console_buffer;
  390. len = 3;
  391. }
  392. /* Continue calling setenv code */
  393. return _do_env_set(flag, len, local_args, H_INTERACTIVE);
  394. }
  395. #endif
  396. #if defined(CONFIG_CMD_ENV_CALLBACK)
  397. static int print_static_binding(const char *var_name, const char *callback_name,
  398. void *priv)
  399. {
  400. printf("\t%-20s %-20s\n", var_name, callback_name);
  401. return 0;
  402. }
  403. static int print_active_callback(struct env_entry *entry)
  404. {
  405. struct env_clbk_tbl *clbkp;
  406. int i;
  407. int num_callbacks;
  408. if (entry->callback == NULL)
  409. return 0;
  410. /* look up the callback in the linker-list */
  411. num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
  412. for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
  413. i < num_callbacks;
  414. i++, clbkp++) {
  415. #if defined(CONFIG_NEEDS_MANUAL_RELOC)
  416. if (entry->callback == clbkp->callback + gd->reloc_off)
  417. #else
  418. if (entry->callback == clbkp->callback)
  419. #endif
  420. break;
  421. }
  422. if (i == num_callbacks)
  423. /* this should probably never happen, but just in case... */
  424. printf("\t%-20s %p\n", entry->key, entry->callback);
  425. else
  426. printf("\t%-20s %-20s\n", entry->key, clbkp->name);
  427. return 0;
  428. }
  429. /*
  430. * Print the callbacks available and what they are bound to
  431. */
  432. int do_env_callback(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  433. {
  434. struct env_clbk_tbl *clbkp;
  435. int i;
  436. int num_callbacks;
  437. /* Print the available callbacks */
  438. puts("Available callbacks:\n");
  439. puts("\tCallback Name\n");
  440. puts("\t-------------\n");
  441. num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
  442. for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
  443. i < num_callbacks;
  444. i++, clbkp++)
  445. printf("\t%s\n", clbkp->name);
  446. puts("\n");
  447. /* Print the static bindings that may exist */
  448. puts("Static callback bindings:\n");
  449. printf("\t%-20s %-20s\n", "Variable Name", "Callback Name");
  450. printf("\t%-20s %-20s\n", "-------------", "-------------");
  451. env_attr_walk(ENV_CALLBACK_LIST_STATIC, print_static_binding, NULL);
  452. puts("\n");
  453. /* walk through each variable and print the callback if it has one */
  454. puts("Active callback bindings:\n");
  455. printf("\t%-20s %-20s\n", "Variable Name", "Callback Name");
  456. printf("\t%-20s %-20s\n", "-------------", "-------------");
  457. hwalk_r(&env_htab, print_active_callback);
  458. return 0;
  459. }
  460. #endif
  461. #if defined(CONFIG_CMD_ENV_FLAGS)
  462. static int print_static_flags(const char *var_name, const char *flags,
  463. void *priv)
  464. {
  465. enum env_flags_vartype type = env_flags_parse_vartype(flags);
  466. enum env_flags_varaccess access = env_flags_parse_varaccess(flags);
  467. printf("\t%-20s %-20s %-20s\n", var_name,
  468. env_flags_get_vartype_name(type),
  469. env_flags_get_varaccess_name(access));
  470. return 0;
  471. }
  472. static int print_active_flags(struct env_entry *entry)
  473. {
  474. enum env_flags_vartype type;
  475. enum env_flags_varaccess access;
  476. if (entry->flags == 0)
  477. return 0;
  478. type = (enum env_flags_vartype)
  479. (entry->flags & ENV_FLAGS_VARTYPE_BIN_MASK);
  480. access = env_flags_parse_varaccess_from_binflags(entry->flags);
  481. printf("\t%-20s %-20s %-20s\n", entry->key,
  482. env_flags_get_vartype_name(type),
  483. env_flags_get_varaccess_name(access));
  484. return 0;
  485. }
  486. /*
  487. * Print the flags available and what variables have flags
  488. */
  489. int do_env_flags(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  490. {
  491. /* Print the available variable types */
  492. printf("Available variable type flags (position %d):\n",
  493. ENV_FLAGS_VARTYPE_LOC);
  494. puts("\tFlag\tVariable Type Name\n");
  495. puts("\t----\t------------------\n");
  496. env_flags_print_vartypes();
  497. puts("\n");
  498. /* Print the available variable access types */
  499. printf("Available variable access flags (position %d):\n",
  500. ENV_FLAGS_VARACCESS_LOC);
  501. puts("\tFlag\tVariable Access Name\n");
  502. puts("\t----\t--------------------\n");
  503. env_flags_print_varaccess();
  504. puts("\n");
  505. /* Print the static flags that may exist */
  506. puts("Static flags:\n");
  507. printf("\t%-20s %-20s %-20s\n", "Variable Name", "Variable Type",
  508. "Variable Access");
  509. printf("\t%-20s %-20s %-20s\n", "-------------", "-------------",
  510. "---------------");
  511. env_attr_walk(ENV_FLAGS_LIST_STATIC, print_static_flags, NULL);
  512. puts("\n");
  513. /* walk through each variable and print the flags if non-default */
  514. puts("Active flags:\n");
  515. printf("\t%-20s %-20s %-20s\n", "Variable Name", "Variable Type",
  516. "Variable Access");
  517. printf("\t%-20s %-20s %-20s\n", "-------------", "-------------",
  518. "---------------");
  519. hwalk_r(&env_htab, print_active_flags);
  520. return 0;
  521. }
  522. #endif
  523. /*
  524. * Interactively edit an environment variable
  525. */
  526. #if defined(CONFIG_CMD_EDITENV)
  527. static int do_env_edit(cmd_tbl_t *cmdtp, int flag, int argc,
  528. char * const argv[])
  529. {
  530. char buffer[CONFIG_SYS_CBSIZE];
  531. char *init_val;
  532. if (argc < 2)
  533. return CMD_RET_USAGE;
  534. /* before import into hashtable */
  535. if (!(gd->flags & GD_FLG_ENV_READY))
  536. return 1;
  537. /* Set read buffer to initial value or empty sting */
  538. init_val = env_get(argv[1]);
  539. if (init_val)
  540. snprintf(buffer, CONFIG_SYS_CBSIZE, "%s", init_val);
  541. else
  542. buffer[0] = '\0';
  543. if (cli_readline_into_buffer("edit: ", buffer, 0) < 0)
  544. return 1;
  545. if (buffer[0] == '\0') {
  546. const char * const _argv[3] = { "setenv", argv[1], NULL };
  547. return _do_env_set(0, 2, (char * const *)_argv, H_INTERACTIVE);
  548. } else {
  549. const char * const _argv[4] = { "setenv", argv[1], buffer,
  550. NULL };
  551. return _do_env_set(0, 3, (char * const *)_argv, H_INTERACTIVE);
  552. }
  553. }
  554. #endif /* CONFIG_CMD_EDITENV */
  555. #endif /* CONFIG_SPL_BUILD */
  556. /*
  557. * Look up variable from environment,
  558. * return address of storage for that variable,
  559. * or NULL if not found
  560. */
  561. char *env_get(const char *name)
  562. {
  563. if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */
  564. struct env_entry e, *ep;
  565. WATCHDOG_RESET();
  566. e.key = name;
  567. e.data = NULL;
  568. hsearch_r(e, ENV_FIND, &ep, &env_htab, 0);
  569. return ep ? ep->data : NULL;
  570. }
  571. /* restricted capabilities before import */
  572. if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)
  573. return (char *)(gd->env_buf);
  574. return NULL;
  575. }
  576. /*
  577. * Like env_get, but prints an error if envvar isn't defined in the
  578. * environment. It always returns what env_get does, so it can be used in
  579. * place of env_get without changing error handling otherwise.
  580. */
  581. char *from_env(const char *envvar)
  582. {
  583. char *ret;
  584. ret = env_get(envvar);
  585. if (!ret)
  586. printf("missing environment variable: %s\n", envvar);
  587. return ret;
  588. }
  589. /*
  590. * Look up variable from environment for restricted C runtime env.
  591. */
  592. int env_get_f(const char *name, char *buf, unsigned len)
  593. {
  594. int i, nxt, c;
  595. for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
  596. int val, n;
  597. for (nxt = i; (c = env_get_char(nxt)) != '\0'; ++nxt) {
  598. if (c < 0)
  599. return c;
  600. if (nxt >= CONFIG_ENV_SIZE)
  601. return -1;
  602. }
  603. val = env_match((uchar *)name, i);
  604. if (val < 0)
  605. continue;
  606. /* found; copy out */
  607. for (n = 0; n < len; ++n, ++buf) {
  608. c = env_get_char(val++);
  609. if (c < 0)
  610. return c;
  611. *buf = c;
  612. if (*buf == '\0')
  613. return n;
  614. }
  615. if (n)
  616. *--buf = '\0';
  617. printf("env_buf [%u bytes] too small for value of \"%s\"\n",
  618. len, name);
  619. return n;
  620. }
  621. return -1;
  622. }
  623. /**
  624. * Decode the integer value of an environment variable and return it.
  625. *
  626. * @param name Name of environment variable
  627. * @param base Number base to use (normally 10, or 16 for hex)
  628. * @param default_val Default value to return if the variable is not
  629. * found
  630. * @return the decoded value, or default_val if not found
  631. */
  632. ulong env_get_ulong(const char *name, int base, ulong default_val)
  633. {
  634. /*
  635. * We can use env_get() here, even before relocation, since the
  636. * environment variable value is an integer and thus short.
  637. */
  638. const char *str = env_get(name);
  639. return str ? simple_strtoul(str, NULL, base) : default_val;
  640. }
  641. #ifndef CONFIG_SPL_BUILD
  642. #if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
  643. static int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc,
  644. char * const argv[])
  645. {
  646. return env_save() ? 1 : 0;
  647. }
  648. U_BOOT_CMD(
  649. saveenv, 1, 0, do_env_save,
  650. "save environment variables to persistent storage",
  651. ""
  652. );
  653. #if defined(CONFIG_CMD_ERASEENV)
  654. static int do_env_erase(cmd_tbl_t *cmdtp, int flag, int argc,
  655. char * const argv[])
  656. {
  657. return env_erase() ? 1 : 0;
  658. }
  659. U_BOOT_CMD(
  660. eraseenv, 1, 0, do_env_erase,
  661. "erase environment variables from persistent storage",
  662. ""
  663. );
  664. #endif
  665. #endif
  666. #endif /* CONFIG_SPL_BUILD */
  667. int env_match(uchar *s1, int i2)
  668. {
  669. if (s1 == NULL)
  670. return -1;
  671. while (*s1 == env_get_char(i2++))
  672. if (*s1++ == '=')
  673. return i2;
  674. if (*s1 == '\0' && env_get_char(i2-1) == '=')
  675. return i2;
  676. return -1;
  677. }
  678. #ifndef CONFIG_SPL_BUILD
  679. static int do_env_default(cmd_tbl_t *cmdtp, int flag,
  680. int argc, char * const argv[])
  681. {
  682. int all = 0, env_flag = H_INTERACTIVE;
  683. debug("Initial value for argc=%d\n", argc);
  684. while (--argc > 0 && **++argv == '-') {
  685. char *arg = *argv;
  686. while (*++arg) {
  687. switch (*arg) {
  688. case 'a': /* default all */
  689. all = 1;
  690. break;
  691. case 'f': /* force */
  692. env_flag |= H_FORCE;
  693. break;
  694. default:
  695. return cmd_usage(cmdtp);
  696. }
  697. }
  698. }
  699. debug("Final value for argc=%d\n", argc);
  700. if (all && (argc == 0)) {
  701. /* Reset the whole environment */
  702. env_set_default("## Resetting to default environment\n",
  703. env_flag);
  704. return 0;
  705. }
  706. if (!all && (argc > 0)) {
  707. /* Reset individual variables */
  708. env_set_default_vars(argc, argv, env_flag);
  709. return 0;
  710. }
  711. return cmd_usage(cmdtp);
  712. }
  713. static int do_env_delete(cmd_tbl_t *cmdtp, int flag,
  714. int argc, char * const argv[])
  715. {
  716. int env_flag = H_INTERACTIVE;
  717. int ret = 0;
  718. debug("Initial value for argc=%d\n", argc);
  719. while (argc > 1 && **(argv + 1) == '-') {
  720. char *arg = *++argv;
  721. --argc;
  722. while (*++arg) {
  723. switch (*arg) {
  724. case 'f': /* force */
  725. env_flag |= H_FORCE;
  726. break;
  727. default:
  728. return CMD_RET_USAGE;
  729. }
  730. }
  731. }
  732. debug("Final value for argc=%d\n", argc);
  733. env_id++;
  734. while (--argc > 0) {
  735. char *name = *++argv;
  736. if (!hdelete_r(name, &env_htab, env_flag))
  737. ret = 1;
  738. }
  739. return ret;
  740. }
  741. #ifdef CONFIG_CMD_EXPORTENV
  742. /*
  743. * env export [-t | -b | -c] [-s size] addr [var ...]
  744. * -t: export as text format; if size is given, data will be
  745. * padded with '\0' bytes; if not, one terminating '\0'
  746. * will be added (which is included in the "filesize"
  747. * setting so you can for exmple copy this to flash and
  748. * keep the termination).
  749. * -b: export as binary format (name=value pairs separated by
  750. * '\0', list end marked by double "\0\0")
  751. * -c: export as checksum protected environment format as
  752. * used for example by "saveenv" command
  753. * -s size:
  754. * size of output buffer
  755. * addr: memory address where environment gets stored
  756. * var... List of variable names that get included into the
  757. * export. Without arguments, the whole environment gets
  758. * exported.
  759. *
  760. * With "-c" and size is NOT given, then the export command will
  761. * format the data as currently used for the persistent storage,
  762. * i. e. it will use CONFIG_ENV_SECT_SIZE as output block size and
  763. * prepend a valid CRC32 checksum and, in case of redundant
  764. * environment, a "current" redundancy flag. If size is given, this
  765. * value will be used instead of CONFIG_ENV_SECT_SIZE; again, CRC32
  766. * checksum and redundancy flag will be inserted.
  767. *
  768. * With "-b" and "-t", always only the real data (including a
  769. * terminating '\0' byte) will be written; here the optional size
  770. * argument will be used to make sure not to overflow the user
  771. * provided buffer; the command will abort if the size is not
  772. * sufficient. Any remaining space will be '\0' padded.
  773. *
  774. * On successful return, the variable "filesize" will be set.
  775. * Note that filesize includes the trailing/terminating '\0' byte(s).
  776. *
  777. * Usage scenario: create a text snapshot/backup of the current settings:
  778. *
  779. * => env export -t 100000
  780. * => era ${backup_addr} +${filesize}
  781. * => cp.b 100000 ${backup_addr} ${filesize}
  782. *
  783. * Re-import this snapshot, deleting all other settings:
  784. *
  785. * => env import -d -t ${backup_addr}
  786. */
  787. static int do_env_export(cmd_tbl_t *cmdtp, int flag,
  788. int argc, char * const argv[])
  789. {
  790. char buf[32];
  791. ulong addr;
  792. char *ptr, *cmd, *res;
  793. size_t size = 0;
  794. ssize_t len;
  795. env_t *envp;
  796. char sep = '\n';
  797. int chk = 0;
  798. int fmt = 0;
  799. cmd = *argv;
  800. while (--argc > 0 && **++argv == '-') {
  801. char *arg = *argv;
  802. while (*++arg) {
  803. switch (*arg) {
  804. case 'b': /* raw binary format */
  805. if (fmt++)
  806. goto sep_err;
  807. sep = '\0';
  808. break;
  809. case 'c': /* external checksum format */
  810. if (fmt++)
  811. goto sep_err;
  812. sep = '\0';
  813. chk = 1;
  814. break;
  815. case 's': /* size given */
  816. if (--argc <= 0)
  817. return cmd_usage(cmdtp);
  818. size = simple_strtoul(*++argv, NULL, 16);
  819. goto NXTARG;
  820. case 't': /* text format */
  821. if (fmt++)
  822. goto sep_err;
  823. sep = '\n';
  824. break;
  825. default:
  826. return CMD_RET_USAGE;
  827. }
  828. }
  829. NXTARG: ;
  830. }
  831. if (argc < 1)
  832. return CMD_RET_USAGE;
  833. addr = simple_strtoul(argv[0], NULL, 16);
  834. ptr = map_sysmem(addr, size);
  835. if (size)
  836. memset(ptr, '\0', size);
  837. argc--;
  838. argv++;
  839. if (sep) { /* export as text file */
  840. len = hexport_r(&env_htab, sep,
  841. H_MATCH_KEY | H_MATCH_IDENT,
  842. &ptr, size, argc, argv);
  843. if (len < 0) {
  844. pr_err("## Error: Cannot export environment: errno = %d\n",
  845. errno);
  846. return 1;
  847. }
  848. sprintf(buf, "%zX", (size_t)len);
  849. env_set("filesize", buf);
  850. return 0;
  851. }
  852. envp = (env_t *)ptr;
  853. if (chk) /* export as checksum protected block */
  854. res = (char *)envp->data;
  855. else /* export as raw binary data */
  856. res = ptr;
  857. len = hexport_r(&env_htab, '\0',
  858. H_MATCH_KEY | H_MATCH_IDENT,
  859. &res, ENV_SIZE, argc, argv);
  860. if (len < 0) {
  861. pr_err("## Error: Cannot export environment: errno = %d\n",
  862. errno);
  863. return 1;
  864. }
  865. if (chk) {
  866. envp->crc = crc32(0, envp->data,
  867. size ? size - offsetof(env_t, data) : ENV_SIZE);
  868. #ifdef CONFIG_ENV_ADDR_REDUND
  869. envp->flags = ENV_REDUND_ACTIVE;
  870. #endif
  871. }
  872. env_set_hex("filesize", len + offsetof(env_t, data));
  873. return 0;
  874. sep_err:
  875. printf("## Error: %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n",
  876. cmd);
  877. return 1;
  878. }
  879. #endif
  880. #ifdef CONFIG_CMD_IMPORTENV
  881. /*
  882. * env import [-d] [-t [-r] | -b | -c] addr [size] [var ...]
  883. * -d: delete existing environment before importing if no var is
  884. * passed; if vars are passed, if one var is in the current
  885. * environment but not in the environment at addr, delete var from
  886. * current environment;
  887. * otherwise overwrite / append to existing definitions
  888. * -t: assume text format; either "size" must be given or the
  889. * text data must be '\0' terminated
  890. * -r: handle CRLF like LF, that means exported variables with
  891. * a content which ends with \r won't get imported. Used
  892. * to import text files created with editors which are using CRLF
  893. * for line endings. Only effective in addition to -t.
  894. * -b: assume binary format ('\0' separated, "\0\0" terminated)
  895. * -c: assume checksum protected environment format
  896. * addr: memory address to read from
  897. * size: length of input data; if missing, proper '\0'
  898. * termination is mandatory
  899. * if var is set and size should be missing (i.e. '\0'
  900. * termination), set size to '-'
  901. * var... List of the names of the only variables that get imported from
  902. * the environment at address 'addr'. Without arguments, the whole
  903. * environment gets imported.
  904. */
  905. static int do_env_import(cmd_tbl_t *cmdtp, int flag,
  906. int argc, char * const argv[])
  907. {
  908. ulong addr;
  909. char *cmd, *ptr;
  910. char sep = '\n';
  911. int chk = 0;
  912. int fmt = 0;
  913. int del = 0;
  914. int crlf_is_lf = 0;
  915. int wl = 0;
  916. size_t size;
  917. cmd = *argv;
  918. while (--argc > 0 && **++argv == '-') {
  919. char *arg = *argv;
  920. while (*++arg) {
  921. switch (*arg) {
  922. case 'b': /* raw binary format */
  923. if (fmt++)
  924. goto sep_err;
  925. sep = '\0';
  926. break;
  927. case 'c': /* external checksum format */
  928. if (fmt++)
  929. goto sep_err;
  930. sep = '\0';
  931. chk = 1;
  932. break;
  933. case 't': /* text format */
  934. if (fmt++)
  935. goto sep_err;
  936. sep = '\n';
  937. break;
  938. case 'r': /* handle CRLF like LF */
  939. crlf_is_lf = 1;
  940. break;
  941. case 'd':
  942. del = 1;
  943. break;
  944. default:
  945. return CMD_RET_USAGE;
  946. }
  947. }
  948. }
  949. if (argc < 1)
  950. return CMD_RET_USAGE;
  951. if (!fmt)
  952. printf("## Warning: defaulting to text format\n");
  953. if (sep != '\n' && crlf_is_lf )
  954. crlf_is_lf = 0;
  955. addr = simple_strtoul(argv[0], NULL, 16);
  956. ptr = map_sysmem(addr, 0);
  957. if (argc >= 2 && strcmp(argv[1], "-")) {
  958. size = simple_strtoul(argv[1], NULL, 16);
  959. } else if (chk) {
  960. puts("## Error: external checksum format must pass size\n");
  961. return CMD_RET_FAILURE;
  962. } else {
  963. char *s = ptr;
  964. size = 0;
  965. while (size < MAX_ENV_SIZE) {
  966. if ((*s == sep) && (*(s+1) == '\0'))
  967. break;
  968. ++s;
  969. ++size;
  970. }
  971. if (size == MAX_ENV_SIZE) {
  972. printf("## Warning: Input data exceeds %d bytes"
  973. " - truncated\n", MAX_ENV_SIZE);
  974. }
  975. size += 2;
  976. printf("## Info: input data size = %zu = 0x%zX\n", size, size);
  977. }
  978. if (argc > 2)
  979. wl = 1;
  980. if (chk) {
  981. uint32_t crc;
  982. env_t *ep = (env_t *)ptr;
  983. size -= offsetof(env_t, data);
  984. memcpy(&crc, &ep->crc, sizeof(crc));
  985. if (crc32(0, ep->data, size) != crc) {
  986. puts("## Error: bad CRC, import failed\n");
  987. return 1;
  988. }
  989. ptr = (char *)ep->data;
  990. }
  991. if (!himport_r(&env_htab, ptr, size, sep, del ? 0 : H_NOCLEAR,
  992. crlf_is_lf, wl ? argc - 2 : 0, wl ? &argv[2] : NULL)) {
  993. pr_err("## Error: Environment import failed: errno = %d\n",
  994. errno);
  995. return 1;
  996. }
  997. gd->flags |= GD_FLG_ENV_READY;
  998. return 0;
  999. sep_err:
  1000. printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n",
  1001. cmd);
  1002. return 1;
  1003. }
  1004. #endif
  1005. #if defined(CONFIG_CMD_NVEDIT_INFO)
  1006. /*
  1007. * print_env_info - print environment information
  1008. */
  1009. static int print_env_info(void)
  1010. {
  1011. const char *value;
  1012. /* print environment validity value */
  1013. switch (gd->env_valid) {
  1014. case ENV_INVALID:
  1015. value = "invalid";
  1016. break;
  1017. case ENV_VALID:
  1018. value = "valid";
  1019. break;
  1020. case ENV_REDUND:
  1021. value = "redundant";
  1022. break;
  1023. default:
  1024. value = "unknown";
  1025. break;
  1026. }
  1027. printf("env_valid = %s\n", value);
  1028. /* print environment ready flag */
  1029. value = gd->flags & GD_FLG_ENV_READY ? "true" : "false";
  1030. printf("env_ready = %s\n", value);
  1031. /* print environment using default flag */
  1032. value = gd->flags & GD_FLG_ENV_DEFAULT ? "true" : "false";
  1033. printf("env_use_default = %s\n", value);
  1034. return CMD_RET_SUCCESS;
  1035. }
  1036. #define ENV_INFO_IS_DEFAULT BIT(0) /* default environment bit mask */
  1037. #define ENV_INFO_IS_PERSISTED BIT(1) /* environment persistence bit mask */
  1038. /*
  1039. * env info - display environment information
  1040. * env info [-d] - evaluate whether default environment is used
  1041. * env info [-p] - evaluate whether environment can be persisted
  1042. */
  1043. static int do_env_info(cmd_tbl_t *cmdtp, int flag,
  1044. int argc, char * const argv[])
  1045. {
  1046. int eval_flags = 0;
  1047. int eval_results = 0;
  1048. /* display environment information */
  1049. if (argc <= 1)
  1050. return print_env_info();
  1051. /* process options */
  1052. while (--argc > 0 && **++argv == '-') {
  1053. char *arg = *argv;
  1054. while (*++arg) {
  1055. switch (*arg) {
  1056. case 'd':
  1057. eval_flags |= ENV_INFO_IS_DEFAULT;
  1058. break;
  1059. case 'p':
  1060. eval_flags |= ENV_INFO_IS_PERSISTED;
  1061. break;
  1062. default:
  1063. return CMD_RET_USAGE;
  1064. }
  1065. }
  1066. }
  1067. /* evaluate whether default environment is used */
  1068. if (eval_flags & ENV_INFO_IS_DEFAULT) {
  1069. if (gd->flags & GD_FLG_ENV_DEFAULT) {
  1070. printf("Default environment is used\n");
  1071. eval_results |= ENV_INFO_IS_DEFAULT;
  1072. } else {
  1073. printf("Environment was loaded from persistent storage\n");
  1074. }
  1075. }
  1076. /* evaluate whether environment can be persisted */
  1077. if (eval_flags & ENV_INFO_IS_PERSISTED) {
  1078. #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
  1079. printf("Environment can be persisted\n");
  1080. eval_results |= ENV_INFO_IS_PERSISTED;
  1081. #else
  1082. printf("Environment cannot be persisted\n");
  1083. #endif
  1084. }
  1085. /* The result of evaluations is combined with AND */
  1086. if (eval_flags != eval_results)
  1087. return CMD_RET_FAILURE;
  1088. return CMD_RET_SUCCESS;
  1089. }
  1090. #endif
  1091. #if defined(CONFIG_CMD_ENV_EXISTS)
  1092. static int do_env_exists(cmd_tbl_t *cmdtp, int flag, int argc,
  1093. char * const argv[])
  1094. {
  1095. struct env_entry e, *ep;
  1096. if (argc < 2)
  1097. return CMD_RET_USAGE;
  1098. e.key = argv[1];
  1099. e.data = NULL;
  1100. hsearch_r(e, ENV_FIND, &ep, &env_htab, 0);
  1101. return (ep == NULL) ? 1 : 0;
  1102. }
  1103. #endif
  1104. /*
  1105. * New command line interface: "env" command with subcommands
  1106. */
  1107. static cmd_tbl_t cmd_env_sub[] = {
  1108. #if defined(CONFIG_CMD_ASKENV)
  1109. U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", ""),
  1110. #endif
  1111. U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", ""),
  1112. U_BOOT_CMD_MKENT(delete, CONFIG_SYS_MAXARGS, 0, do_env_delete, "", ""),
  1113. #if defined(CONFIG_CMD_EDITENV)
  1114. U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", ""),
  1115. #endif
  1116. #if defined(CONFIG_CMD_ENV_CALLBACK)
  1117. U_BOOT_CMD_MKENT(callbacks, 1, 0, do_env_callback, "", ""),
  1118. #endif
  1119. #if defined(CONFIG_CMD_ENV_FLAGS)
  1120. U_BOOT_CMD_MKENT(flags, 1, 0, do_env_flags, "", ""),
  1121. #endif
  1122. #if defined(CONFIG_CMD_EXPORTENV)
  1123. U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", ""),
  1124. #endif
  1125. #if defined(CONFIG_CMD_GREPENV)
  1126. U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""),
  1127. #endif
  1128. #if defined(CONFIG_CMD_IMPORTENV)
  1129. U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""),
  1130. #endif
  1131. #if defined(CONFIG_CMD_NVEDIT_INFO)
  1132. U_BOOT_CMD_MKENT(info, 2, 0, do_env_info, "", ""),
  1133. #endif
  1134. U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""),
  1135. #if defined(CONFIG_CMD_RUN)
  1136. U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""),
  1137. #endif
  1138. #if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
  1139. U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""),
  1140. #if defined(CONFIG_CMD_ERASEENV)
  1141. U_BOOT_CMD_MKENT(erase, 1, 0, do_env_erase, "", ""),
  1142. #endif
  1143. #endif
  1144. U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""),
  1145. #if defined(CONFIG_CMD_ENV_EXISTS)
  1146. U_BOOT_CMD_MKENT(exists, 2, 0, do_env_exists, "", ""),
  1147. #endif
  1148. };
  1149. #if defined(CONFIG_NEEDS_MANUAL_RELOC)
  1150. void env_reloc(void)
  1151. {
  1152. fixup_cmdtable(cmd_env_sub, ARRAY_SIZE(cmd_env_sub));
  1153. }
  1154. #endif
  1155. static int do_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  1156. {
  1157. cmd_tbl_t *cp;
  1158. if (argc < 2)
  1159. return CMD_RET_USAGE;
  1160. /* drop initial "env" arg */
  1161. argc--;
  1162. argv++;
  1163. cp = find_cmd_tbl(argv[0], cmd_env_sub, ARRAY_SIZE(cmd_env_sub));
  1164. if (cp)
  1165. return cp->cmd(cmdtp, flag, argc, argv);
  1166. return CMD_RET_USAGE;
  1167. }
  1168. #ifdef CONFIG_SYS_LONGHELP
  1169. static char env_help_text[] =
  1170. #if defined(CONFIG_CMD_ASKENV)
  1171. "ask name [message] [size] - ask for environment variable\nenv "
  1172. #endif
  1173. #if defined(CONFIG_CMD_ENV_CALLBACK)
  1174. "callbacks - print callbacks and their associated variables\nenv "
  1175. #endif
  1176. "default [-f] -a - [forcibly] reset default environment\n"
  1177. "env default [-f] var [...] - [forcibly] reset variable(s) to their default values\n"
  1178. "env delete [-f] var [...] - [forcibly] delete variable(s)\n"
  1179. #if defined(CONFIG_CMD_EDITENV)
  1180. "env edit name - edit environment variable\n"
  1181. #endif
  1182. #if defined(CONFIG_CMD_ENV_EXISTS)
  1183. "env exists name - tests for existence of variable\n"
  1184. #endif
  1185. #if defined(CONFIG_CMD_EXPORTENV)
  1186. "env export [-t | -b | -c] [-s size] addr [var ...] - export environment\n"
  1187. #endif
  1188. #if defined(CONFIG_CMD_ENV_FLAGS)
  1189. "env flags - print variables that have non-default flags\n"
  1190. #endif
  1191. #if defined(CONFIG_CMD_GREPENV)
  1192. #ifdef CONFIG_REGEX
  1193. "env grep [-e] [-n | -v | -b] string [...] - search environment\n"
  1194. #else
  1195. "env grep [-n | -v | -b] string [...] - search environment\n"
  1196. #endif
  1197. #endif
  1198. #if defined(CONFIG_CMD_IMPORTENV)
  1199. "env import [-d] [-t [-r] | -b | -c] addr [size] [var ...] - import environment\n"
  1200. #endif
  1201. #if defined(CONFIG_CMD_NVEDIT_INFO)
  1202. "env info - display environment information\n"
  1203. "env info [-d] - whether default environment is used\n"
  1204. "env info [-p] - whether environment can be persisted\n"
  1205. #endif
  1206. "env print [-a | name ...] - print environment\n"
  1207. #if defined(CONFIG_CMD_NVEDIT_EFI)
  1208. "env print -e [-guid guid|-all][-n] [name ...] - print UEFI environment\n"
  1209. #endif
  1210. #if defined(CONFIG_CMD_RUN)
  1211. "env run var [...] - run commands in an environment variable\n"
  1212. #endif
  1213. #if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
  1214. "env save - save environment\n"
  1215. #if defined(CONFIG_CMD_ERASEENV)
  1216. "env erase - erase environment\n"
  1217. #endif
  1218. #endif
  1219. #if defined(CONFIG_CMD_NVEDIT_EFI)
  1220. "env set -e [-nv][-bs][-rt][-at][-a][-i addr,size][-v] name [arg ...]\n"
  1221. " - set UEFI variable; unset if '-i' or 'arg' not specified\n"
  1222. #endif
  1223. "env set [-f] name [arg ...]\n";
  1224. #endif
  1225. U_BOOT_CMD(
  1226. env, CONFIG_SYS_MAXARGS, 1, do_env,
  1227. "environment handling commands", env_help_text
  1228. );
  1229. /*
  1230. * Old command line interface, kept for compatibility
  1231. */
  1232. #if defined(CONFIG_CMD_EDITENV)
  1233. U_BOOT_CMD_COMPLETE(
  1234. editenv, 2, 0, do_env_edit,
  1235. "edit environment variable",
  1236. "name\n"
  1237. " - edit environment variable 'name'",
  1238. var_complete
  1239. );
  1240. #endif
  1241. U_BOOT_CMD_COMPLETE(
  1242. printenv, CONFIG_SYS_MAXARGS, 1, do_env_print,
  1243. "print environment variables",
  1244. "[-a]\n - print [all] values of all environment variables\n"
  1245. #if defined(CONFIG_CMD_NVEDIT_EFI)
  1246. "printenv -e [-guid guid|-all][-n] [name ...]\n"
  1247. " - print UEFI variable 'name' or all the variables\n"
  1248. " \"-n\": suppress dumping variable's value\n"
  1249. #endif
  1250. "printenv name ...\n"
  1251. " - print value of environment variable 'name'",
  1252. var_complete
  1253. );
  1254. #ifdef CONFIG_CMD_GREPENV
  1255. U_BOOT_CMD_COMPLETE(
  1256. grepenv, CONFIG_SYS_MAXARGS, 0, do_env_grep,
  1257. "search environment variables",
  1258. #ifdef CONFIG_REGEX
  1259. "[-e] [-n | -v | -b] string ...\n"
  1260. #else
  1261. "[-n | -v | -b] string ...\n"
  1262. #endif
  1263. " - list environment name=value pairs matching 'string'\n"
  1264. #ifdef CONFIG_REGEX
  1265. " \"-e\": enable regular expressions;\n"
  1266. #endif
  1267. " \"-n\": search variable names; \"-v\": search values;\n"
  1268. " \"-b\": search both names and values (default)",
  1269. var_complete
  1270. );
  1271. #endif
  1272. U_BOOT_CMD_COMPLETE(
  1273. setenv, CONFIG_SYS_MAXARGS, 0, do_env_set,
  1274. "set environment variables",
  1275. #if defined(CONFIG_CMD_NVEDIT_EFI)
  1276. "-e [-guid guid][-nv][-bs][-rt][-at][-a][-v]\n"
  1277. " [-i addr,size name], or [name [value ...]]\n"
  1278. " - set UEFI variable 'name' to 'value' ...'\n"
  1279. " \"-guid\": set vendor guid\n"
  1280. " \"-nv\": set non-volatile attribute\n"
  1281. " \"-bs\": set boot-service attribute\n"
  1282. " \"-rt\": set runtime attribute\n"
  1283. " \"-at\": set time-based authentication attribute\n"
  1284. " \"-a\": append-write\n"
  1285. " \"-i addr,size\": use <addr,size> as variable's value\n"
  1286. " \"-v\": verbose message\n"
  1287. " - delete UEFI variable 'name' if 'value' not specified\n"
  1288. #endif
  1289. "setenv [-f] name value ...\n"
  1290. " - [forcibly] set environment variable 'name' to 'value ...'\n"
  1291. "setenv [-f] name\n"
  1292. " - [forcibly] delete environment variable 'name'",
  1293. var_complete
  1294. );
  1295. #if defined(CONFIG_CMD_ASKENV)
  1296. U_BOOT_CMD(
  1297. askenv, CONFIG_SYS_MAXARGS, 1, do_env_ask,
  1298. "get environment variables from stdin",
  1299. "name [message] [size]\n"
  1300. " - get environment variable 'name' from stdin (max 'size' chars)"
  1301. );
  1302. #endif
  1303. #if defined(CONFIG_CMD_RUN)
  1304. U_BOOT_CMD_COMPLETE(
  1305. run, CONFIG_SYS_MAXARGS, 1, do_run,
  1306. "run commands in an environment variable",
  1307. "var [...]\n"
  1308. " - run the commands in the environment variable(s) 'var'",
  1309. var_complete
  1310. );
  1311. #endif
  1312. #endif /* CONFIG_SPL_BUILD */