diff --git a/env/Makefile b/env/Makefile index 4c1bdcfdf495462224627541d530bb3dfafc85eb..8df5b9d4c9063b893270f0ce47f62de372a74d25 100644 --- a/env/Makefile +++ b/env/Makefile @@ -5,7 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += common.o +obj-y += common.o env.o ifndef CONFIG_SPL_BUILD obj-y += attr.o diff --git a/env/env.c b/env/env.c new file mode 100644 index 0000000000000000000000000000000000000000..9f0a04c33ccb23dffccb46aeda329d4496a81bda --- /dev/null +++ b/env/env.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2017 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static struct env_driver *env_driver_lookup(enum env_location loc) +{ + struct env_driver *drv; + const int n_ents = ll_entry_count(struct env_driver, env_driver); + struct env_driver *entry; + + drv = ll_entry_start(struct env_driver, env_driver); + for (entry = drv; entry != drv + n_ents; entry++) { + if (loc == entry->location) + return entry; + } + + /* Not found */ + return NULL; +} + +static enum env_location env_get_default_location(void) +{ + if IS_ENABLED(CONFIG_ENV_IS_IN_DATAFLASH) + return ENVL_DATAFLASH; + else if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM) + return ENVL_EEPROM; + else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) + return ENVL_FAT; + else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH) + return ENVL_FLASH; + else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC) + return ENVL_MMC; + else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND) + return ENVL_NAND; + else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM) + return ENVL_NVRAM; + else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE) + return ENVL_REMOTE; + else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) + return ENVL_SPI_FLASH; + else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI) + return ENVL_UBI; + else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE) + return ENVL_NOWHERE; + else + return ENVL_UNKNOWN; +} + +static struct env_driver *env_driver_lookup_default(void) +{ + enum env_location loc = env_get_default_location(); + struct env_driver *drv; + + drv = env_driver_lookup(loc); + if (!drv) { + debug("%s: No environment driver for location %d\n", __func__, + loc); + return NULL; + } + + return drv; +} + +int env_get_char_new(int index) +{ + struct env_driver *drv = env_driver_lookup_default(); + int ret; + + if (!drv) + return -ENODEV; + if (!drv->get_char) + return *(uchar *)(gd->env_addr + index); + ret = drv->get_char(index); + if (ret < 0) { + debug("%s: Environment failed to load (err=%d)\n", + __func__, ret); + } + + return ret; +} + +int env_load(void) +{ + struct env_driver *drv = env_driver_lookup_default(); + int ret = 0; + + if (!drv) + return -ENODEV; + if (!drv->load) + return 0; + drv->load(); /* TODO(sjg@chromium.org): Make this return an error */ + if (ret) { + debug("%s: Environment failed to load (err=%d)\n", __func__, + ret); + return ret; + } + + return 0; +} + +int env_save(void) +{ + struct env_driver *drv = env_driver_lookup_default(); + int ret; + + if (!drv) + return -ENODEV; + if (!drv->save) + return -ENOSYS; + ret = drv->save(); + if (ret) { + debug("%s: Environment failed to save (err=%d)\n", __func__, + ret); + return ret; + } + + return 0; +} + +int env_init_new(void) +{ + struct env_driver *drv = env_driver_lookup_default(); + int ret; + + if (!drv) + return -ENODEV; + if (!drv->init) + return -ENOSYS; + ret = drv->init(); + if (ret) { + debug("%s: Environment failed to init (err=%d)\n", __func__, + ret); + return ret; + } + + return 0; +}