2 * Copyright (C) 2017 Google, Inc
3 * Written by Simon Glass <sjg@chromium.org>
5 * SPDX-License-Identifier: GPL-2.0+
9 #include <environment.h>
11 DECLARE_GLOBAL_DATA_PTR;
13 static struct env_driver *_env_driver_lookup(enum env_location loc)
15 struct env_driver *drv;
16 const int n_ents = ll_entry_count(struct env_driver, env_driver);
17 struct env_driver *entry;
19 drv = ll_entry_start(struct env_driver, env_driver);
20 for (entry = drv; entry != drv + n_ents; entry++) {
21 if (loc == entry->location)
30 * env_get_location() - Returns the best env location for a board
31 * @op: operations performed on the environment
32 * @prio: priority between the multiple environments, 0 being the
35 * This will return the preferred environment for the given priority.
37 * All implementations are free to use the operation, the priority and
38 * any other data relevant to their choice, but must take into account
39 * the fact that the lowest prority (0) is the most important location
40 * in the system. The following locations should be returned by order
41 * of descending priorities, from the highest to the lowest priority.
44 * an enum env_location value on success, a negative error code otherwise
46 static enum env_location env_get_location(enum env_operation op, int prio)
49 * We support a single environment, so any environment asked
50 * with a priority that is not zero is out of our supported
56 if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM)
58 else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT)
60 else if IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)
62 else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH)
64 else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
66 else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND)
68 else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM)
70 else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE)
72 else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)
73 return ENVL_SPI_FLASH;
74 else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI)
76 else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE)
84 * env_driver_lookup() - Finds the most suited environment location
85 * @op: operations performed on the environment
86 * @prio: priority between the multiple environments, 0 being the
89 * This will try to find the available environment with the highest
90 * priority in the system.
93 * NULL on error, a pointer to a struct env_driver otherwise
95 static struct env_driver *env_driver_lookup(enum env_operation op, int prio)
97 enum env_location loc = env_get_location(op, prio);
98 struct env_driver *drv;
100 if (loc == ENVL_UNKNOWN)
103 drv = _env_driver_lookup(loc);
105 debug("%s: No environment driver for location %d\n", __func__,
113 int env_get_char(int index)
115 struct env_driver *drv;
118 if (gd->env_valid == ENV_INVALID)
119 return default_environment[index];
121 for (prio = 0; (drv = env_driver_lookup(ENVOP_GET_CHAR, prio)); prio++) {
127 ret = drv->get_char(index);
131 debug("%s: Environment %s failed to load (err=%d)\n", __func__,
140 struct env_driver *drv;
143 for (prio = 0; (drv = env_driver_lookup(ENVOP_LOAD, prio)); prio++) {
153 debug("%s: Environment %s failed to load (err=%d)\n", __func__,
162 struct env_driver *drv;
165 for (prio = 0; (drv = env_driver_lookup(ENVOP_SAVE, prio)); prio++) {
171 printf("Saving Environment to %s...\n", drv->name);
176 debug("%s: Environment %s failed to save (err=%d)\n", __func__,
185 struct env_driver *drv;
189 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
197 debug("%s: Environment %s failed to init (err=%d)\n", __func__,
204 if (ret == -ENOENT) {
205 gd->env_addr = (ulong)&default_environment[0];
206 gd->env_valid = ENV_VALID;