/* * 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_EEPROM) return ENVL_EEPROM; else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) return ENVL_FAT; else if IS_ENABLED(CONFIG_ENV_IS_IN_EXT4) return ENVL_EXT4; 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(int index) { struct env_driver *drv = env_driver_lookup_default(); int ret; if (gd->env_valid == ENV_INVALID) return default_environment[index]; 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; ret = drv->load(); 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; printf("Saving Environment to %s...\n", drv->name); ret = drv->save(); if (ret) { debug("%s: Environment failed to save (err=%d)\n", __func__, ret); return ret; } return 0; } int env_init(void) { struct env_driver *drv = env_driver_lookup_default(); int ret = -ENOENT; if (!drv) return -ENODEV; if (drv->init) ret = drv->init(); if (ret == -ENOENT) { gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = ENV_VALID; return 0; } else if (ret) { debug("%s: Environment failed to init (err=%d)\n", __func__, ret); return ret; } return 0; }