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