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