1c9d728ddSSimon Glass /* 2c9d728ddSSimon Glass * Copyright (C) 2017 Google, Inc 3c9d728ddSSimon Glass * Written by Simon Glass <sjg@chromium.org> 4c9d728ddSSimon Glass * 5c9d728ddSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6c9d728ddSSimon Glass */ 7c9d728ddSSimon Glass 8c9d728ddSSimon Glass #include <common.h> 9c9d728ddSSimon Glass #include <environment.h> 10c9d728ddSSimon Glass 11c9d728ddSSimon Glass DECLARE_GLOBAL_DATA_PTR; 12c9d728ddSSimon Glass 13c9d728ddSSimon Glass static struct env_driver *env_driver_lookup(enum env_location loc) 14c9d728ddSSimon Glass { 15c9d728ddSSimon Glass struct env_driver *drv; 16c9d728ddSSimon Glass const int n_ents = ll_entry_count(struct env_driver, env_driver); 17c9d728ddSSimon Glass struct env_driver *entry; 18c9d728ddSSimon Glass 19c9d728ddSSimon Glass drv = ll_entry_start(struct env_driver, env_driver); 20c9d728ddSSimon Glass for (entry = drv; entry != drv + n_ents; entry++) { 21c9d728ddSSimon Glass if (loc == entry->location) 22c9d728ddSSimon Glass return entry; 23c9d728ddSSimon Glass } 24c9d728ddSSimon Glass 25c9d728ddSSimon Glass /* Not found */ 26c9d728ddSSimon Glass return NULL; 27c9d728ddSSimon Glass } 28c9d728ddSSimon Glass 29c9d728ddSSimon Glass static enum env_location env_get_default_location(void) 30c9d728ddSSimon Glass { 317b7341d7STuomas Tynkkynen if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM) 32c9d728ddSSimon Glass return ENVL_EEPROM; 33c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) 34c9d728ddSSimon Glass return ENVL_FAT; 351087a794SJorge Ramirez-Ortiz else if IS_ENABLED(CONFIG_ENV_IS_IN_EXT4) 361087a794SJorge Ramirez-Ortiz return ENVL_EXT4; 37c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH) 38c9d728ddSSimon Glass return ENVL_FLASH; 39c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC) 40c9d728ddSSimon Glass return ENVL_MMC; 41c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND) 42c9d728ddSSimon Glass return ENVL_NAND; 43c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM) 44c9d728ddSSimon Glass return ENVL_NVRAM; 45c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE) 46c9d728ddSSimon Glass return ENVL_REMOTE; 47c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) 48c9d728ddSSimon Glass return ENVL_SPI_FLASH; 49c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI) 50c9d728ddSSimon Glass return ENVL_UBI; 51c9d728ddSSimon Glass else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE) 52c9d728ddSSimon Glass return ENVL_NOWHERE; 53c9d728ddSSimon Glass else 54c9d728ddSSimon Glass return ENVL_UNKNOWN; 55c9d728ddSSimon Glass } 56c9d728ddSSimon Glass 57*9c24dfb2SMaxime Ripard static struct env_driver *env_driver_lookup_default(void) 58c9d728ddSSimon Glass { 59c9d728ddSSimon Glass enum env_location loc = env_get_default_location(); 60c9d728ddSSimon Glass struct env_driver *drv; 61c9d728ddSSimon Glass 62c9d728ddSSimon Glass drv = env_driver_lookup(loc); 63c9d728ddSSimon Glass if (!drv) { 64c9d728ddSSimon Glass debug("%s: No environment driver for location %d\n", __func__, 65c9d728ddSSimon Glass loc); 66c9d728ddSSimon Glass return NULL; 67c9d728ddSSimon Glass } 68c9d728ddSSimon Glass 69c9d728ddSSimon Glass return drv; 70c9d728ddSSimon Glass } 71c9d728ddSSimon Glass 72a69d0f60SSimon Glass int env_get_char(int index) 73c9d728ddSSimon Glass { 74c9d728ddSSimon Glass struct env_driver *drv = env_driver_lookup_default(); 75c9d728ddSSimon Glass int ret; 76c9d728ddSSimon Glass 772d7cb5b4SSimon Glass if (gd->env_valid == ENV_INVALID) 78a69d0f60SSimon Glass return default_environment[index]; 79c9d728ddSSimon Glass if (!drv) 80c9d728ddSSimon Glass return -ENODEV; 81c9d728ddSSimon Glass if (!drv->get_char) 82c9d728ddSSimon Glass return *(uchar *)(gd->env_addr + index); 83c9d728ddSSimon Glass ret = drv->get_char(index); 84c9d728ddSSimon Glass if (ret < 0) { 85c9d728ddSSimon Glass debug("%s: Environment failed to load (err=%d)\n", 86c9d728ddSSimon Glass __func__, ret); 87c9d728ddSSimon Glass } 88c9d728ddSSimon Glass 89c9d728ddSSimon Glass return ret; 90c9d728ddSSimon Glass } 91c9d728ddSSimon Glass 92c9d728ddSSimon Glass int env_load(void) 93c9d728ddSSimon Glass { 94c9d728ddSSimon Glass struct env_driver *drv = env_driver_lookup_default(); 95c9d728ddSSimon Glass int ret = 0; 96c9d728ddSSimon Glass 97c9d728ddSSimon Glass if (!drv) 98c9d728ddSSimon Glass return -ENODEV; 99c9d728ddSSimon Glass if (!drv->load) 100c9d728ddSSimon Glass return 0; 101c55d8b94SSimon Glass ret = drv->load(); 102c9d728ddSSimon Glass if (ret) { 103c9d728ddSSimon Glass debug("%s: Environment failed to load (err=%d)\n", __func__, 104c9d728ddSSimon Glass ret); 105c9d728ddSSimon Glass return ret; 106c9d728ddSSimon Glass } 107c9d728ddSSimon Glass 108c9d728ddSSimon Glass return 0; 109c9d728ddSSimon Glass } 110c9d728ddSSimon Glass 111c9d728ddSSimon Glass int env_save(void) 112c9d728ddSSimon Glass { 113c9d728ddSSimon Glass struct env_driver *drv = env_driver_lookup_default(); 114c9d728ddSSimon Glass int ret; 115c9d728ddSSimon Glass 116c9d728ddSSimon Glass if (!drv) 117c9d728ddSSimon Glass return -ENODEV; 118c9d728ddSSimon Glass if (!drv->save) 119c9d728ddSSimon Glass return -ENOSYS; 120*9c24dfb2SMaxime Ripard 121*9c24dfb2SMaxime Ripard printf("Saving Environment to %s...\n", drv->name); 122c9d728ddSSimon Glass ret = drv->save(); 123c9d728ddSSimon Glass if (ret) { 124c9d728ddSSimon Glass debug("%s: Environment failed to save (err=%d)\n", __func__, 125c9d728ddSSimon Glass ret); 126c9d728ddSSimon Glass return ret; 127c9d728ddSSimon Glass } 128c9d728ddSSimon Glass 129c9d728ddSSimon Glass return 0; 130c9d728ddSSimon Glass } 131c9d728ddSSimon Glass 1326eeae424SSimon Glass int env_init(void) 133c9d728ddSSimon Glass { 134c9d728ddSSimon Glass struct env_driver *drv = env_driver_lookup_default(); 1357938822aSSimon Glass int ret = -ENOENT; 136c9d728ddSSimon Glass 137c9d728ddSSimon Glass if (!drv) 138c9d728ddSSimon Glass return -ENODEV; 1397938822aSSimon Glass if (drv->init) 140c9d728ddSSimon Glass ret = drv->init(); 1417938822aSSimon Glass if (ret == -ENOENT) { 1427938822aSSimon Glass gd->env_addr = (ulong)&default_environment[0]; 143eeba55cbSTom Rini gd->env_valid = ENV_VALID; 1447938822aSSimon Glass 1457938822aSSimon Glass return 0; 1467938822aSSimon Glass } else if (ret) { 147c9d728ddSSimon Glass debug("%s: Environment failed to init (err=%d)\n", __func__, 148c9d728ddSSimon Glass ret); 149c9d728ddSSimon Glass return ret; 150c9d728ddSSimon Glass } 151c9d728ddSSimon Glass 152c9d728ddSSimon Glass return 0; 153c9d728ddSSimon Glass } 154