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