1 /* 2 * (C) Copyright 2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #ifndef _ENVIRONMENT_H_ 9 #define _ENVIRONMENT_H_ 10 11 #include <stdbool.h> 12 #include <linux/kconfig.h> 13 14 /************************************************************************** 15 * 16 * The "environment" is stored as a list of '\0' terminated 17 * "name=value" strings. The end of the list is marked by a double 18 * '\0'. New entries are always added at the end. Deleting an entry 19 * shifts the remaining entries to the front. Replacing an entry is a 20 * combination of deleting the old value and adding the new one. 21 * 22 * The environment is preceded by a 32 bit CRC over the data part. 23 * 24 *************************************************************************/ 25 26 #if defined(CONFIG_ENV_IS_IN_FLASH) 27 # ifndef CONFIG_ENV_ADDR 28 # define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET) 29 # endif 30 # ifndef CONFIG_ENV_OFFSET 31 # define CONFIG_ENV_OFFSET (CONFIG_ENV_ADDR - CONFIG_SYS_FLASH_BASE) 32 # endif 33 # if !defined(CONFIG_ENV_ADDR_REDUND) && defined(CONFIG_ENV_OFFSET_REDUND) 34 # define CONFIG_ENV_ADDR_REDUND \ 35 (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET_REDUND) 36 # endif 37 # if defined(CONFIG_ENV_SECT_SIZE) || defined(CONFIG_ENV_SIZE) 38 # ifndef CONFIG_ENV_SECT_SIZE 39 # define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE 40 # endif 41 # ifndef CONFIG_ENV_SIZE 42 # define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE 43 # endif 44 # else 45 # error "Both CONFIG_ENV_SECT_SIZE and CONFIG_ENV_SIZE undefined" 46 # endif 47 # if defined(CONFIG_ENV_ADDR_REDUND) && !defined(CONFIG_ENV_SIZE_REDUND) 48 # define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE 49 # endif 50 # if (CONFIG_ENV_ADDR >= CONFIG_SYS_MONITOR_BASE) && \ 51 (CONFIG_ENV_ADDR + CONFIG_ENV_SIZE) <= \ 52 (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) 53 # define ENV_IS_EMBEDDED 54 # endif 55 # if defined(CONFIG_ENV_ADDR_REDUND) || defined(CONFIG_ENV_OFFSET_REDUND) 56 # define CONFIG_SYS_REDUNDAND_ENVIRONMENT 57 # endif 58 # ifdef CONFIG_ENV_IS_EMBEDDED 59 # error "do not define CONFIG_ENV_IS_EMBEDDED in your board config" 60 # error "it is calculated automatically for you" 61 # endif 62 #endif /* CONFIG_ENV_IS_IN_FLASH */ 63 64 #if defined(CONFIG_ENV_IS_IN_MMC) 65 # ifdef CONFIG_ENV_OFFSET_REDUND 66 # define CONFIG_SYS_REDUNDAND_ENVIRONMENT 67 # endif 68 #endif 69 70 #if defined(CONFIG_ENV_IS_IN_NAND) 71 # if defined(CONFIG_ENV_OFFSET_OOB) 72 # ifdef CONFIG_ENV_OFFSET_REDUND 73 # error "CONFIG_ENV_OFFSET_REDUND is not supported when CONFIG_ENV_OFFSET_OOB" 74 # error "is set" 75 # endif 76 extern unsigned long nand_env_oob_offset; 77 # define CONFIG_ENV_OFFSET nand_env_oob_offset 78 # else 79 # ifndef CONFIG_ENV_OFFSET 80 # error "Need to define CONFIG_ENV_OFFSET when using CONFIG_ENV_IS_IN_NAND" 81 # endif 82 # ifdef CONFIG_ENV_OFFSET_REDUND 83 # define CONFIG_SYS_REDUNDAND_ENVIRONMENT 84 # endif 85 # endif /* CONFIG_ENV_OFFSET_OOB */ 86 # ifndef CONFIG_ENV_SIZE 87 # error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_NAND" 88 # endif 89 #endif /* CONFIG_ENV_IS_IN_NAND */ 90 91 #if defined(CONFIG_ENV_IS_IN_UBI) 92 # ifndef CONFIG_ENV_UBI_PART 93 # error "Need to define CONFIG_ENV_UBI_PART when using CONFIG_ENV_IS_IN_UBI" 94 # endif 95 # ifndef CONFIG_ENV_UBI_VOLUME 96 # error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI" 97 # endif 98 # if defined(CONFIG_ENV_UBI_VOLUME_REDUND) 99 # define CONFIG_SYS_REDUNDAND_ENVIRONMENT 100 # endif 101 # ifndef CONFIG_ENV_SIZE 102 # error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_UBI" 103 # endif 104 # ifndef CONFIG_CMD_UBI 105 # error "Need to define CONFIG_CMD_UBI when using CONFIG_ENV_IS_IN_UBI" 106 # endif 107 #endif /* CONFIG_ENV_IS_IN_UBI */ 108 109 /* Embedded env is only supported for some flash types */ 110 #ifdef CONFIG_ENV_IS_EMBEDDED 111 # if !defined(CONFIG_ENV_IS_IN_FLASH) && \ 112 !defined(CONFIG_ENV_IS_IN_NAND) && \ 113 !defined(CONFIG_ENV_IS_IN_ONENAND) && \ 114 !defined(CONFIG_ENV_IS_IN_SPI_FLASH) 115 # error "CONFIG_ENV_IS_EMBEDDED not supported for your flash type" 116 # endif 117 #endif 118 119 /* 120 * For the flash types where embedded env is supported, but it cannot be 121 * calculated automatically (i.e. NAND), take the board opt-in. 122 */ 123 #if defined(CONFIG_ENV_IS_EMBEDDED) && !defined(ENV_IS_EMBEDDED) 124 # define ENV_IS_EMBEDDED 125 #endif 126 127 /* The build system likes to know if the env is embedded */ 128 #ifdef DO_DEPS_ONLY 129 # ifdef ENV_IS_EMBEDDED 130 # ifndef CONFIG_ENV_IS_EMBEDDED 131 # define CONFIG_ENV_IS_EMBEDDED 132 # endif 133 # endif 134 #endif 135 136 #include "compiler.h" 137 138 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 139 # define ENV_HEADER_SIZE (sizeof(uint32_t) + 1) 140 141 # define ACTIVE_FLAG 1 142 # define OBSOLETE_FLAG 0 143 #else 144 # define ENV_HEADER_SIZE (sizeof(uint32_t)) 145 #endif 146 147 /* Select the MAX from CONFIG_ENV_{,NAND,NOR}_SIZE */ 148 #if defined(CONFIG_ENV_NAND_SIZE) && (CONFIG_ENV_SIZE < CONFIG_ENV_NAND_SIZE) 149 #define ENV_SIZE_VAL CONFIG_ENV_NAND_SIZE 150 #else 151 #define ENV_SIZE_VAL CONFIG_ENV_SIZE 152 #endif 153 #if defined(CONFIG_ENV_NOR_SIZE) && (ENV_SIZE_VAL < CONFIG_ENV_NOR_SIZE) 154 #undef ENV_SIZE_VAL 155 #define ENV_SIZE_VAL CONFIG_ENV_NOR_SIZE 156 #endif 157 158 #ifdef CONFIG_ENV_AES 159 /* Make sure the payload is multiple of AES block size */ 160 #define ENV_SIZE ((ENV_SIZE_VAL - ENV_HEADER_SIZE) & ~(16 - 1)) 161 #else 162 #define ENV_SIZE (ENV_SIZE_VAL - ENV_HEADER_SIZE) 163 #endif 164 165 typedef struct environment_s { 166 uint32_t crc; /* CRC32 over data bytes */ 167 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 168 unsigned char flags; /* active/obsolete flags */ 169 #endif 170 unsigned char data[ENV_SIZE]; /* Environment data */ 171 } env_t 172 #ifdef CONFIG_ENV_AES 173 /* Make sure the env is aligned to block size. */ 174 __attribute__((aligned(16))) 175 #endif 176 ; 177 178 #ifdef ENV_IS_EMBEDDED 179 extern env_t environment; 180 #endif /* ENV_IS_EMBEDDED */ 181 182 extern const unsigned char default_environment[]; 183 extern env_t *env_ptr; 184 185 #if defined(CONFIG_NEEDS_MANUAL_RELOC) 186 extern void env_reloc(void); 187 #endif 188 189 #ifdef CONFIG_ENV_IS_IN_MMC 190 #include <mmc.h> 191 192 extern int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr); 193 # ifdef CONFIG_SYS_MMC_ENV_PART 194 extern uint mmc_get_env_part(struct mmc *mmc); 195 # endif 196 #endif 197 198 #ifndef DO_DEPS_ONLY 199 200 #include <env_attr.h> 201 #include <env_callback.h> 202 #include <env_flags.h> 203 #include <search.h> 204 205 /* Value for environment validity */ 206 enum env_valid { 207 ENV_INVALID, /* No valid environment */ 208 ENV_VALID, /* First or only environment is valid */ 209 ENV_REDUND, /* Redundant environment is valid */ 210 }; 211 212 enum env_location { 213 ENVL_EEPROM, 214 ENVL_EXT4, 215 ENVL_FAT, 216 ENVL_FLASH, 217 ENVL_MMC, 218 ENVL_NAND, 219 ENVL_NVRAM, 220 ENVL_ONENAND, 221 ENVL_REMOTE, 222 ENVL_SPI_FLASH, 223 ENVL_UBI, 224 ENVL_NOWHERE, 225 ENVL_BLK, 226 227 ENVL_COUNT, 228 ENVL_UNKNOWN, 229 }; 230 231 struct env_driver { 232 const char *name; 233 enum env_location location; 234 235 /** 236 * get_char() - Read a character from the environment 237 * 238 * This method is optional. If not provided, a default implementation 239 * will read from gd->env_addr. 240 * 241 * @index: Index of character to read (0=first) 242 * @return character read, or -ve on error 243 */ 244 int (*get_char)(int index); 245 246 /** 247 * load() - Load the environment from storage 248 * 249 * This method is optional. If not provided, no environment will be 250 * loaded. 251 * 252 * @return 0 if OK, -ve on error 253 */ 254 int (*load)(void); 255 256 /** 257 * save() - Save the environment to storage 258 * 259 * This method is required for 'saveenv' to work. 260 * 261 * @return 0 if OK, -ve on error 262 */ 263 int (*save)(void); 264 265 /** 266 * init() - Set up the initial pre-relocation environment 267 * 268 * This method is optional. 269 * 270 * @return 0 if OK, -ENOENT if no initial environment could be found, 271 * other -ve on error 272 */ 273 int (*init)(void); 274 }; 275 276 /* Declare a new environment location driver */ 277 #define U_BOOT_ENV_LOCATION(__name) \ 278 ll_entry_declare(struct env_driver, __name, env_driver) 279 280 /* Declare the name of a location */ 281 #ifdef CONFIG_CMD_SAVEENV 282 #define ENV_NAME(_name) .name = _name, 283 #else 284 #define ENV_NAME(_name) 285 #endif 286 287 #ifdef CONFIG_CMD_SAVEENV 288 #define env_save_ptr(x) x 289 #else 290 #define env_save_ptr(x) NULL 291 #endif 292 293 extern struct hsearch_data env_htab; 294 295 /* Function that updates CRC of the enironment */ 296 void env_crc_update(void); 297 298 /* Look up the variable from the default environment */ 299 char *env_get_default(const char *name); 300 301 /* [re]set to the default environment */ 302 void set_default_env(const char *s); 303 304 /* [re]set to the board environment */ 305 int set_board_env(const char *vars, int size, int flags, bool ready); 306 307 /* [re]set individual variables to their value in the default environment */ 308 int set_default_vars(int nvars, char * const vars[]); 309 310 /* Import from binary representation into hash table */ 311 int env_import(const char *buf, int check); 312 313 /* Export from hash table into binary representation */ 314 int env_export(env_t *env_out); 315 316 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 317 /* Select and import one of two redundant environments */ 318 int env_import_redund(const char *buf1, const char *buf2); 319 #endif 320 321 /** 322 * env_driver_lookup_default() - Look up the default environment driver 323 * 324 * @return pointer to driver, or NULL if none (which should not happen) 325 */ 326 struct env_driver *env_driver_lookup_default(void); 327 328 /** 329 * env_get_char() - Get a character from the early environment 330 * 331 * This reads from the pre-relocation environemnt 332 * 333 * @index: Index of character to read (0 = first) 334 * @return character read, or -ve on error 335 */ 336 int env_get_char(int index); 337 338 /** 339 * env_load() - Load the environment from storage 340 * 341 * @return 0 if OK, -ve on error 342 */ 343 int env_load(void); 344 345 /** 346 * env_save() - Save the environment to storage 347 * 348 * @return 0 if OK, -ve on error 349 */ 350 int env_save(void); 351 352 #endif /* DO_DEPS_ONLY */ 353 354 #endif /* _ENVIRONMENT_H_ */ 355