
If U-Boot environment variable is set to ENV_FLAGS_VARSTORAGE_NON_VOLATILE, it will be saved at env_save[_ext](). If U-Boot environment variable is set to ENV_FLAGS_VARSTORAGE_NON_VOLATILE_AUTOSAVE, it will be saved at env_set_ext() as well as env_save[_ext](). Otherwise, it is handled as a temporary variable.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org --- env/flags.c | 130 +++++++++++++++++++++++++++++++++++++++++++- include/env_flags.h | 36 +++++++++++- 2 files changed, 164 insertions(+), 2 deletions(-)
diff --git a/env/flags.c b/env/flags.c index 79dccc05fe27..c1db891a2343 100644 --- a/env/flags.c +++ b/env/flags.c @@ -29,6 +29,7 @@
static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS; static const char env_flags_varaccess_rep[] = "aroc"; +static const char env_flags_varstorage_rep[] = "vna"; static const int env_flags_varaccess_mask[] = { 0, ENV_FLAGS_VARACCESS_PREVENT_DELETE | @@ -57,6 +58,12 @@ static const char * const env_flags_varaccess_names[] = { "change-default", };
+static const char * const env_flags_varstorage_names[] = { + "volatile", + "non-volatile", + "non-volatile-autosave", +}; + /* * Print the whole list of available type flags. */ @@ -85,6 +92,20 @@ void env_flags_print_varaccess(void) } }
+/* + * Print the whole list of available storage flags. + */ +void env_flags_print_varstorage(void) +{ + enum env_flags_varstorage curstorage = (enum env_flags_varstorage)0; + + while (curstorage != env_flags_varstorage_end) { + printf("\t%c -\t%s\n", env_flags_varstorage_rep[curstorage], + env_flags_varstorage_names[curstorage]); + curstorage++; + } +} + /* * Return the name of the type. */ @@ -100,6 +121,14 @@ const char *env_flags_get_varaccess_name(enum env_flags_varaccess access) { return env_flags_varaccess_names[access]; } + +/* + * Return the name of the storage. + */ +const char *env_flags_get_varstorage_name(enum env_flags_varstorage storage) +{ + return env_flags_varstorage_names[storage]; +} #endif /* CONFIG_CMD_ENV_FLAGS */
/* @@ -146,6 +175,30 @@ enum env_flags_varaccess env_flags_parse_varaccess(const char *flags) return env_flags_varaccess_any; }
+/* + * Parse the flags string from a .flags attribute list into the varstorage enum. + */ +enum env_flags_varstorage env_flags_parse_varstorage(const char *flags) +{ + char *storage; + + if (strlen(flags) <= ENV_FLAGS_VARSTORAGE_LOC) + /* for compatibility */ + return env_flags_varstorage_non_volatile; + + storage = strchr(env_flags_varstorage_rep, + flags[ENV_FLAGS_VARSTORAGE_LOC]); + + if (storage) + return (enum env_flags_varstorage) + (storage - &env_flags_varstorage_rep[0]); + + printf("## Warning: Unknown environment variable storage '%c'\n", + flags[ENV_FLAGS_VARSTORAGE_LOC]); + + return env_flags_varstorage_non_volatile; +} + /* * Parse the binary flags from a hash table entry into the varaccess enum. */ @@ -164,6 +217,27 @@ enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags) return env_flags_varaccess_any; }
+/* + * Parse the binary flags from a hash table entry into the varstorage enum. + */ +enum env_flags_varstorage env_flags_parse_varstorage_from_binflags(int binflags) +{ + int bits; + + bits = binflags & ENV_FLAGS_VARSTORAGE_BIN_MASK; + if (bits == ENV_FLAGS_VARSTORAGE_VOLATILE) + return env_flags_varstorage_volatile; + else if (bits == ENV_FLAGS_VARSTORAGE_NON_VOLATILE) + return env_flags_varstorage_non_volatile; + else if (bits == ENV_FLAGS_VARSTORAGE_NON_VOLATILE_AUTOSAVE) + return env_flags_varstorage_non_volatile_autosave; + + printf("Warning: Non-standard storage flags. (0x%x)\n", + binflags & ENV_FLAGS_VARSTORAGE_BIN_MASK); + + return env_flags_varstorage_non_volatile; +} + static inline int is_hex_prefix(const char *value) { return value[0] == '0' && (value[1] == 'x' || value[1] == 'X'); @@ -336,6 +410,23 @@ enum env_flags_varaccess env_flags_get_varaccess(const char *name) return env_flags_parse_varaccess(flags); }
+/* + * Look up the storage of a variable directly from the .flags var. + */ +enum env_flags_varstorage env_flags_get_storage(const char *name) +{ + const char *flags_list = env_get(ENV_FLAGS_VAR); + char flags[ENV_FLAGS_ATTR_MAX_LEN + 1]; + + if (env_flags_lookup(flags_list, name, flags)) + return env_flags_varstorage_non_volatile; + + if (strlen(flags) <= ENV_FLAGS_VARSTORAGE_LOC) + return env_flags_varstorage_non_volatile; + + return env_flags_parse_varstorage(flags); +} + /* * Validate that the proposed new value for "name" is valid according to the * defined flags for that variable, if any. @@ -402,10 +493,25 @@ int env_flags_validate_env_set_params(char *name, char * const val[], int count) */ static int env_parse_flags_to_bin(const char *flags) { - int binflags; + int binflags = 0;
binflags = env_flags_parse_vartype(flags) & ENV_FLAGS_VARTYPE_BIN_MASK; binflags |= env_flags_varaccess_mask[env_flags_parse_varaccess(flags)]; + switch (env_flags_parse_varstorage(flags)) { + case env_flags_varstorage_volatile: + /* actually no effect */ + binflags |= ENV_FLAGS_VARSTORAGE_VOLATILE; + break; + case env_flags_varstorage_non_volatile: + binflags |= ENV_FLAGS_VARSTORAGE_NON_VOLATILE; + break; + case env_flags_varstorage_non_volatile_autosave: + binflags |= ENV_FLAGS_VARSTORAGE_NON_VOLATILE_AUTOSAVE; + break; + case env_flags_varstorage_end: + /* makes no sense */ + break; + }
return binflags; } @@ -413,6 +519,19 @@ static int env_parse_flags_to_bin(const char *flags) static int first_call = 1; static const char *flags_list;
+static int env_flags_default(enum env_context ctx) +{ + if (ctx == ENVCTX_UBOOT) + return ENV_FLAGS_VARSTORAGE_NON_VOLATILE; +#ifdef CONFIG_EFI_VARIABLE_USE_ENV + else if (ctx == ENVCTX_UEFI) + /* explicitly set by caller */ + return 0; +#endif + + return 0; +} + /* * Look for possible flags for a newly added variable * This is called specifically when the variable did not exist in the hash @@ -434,6 +553,9 @@ void env_flags_init(ENTRY *var_entry) /* if any flags were found, set the binary form to the entry */ if (!ret && strlen(flags)) var_entry->flags = env_parse_flags_to_bin(flags); + /* TODO: check early? */ + else if (!var_entry->flags) + var_entry->flags = env_flags_default(var_entry->context); }
/* @@ -522,6 +644,12 @@ int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op, } }
+ /* + * TODO: context specific check necessary? + * For example, STORAGE_NON_VOLATILE and STORAGE_NON_VOLATILE_AUTOSAVE + * must not be mixed in one context. + */ + /* check for access permission */ #ifndef CONFIG_ENV_ACCESS_IGNORE_FORCE if (flag & H_FORCE) diff --git a/include/env_flags.h b/include/env_flags.h index 23744e395c8a..f46528691889 100644 --- a/include/env_flags.h +++ b/include/env_flags.h @@ -27,10 +27,18 @@ enum env_flags_varaccess { env_flags_varaccess_end };
+enum env_flags_varstorage { + env_flags_varstorage_volatile, /* 'v' */ + env_flags_varstorage_non_volatile, /* 'n' */ + env_flags_varstorage_non_volatile_autosave, /* 'a' */ + env_flags_varstorage_end +}; + #define ENV_FLAGS_VAR ".flags" -#define ENV_FLAGS_ATTR_MAX_LEN 2 +#define ENV_FLAGS_ATTR_MAX_LEN 3 #define ENV_FLAGS_VARTYPE_LOC 0 #define ENV_FLAGS_VARACCESS_LOC 1 +#define ENV_FLAGS_VARSTORAGE_LOC 2
#ifndef CONFIG_ENV_FLAGS_LIST_STATIC #define CONFIG_ENV_FLAGS_LIST_STATIC "" @@ -85,6 +93,10 @@ void env_flags_print_vartypes(void); * Print the whole list of available access flags. */ void env_flags_print_varaccess(void); +/* + * Print the whole list of available storage flags. + */ +void env_flags_print_varstorage(void); /* * Return the name of the type. */ @@ -93,6 +105,10 @@ const char *env_flags_get_vartype_name(enum env_flags_vartype type); * Return the name of the access. */ const char *env_flags_get_varaccess_name(enum env_flags_varaccess access); +/* + * Return the name of the storage. + */ +const char *env_flags_get_varstorage_name(enum env_flags_varstorage storage); #endif
/* @@ -103,10 +119,19 @@ enum env_flags_vartype env_flags_parse_vartype(const char *flags); * Parse the flags string from a .flags attribute list into the varaccess enum. */ enum env_flags_varaccess env_flags_parse_varaccess(const char *flags); +/* + * Parse the flags string from a .flags attribute list into the varstorage enum. + */ +enum env_flags_varstorage env_flags_parse_varstorage(const char *flags); /* * Parse the binary flags from a hash table entry into the varaccess enum. */ enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags); +/* + * Parse the binary flags from a hash table entry into the varstorage enum. + */ +enum env_flags_varstorage +env_flags_parse_varstorage_from_binflags(int binflags);
#ifdef CONFIG_CMD_NET /* @@ -124,6 +149,10 @@ enum env_flags_vartype env_flags_get_type(const char *name); * Look up the access of a variable directly from the .flags var. */ enum env_flags_varaccess env_flags_get_access(const char *name); +/* + * Look up the storage of a variable directly from the .flags var. + */ +enum env_flags_varstorage env_flags_get_storage(const char *name); /* * Validate the newval for its type to conform with the requirements defined by * its flags (directly looked at the .flags var). @@ -173,5 +202,10 @@ int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op, #define ENV_FLAGS_VARACCESS_PREVENT_OVERWR 0x00000020 #define ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR 0x00000040 #define ENV_FLAGS_VARACCESS_BIN_MASK 0x00000078 +#define ENV_FLAGS_VARSTORAGE_VOLATILE 0x00000000 +#define ENV_FLAGS_VARSTORAGE_NON_VOLATILE 0x00000080 +#define ENV_FLAGS_VARSTORAGE_NON_VOLATILE_AUTOSAVE 0x00000100 +#define ENV_FLAGS_VARSTORAGE_RESERVED 0x00000180 +#define ENV_FLAGS_VARSTORAGE_BIN_MASK 0x00000180
#endif /* __ENV_FLAGS_H__ */