Merge branch '2020-07-27-misc-env-improvements'

- Assorted environment fixes.
- Enhance environment in MMC and controlled via OF_CONTROL
- Allow for environment in FAT to use the same device we boot from
  rather than be hard-coded.
This commit is contained in:
Tom Rini 2020-07-27 09:25:53 -04:00
commit 3773028fce
12 changed files with 169 additions and 27 deletions

View file

@ -601,6 +601,7 @@ config CMD_NVEDIT_INFO
This command can be optionally used for evaluation in scripts:
[-d] : evaluate whether default environment is used
[-p] : evaluate whether environment can be persisted
[-q] : quiet output
The result of multiple evaluations will be combined with AND.
endmenu

View file

@ -1224,12 +1224,18 @@ static int print_env_info(void)
* env info - display environment information
* env info [-d] - evaluate whether default environment is used
* env info [-p] - evaluate whether environment can be persisted
* Add [-q] - quiet mode, use only for command result, for test by example:
* test env info -p -d -q
*/
static int do_env_info(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
int eval_flags = 0;
int eval_results = 0;
bool quiet = false;
#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
enum env_location loc;
#endif
/* display environment information */
if (argc <= 1)
@ -1247,6 +1253,9 @@ static int do_env_info(struct cmd_tbl *cmdtp, int flag,
case 'p':
eval_flags |= ENV_INFO_IS_PERSISTED;
break;
case 'q':
quiet = true;
break;
default:
return CMD_RET_USAGE;
}
@ -1256,20 +1265,30 @@ static int do_env_info(struct cmd_tbl *cmdtp, int flag,
/* evaluate whether default environment is used */
if (eval_flags & ENV_INFO_IS_DEFAULT) {
if (gd->flags & GD_FLG_ENV_DEFAULT) {
printf("Default environment is used\n");
if (!quiet)
printf("Default environment is used\n");
eval_results |= ENV_INFO_IS_DEFAULT;
} else {
printf("Environment was loaded from persistent storage\n");
if (!quiet)
printf("Environment was loaded from persistent storage\n");
}
}
/* evaluate whether environment can be persisted */
if (eval_flags & ENV_INFO_IS_PERSISTED) {
#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
printf("Environment can be persisted\n");
eval_results |= ENV_INFO_IS_PERSISTED;
loc = env_get_location(ENVOP_SAVE, gd->env_load_prio);
if (ENVL_NOWHERE != loc && ENVL_UNKNOWN != loc) {
if (!quiet)
printf("Environment can be persisted\n");
eval_results |= ENV_INFO_IS_PERSISTED;
} else {
if (!quiet)
printf("Environment cannot be persisted\n");
}
#else
printf("Environment cannot be persisted\n");
if (!quiet)
printf("Environment cannot be persisted\n");
#endif
}
@ -1326,7 +1345,7 @@ static struct cmd_tbl cmd_env_sub[] = {
U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""),
#endif
#if defined(CONFIG_CMD_NVEDIT_INFO)
U_BOOT_CMD_MKENT(info, 2, 0, do_env_info, "", ""),
U_BOOT_CMD_MKENT(info, 3, 0, do_env_info, "", ""),
#endif
U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""),
#if defined(CONFIG_CMD_RUN)
@ -1405,8 +1424,10 @@ static char env_help_text[] =
#endif
#if defined(CONFIG_CMD_NVEDIT_INFO)
"env info - display environment information\n"
"env info [-d] - whether default environment is used\n"
"env info [-p] - whether environment can be persisted\n"
"env info [-d] [-p] [-q] - evaluate environment information\n"
" \"-d\": default environment is used\n"
" \"-p\": environment can be persisted\n"
" \"-q\": quiet output\n"
#endif
"env print [-a | name ...] - print environment\n"
#if defined(CONFIG_CMD_NVEDIT_EFI)

View file

@ -30,6 +30,7 @@ CONFIG_CMD_GREPENV=y
CONFIG_CMD_ENV_CALLBACK=y
CONFIG_CMD_ENV_FLAGS=y
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CMD_NVEDIT_INFO=y
CONFIG_LOOPW=y
CONFIG_CMD_MD5SUM=y
CONFIG_CMD_MEMINFO=y

View file

@ -34,6 +34,7 @@ CONFIG_CMD_GREPENV=y
CONFIG_CMD_ENV_CALLBACK=y
CONFIG_CMD_ENV_FLAGS=y
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CMD_NVEDIT_INFO=y
CONFIG_LOOPW=y
CONFIG_CMD_MD5SUM=y
CONFIG_CMD_MEMINFO=y

View file

@ -24,6 +24,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y
# CONFIG_CMD_ELF is not set
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
CONFIG_CMD_NVEDIT_INFO=y
CONFIG_LOOPW=y
CONFIG_CMD_MD5SUM=y
CONFIG_CMD_MEMINFO=y

View file

@ -34,6 +34,7 @@ CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
CONFIG_CMD_ENV_CALLBACK=y
CONFIG_CMD_ENV_FLAGS=y
CONFIG_CMD_NVEDIT_INFO=y
CONFIG_LOOPW=y
CONFIG_CMD_MD5SUM=y
CONFIG_CMD_MEMINFO=y

4
env/Kconfig vendored
View file

@ -434,6 +434,10 @@ config ENV_FAT_DEVICE_AND_PART
If none, first valid partition in device D. If no
partition table then means device D.
If ENV_FAT_INTERFACE is set to "mmc" then device 'D' can be omitted,
leaving the string starting with a colon, and the boot device will
be used.
config ENV_FAT_FILE
string "Name of the FAT file to use for the environment"
depends on ENV_IS_IN_FAT

18
env/env.c vendored
View file

@ -103,7 +103,7 @@ static void env_set_inited(enum env_location location)
* using the above enum value as the bit index. We need to
* make sure that we're not overflowing it.
*/
BUILD_BUG_ON(ARRAY_SIZE(env_locations) > BITS_PER_LONG);
BUILD_BUG_ON(ENVL_COUNT > BITS_PER_LONG);
gd->env_has_init |= BIT(location);
}
@ -240,13 +240,17 @@ int env_save(void)
if (drv) {
int ret;
if (!drv->save)
return -ENODEV;
if (!env_has_inited(drv->location))
return -ENODEV;
printf("Saving Environment to %s... ", drv->name);
if (!drv->save) {
printf("not possible\n");
return -ENODEV;
}
if (!env_has_inited(drv->location)) {
printf("not initialized\n");
return -ENODEV;
}
ret = drv->save();
if (ret)
printf("Failed (%d)\n", ret);

32
env/fat.c vendored
View file

@ -29,6 +29,34 @@
# define LOADENV
#endif
__weak int mmc_get_env_dev(void)
{
#ifdef CONFIG_SYS_MMC_ENV_DEV
return CONFIG_SYS_MMC_ENV_DEV;
#else
return 0;
#endif
}
static char *env_fat_device_and_part(void)
{
#ifdef CONFIG_MMC
static char *part_str;
if (!part_str) {
part_str = CONFIG_ENV_FAT_DEVICE_AND_PART;
if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc") && part_str[0] == ':') {
part_str = "0" CONFIG_ENV_FAT_DEVICE_AND_PART;
part_str[0] += mmc_get_env_dev();
}
}
return part_str;
#else
return CONFIG_ENV_FAT_DEVICE_AND_PART;
#endif
}
static int env_fat_save(void)
{
env_t __aligned(ARCH_DMA_MINALIGN) env_new;
@ -43,7 +71,7 @@ static int env_fat_save(void)
return err;
part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
CONFIG_ENV_FAT_DEVICE_AND_PART,
env_fat_device_and_part(),
&dev_desc, &info, 1);
if (part < 0)
return 1;
@ -89,7 +117,7 @@ static int env_fat_load(void)
#endif
part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
CONFIG_ENV_FAT_DEVICE_AND_PART,
env_fat_device_and_part(),
&dev_desc, &info, 1);
if (part < 0)
goto err_env_relocate;

26
env/mmc.c vendored
View file

@ -24,14 +24,25 @@
DECLARE_GLOBAL_DATA_PTR;
#if !defined(CONFIG_SYS_MMC_ENV_DEV)
#define CONFIG_SYS_MMC_ENV_DEV 0
#endif
__weak int mmc_get_env_dev(void)
{
return CONFIG_SYS_MMC_ENV_DEV;
}
#if CONFIG_IS_ENABLED(OF_CONTROL)
static inline int mmc_offset_try_partition(const char *str, s64 *val)
static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val)
{
struct disk_partition info;
struct blk_desc *desc;
int len, i, ret;
char dev_str[4];
ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc);
snprintf(dev_str, sizeof(dev_str), "%d", mmc_get_env_dev());
ret = blk_get_device_by_str("mmc", dev_str, &desc);
if (ret < 0)
return (ret);
@ -45,10 +56,10 @@ static inline int mmc_offset_try_partition(const char *str, s64 *val)
}
/* round up to info.blksz */
len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1);
len = DIV_ROUND_UP(CONFIG_ENV_SIZE, info.blksz);
/* use the top of the partion for the environment */
*val = (info.start + info.size - 1) - len / info.blksz;
*val = (info.start + info.size - (1 + copy) * len) * info.blksz;
return 0;
}
@ -73,7 +84,7 @@ static inline s64 mmc_offset(int copy)
str = fdtdec_get_config_string(gd->fdt_blob, dt_prop.partition);
if (str) {
/* try to place the environment at end of the partition */
err = mmc_offset_try_partition(str, &val);
err = mmc_offset_try_partition(str, copy, &val);
if (!err)
return val;
}
@ -114,11 +125,6 @@ __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
return 0;
}
__weak int mmc_get_env_dev(void)
{
return CONFIG_SYS_MMC_ENV_DEV;
}
#ifdef CONFIG_SYS_MMC_ENV_PART
__weak uint mmc_get_env_part(struct mmc *mmc)
{

View file

@ -211,6 +211,17 @@ struct env_driver {
extern struct hsearch_data env_htab;
/**
* env_get_location()- Provide the best location for the U-Boot environment
*
* It is a weak function allowing board to overidde the environment location
*
* @op: operations performed on the environment
* @prio: priority between the multiple environments, 0 being the
* highest priority
* @return an enum env_location value on success, or -ve error code.
*/
enum env_location env_get_location(enum env_operation op, int prio);
#endif /* DO_DEPS_ONLY */
#endif /* _ENV_INTERNAL_H_ */

View file

@ -336,3 +336,66 @@ def test_env_import_whitelist_delete(state_test_env):
unset_var(state_test_env, 'foo2')
unset_var(state_test_env, 'foo3')
unset_var(state_test_env, 'foo4')
@pytest.mark.buildconfigspec('cmd_nvedit_info')
def test_env_info(state_test_env):
"""Test 'env info' command with all possible options.
"""
c = state_test_env.u_boot_console
response = c.run_command('env info')
nb_line = 0
for l in response.split('\n'):
if 'env_valid = ' in l:
assert '= invalid' in l or '= valid' in l or '= redundant' in l
nb_line += 1
elif 'env_ready =' in l or 'env_use_default =' in l:
assert '= true' in l or '= false' in l
nb_line += 1
else:
assert true
assert nb_line == 3
response = c.run_command('env info -p -d')
assert 'Default environment is used' in response or "Environment was loaded from persistent storage" in response
assert 'Environment can be persisted' in response or "Environment cannot be persisted" in response
response = c.run_command('env info -p -d -q')
assert response == ""
response = c.run_command('env info -p -q')
assert response == ""
response = c.run_command('env info -d -q')
assert response == ""
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_nvedit_info')
@pytest.mark.buildconfigspec('cmd_echo')
def test_env_info_sandbox(state_test_env):
"""Test 'env info' command result with several options on sandbox
with a known ENV configuration: ready & default & persistent
"""
c = state_test_env.u_boot_console
response = c.run_command('env info')
assert 'env_ready = true' in response
assert 'env_use_default = true' in response
response = c.run_command('env info -p -d')
assert 'Default environment is used' in response
assert 'Environment cannot be persisted' in response
response = c.run_command('env info -d -q')
response = c.run_command('echo $?')
assert response == "0"
response = c.run_command('env info -p -q')
response = c.run_command('echo $?')
assert response == "1"
response = c.run_command('env info -d -p -q')
response = c.run_command('echo $?')
assert response == "1"