From 4415f1d1f1c57d43f6bc8ff156554c2b2da45b52 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 3 Aug 2017 12:21:58 -0600 Subject: [PATCH] env: Create a location driver for each location Set up a location driver for each supported environment location. At present this just points to the global functions and is not used. A later patch will switch this over to use private functions in each driver. There are several special cases here in various drivers to handle peculiarities of certain boards: 1. Some boards define CONFIG_ENV_IS_IN_FAT and CONFIG_SPL_ENV_SUPPORT but do not actually load the environment in SPL. The env load code was optimised out before but with the driver, it is not. Therefore a special case is added to env/fat.c. The correct fix (depending on board testing might be to disable CONFIG_SPL_ENV_SUPPORT. 2. A similar situations happens with CONFIG_ENV_IS_IN_FLASH. Some boards do not actually load the environment in SPL, so to reduce code size we need to drop that code. A similar fix may be possible with these boards, or it may be possible to adjust the environment CONFIG settings. Added to the above is that the CONFIG_SPL_ENV_SUPPORT option does not apply when the environment is in flash. Obviously the above has been discovered through painful and time-consuming trial and error. Hopefully board maintainers can take a look and figure out what is actually needed. Signed-off-by: Simon Glass --- env/dataflash.c | 8 +++++ env/eeprom.c | 8 +++++ env/ext4.c | 8 +++++ env/fat.c | 30 +++++++++++++++++-- env/flash.c | 39 +++++++++++++++++++++--- env/mmc.c | 10 +++++++ env/nand.c | 12 +++++++- env/nowhere.c | 6 ++++ env/nvram.c | 10 +++++++ env/onenand.c | 8 +++++ env/remote.c | 8 +++++ env/sata.c | 8 +++++ env/sf.c | 20 +++++++++++++ env/ubi.c | 8 +++++ include/environment.h | 70 +++++++++++++++++++++++++++++++++++++++++++ 15 files changed, 246 insertions(+), 7 deletions(-) diff --git a/env/dataflash.c b/env/dataflash.c index c140b74c98..9c59d8e63a 100644 --- a/env/dataflash.c +++ b/env/dataflash.c @@ -82,3 +82,11 @@ int env_init(void) return 0; } + +U_BOOT_ENV_LOCATION(dataflash) = { + .location = ENVL_DATAFLASH, + .get_char = env_get_char_spec, + .load = env_relocate_spec, + .save = env_save_ptr(saveenv), + .init = env_init, +}; diff --git a/env/eeprom.c b/env/eeprom.c index ac6b30fa8f..78569b286b 100644 --- a/env/eeprom.c +++ b/env/eeprom.c @@ -243,3 +243,11 @@ int env_init(void) gd->env_valid = ENV_VALID; return 0; } + +U_BOOT_ENV_LOCATION(eeprom) = { + .location = ENVL_EEPROM, + .get_char = env_get_char_spec, + .load = env_relocate_spec, + .save = env_save_ptr(saveenv), + .init = env_init, +}; diff --git a/env/ext4.c b/env/ext4.c index 7bb4ce7cff..c6a84925d9 100644 --- a/env/ext4.c +++ b/env/ext4.c @@ -127,3 +127,11 @@ void env_relocate_spec(void) err_env_relocate: set_default_env(NULL); } + +U_BOOT_ENV_LOCATION(ext4) = { + .location = ENVL_EXT4, + .get_char = env_get_char_spec, + .load = env_relocate_spec, + .save = env_save_ptr(saveenv), + .init = env_init, +}; diff --git a/env/fat.c b/env/fat.c index 129b945a2f..abf6d115b7 100644 --- a/env/fat.c +++ b/env/fat.c @@ -19,6 +19,18 @@ #include #include +#ifdef CONFIG_SPL_BUILD +/* TODO(sjg@chromium.org): Figure out why this is needed */ +# if !defined(CONFIG_TARGET_AM335X_EVM) || defined(CONFIG_SPL_OS_BOOT) +# define LOADENV +# endif +#else +# define LOADENV +# if defined(CONFIG_CMD_SAVEENV) +# define CMD_SAVEENV +# endif +#endif + char *env_name_spec = "FAT"; env_t *env_ptr; @@ -34,7 +46,7 @@ int env_init(void) return 0; } -#ifdef CONFIG_CMD_SAVEENV +#ifdef CMD_SAVEENV int saveenv(void) { env_t env_new; @@ -72,8 +84,9 @@ int saveenv(void) puts("done\n"); return 0; } -#endif /* CONFIG_CMD_SAVEENV */ +#endif /* CMD_SAVEENV */ +#ifdef LOADENV void env_relocate_spec(void) { ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); @@ -108,3 +121,16 @@ void env_relocate_spec(void) err_env_relocate: set_default_env(NULL); } +#endif /* LOADENV */ + +U_BOOT_ENV_LOCATION(fat) = { + .location = ENVL_FAT, + .get_char = env_get_char_spec, +#ifdef LOADENV + .load = env_relocate_spec, +#endif +#ifdef CMD_SAVEENV + .save = env_save_ptr(saveenv), +#endif + .init = env_init, +}; diff --git a/env/flash.c b/env/flash.c index dcf3cd2c62..cf068d11ee 100644 --- a/env/flash.c +++ b/env/flash.c @@ -20,10 +20,12 @@ DECLARE_GLOBAL_DATA_PTR; -#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_FLASH) -#define CMD_SAVEENV -#elif defined(CONFIG_ENV_ADDR_REDUND) -#error CONFIG_ENV_ADDR_REDUND must have CONFIG_CMD_SAVEENV & CONFIG_CMD_FLASH +#ifndef CONFIG_SPL_BUILD +# if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_FLASH) +# define CMD_SAVEENV +# elif defined(CONFIG_ENV_ADDR_REDUND) +# error CONFIG_ENV_ADDR_REDUND must have CONFIG_CMD_SAVEENV & CONFIG_CMD_FLASH +# endif #endif #if defined(CONFIG_ENV_SIZE_REDUND) && \ @@ -31,6 +33,18 @@ DECLARE_GLOBAL_DATA_PTR; #error CONFIG_ENV_SIZE_REDUND should not be less then CONFIG_ENV_SIZE #endif +/* TODO(sjg@chromium.org): Figure out all these special cases */ +#if (!defined(CONFIG_MICROBLAZE) && !defined(CONFIG_ARCH_ZYNQ) && \ + !defined(CONFIG_TARGET_MCCMON6) && !defined(CONFIG_TARGET_X600) && \ + !defined(CONFIG_TARGET_EDMINIV2)) || \ + !defined(CONFIG_SPL_BUILD) +#define LOADENV +#endif + +#if !defined(CONFIG_TARGET_X600) || !defined(CONFIG_SPL_BUILD) +#define INITENV +#endif + char *env_name_spec = "Flash"; #ifdef ENV_IS_EMBEDDED @@ -58,6 +72,7 @@ static ulong end_addr_new = CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1; #ifdef CONFIG_ENV_ADDR_REDUND +#ifdef INITENV int env_init(void) { int crc1_ok = 0, crc2_ok = 0; @@ -101,6 +116,7 @@ int env_init(void) return 0; } +#endif #ifdef CMD_SAVEENV int saveenv(void) @@ -207,6 +223,7 @@ done: #else /* ! CONFIG_ENV_ADDR_REDUND */ +#ifdef INITENV int env_init(void) { if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) { @@ -219,6 +236,7 @@ int env_init(void) gd->env_valid = 0; return 0; } +#endif #ifdef CMD_SAVEENV int saveenv(void) @@ -336,3 +354,16 @@ void env_relocate_spec(void) env_import((char *)flash_addr, 1); } + +U_BOOT_ENV_LOCATION(flash) = { + .location = ENVL_FLASH, +#ifdef LOADENV + .load = env_relocate_spec, +#endif +#ifdef CMD_SAVEENV + .save = env_save_ptr(saveenv), +#endif +#ifdef INITENV + .init = env_init, +#endif +}; diff --git a/env/mmc.c b/env/mmc.c index e387202e71..0d1e8077d3 100644 --- a/env/mmc.c +++ b/env/mmc.c @@ -324,3 +324,13 @@ err: #endif } #endif /* CONFIG_ENV_OFFSET_REDUND */ + +U_BOOT_ENV_LOCATION(mmc) = { + .location = ENVL_MMC, + .get_char = env_get_char_spec, + .load = env_relocate_spec, +#ifndef CONFIG_SPL_BUILD + .save = env_save_ptr(saveenv), +#endif + .init = env_init, +}; diff --git a/env/nand.c b/env/nand.c index d1b8b26999..07edabab79 100644 --- a/env/nand.c +++ b/env/nand.c @@ -24,7 +24,8 @@ #include #include -#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND) +#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND) && \ + !defined(CONFIG_SPL_BUILD) #define CMD_SAVEENV #elif defined(CONFIG_ENV_OFFSET_REDUND) #error CONFIG_ENV_OFFSET_REDUND must have CONFIG_CMD_SAVEENV & CONFIG_CMD_NAND @@ -394,3 +395,12 @@ void env_relocate_spec(void) #endif /* ! ENV_IS_EMBEDDED */ } #endif /* CONFIG_ENV_OFFSET_REDUND */ + +U_BOOT_ENV_LOCATION(nand) = { + .location = ENVL_NAND, + .load = env_relocate_spec, +#if defined(CMD_SAVEENV) + .save = env_save_ptr(saveenv), +#endif + .init = env_init, +}; diff --git a/env/nowhere.c b/env/nowhere.c index bdc1ed5e67..c58d299308 100644 --- a/env/nowhere.c +++ b/env/nowhere.c @@ -33,3 +33,9 @@ int env_init(void) return 0; } + +U_BOOT_ENV_LOCATION(nowhere) = { + .location = ENVL_NOWHERE, + .load = env_relocate_spec, + .init = env_init, +}; diff --git a/env/nvram.c b/env/nvram.c index d046c9393c..4f45eae73e 100644 --- a/env/nvram.c +++ b/env/nvram.c @@ -112,3 +112,13 @@ int env_init(void) return 0; } + +U_BOOT_ENV_LOCATION(nvram) = { + .location = ENVL_NVRAM, +#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE + .get_char = env_get_char_spec, +#endif + .load = env_relocate_spec, + .save = env_save_ptr(saveenv), + .init = env_init, +}; diff --git a/env/onenand.c b/env/onenand.c index d7ad45a0e5..d4dfc02a46 100644 --- a/env/onenand.c +++ b/env/onenand.c @@ -114,3 +114,11 @@ int env_init(void) return 0; } + +U_BOOT_ENV_LOCATION(onenand) = { + .location = ENVL_ONENAND, + .get_char = env_get_char_spec, + .load = env_relocate_spec, + .save = env_save_ptr(saveenv), + .init = env_init, +}; diff --git a/env/remote.c b/env/remote.c index e003e02fb9..c221d55c4f 100644 --- a/env/remote.c +++ b/env/remote.c @@ -56,3 +56,11 @@ void env_relocate_spec(void) env_import((char *)env_ptr, 1); #endif } + +U_BOOT_ENV_LOCATION(remote) = { + .location = ENVL_REMOTE, + .get_char = env_get_char_spec, + .load = env_relocate_spec, + .save = env_save_ptr(saveenv), + .init = env_init, +}; diff --git a/env/sata.c b/env/sata.c index 64589117f2..f7b159a347 100644 --- a/env/sata.c +++ b/env/sata.c @@ -125,3 +125,11 @@ void env_relocate_spec(void) env_import(buf, 1); } + +U_BOOT_ENV_LOCATION(sata) = { + .location = ENVL_ESATA, + .get_char = env_get_char_spec, + .load = env_relocate_spec, + .save = env_save_ptr(saveenv), + .init = env_init, +}; diff --git a/env/sf.c b/env/sf.c index 1da3549138..8f81cf5e40 100644 --- a/env/sf.c +++ b/env/sf.c @@ -32,9 +32,15 @@ # define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE #endif +#ifndef CONFIG_SPL_BUILD +#define CMD_SAVEENV +#endif + #ifdef CONFIG_ENV_OFFSET_REDUND +#ifdef CMD_SAVEENV static ulong env_offset = CONFIG_ENV_OFFSET; static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND; +#endif #define ACTIVE_FLAG 1 #define OBSOLETE_FLAG 0 @@ -77,6 +83,7 @@ static int setup_flash_device(void) } #if defined(CONFIG_ENV_OFFSET_REDUND) +#ifdef CMD_SAVEENV int saveenv(void) { env_t env_new; @@ -155,6 +162,7 @@ int saveenv(void) return ret; } +#endif /* CMD_SAVEENV */ void env_relocate_spec(void) { @@ -240,6 +248,7 @@ out: free(tmp_env2); } #else +#ifdef CMD_SAVEENV int saveenv(void) { u32 saved_size, saved_offset, sector; @@ -299,6 +308,7 @@ int saveenv(void) return ret; } +#endif /* CMD_SAVEENV */ void env_relocate_spec(void) { @@ -342,3 +352,13 @@ int env_init(void) return 0; } + +U_BOOT_ENV_LOCATION(sf) = { + .location = ENVL_SPI_FLASH, + .get_char = env_get_char_spec, + .load = env_relocate_spec, +#ifdef CMD_SAVEENV + .save = env_save_ptr(saveenv), +#endif + .init = env_init, +}; diff --git a/env/ubi.c b/env/ubi.c index 542371df8f..d91fdbaa4a 100644 --- a/env/ubi.c +++ b/env/ubi.c @@ -177,3 +177,11 @@ void env_relocate_spec(void) env_import(buf, 1); } #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ + +U_BOOT_ENV_LOCATION(ubi) = { + .location = ENVL_UBI, + .get_char = env_get_char_spec, + .load = env_relocate_spec, + .save = env_save_ptr(saveenv), + .init = env_init, +}; diff --git a/include/environment.h b/include/environment.h index ad2331c90b..ff3f54263a 100644 --- a/include/environment.h +++ b/include/environment.h @@ -204,6 +204,76 @@ enum env_valid { ENV_REDUND, /* Redundant environment is valid */ }; +enum env_location { + ENVL_DATAFLASH, + ENVL_EEPROM, + ENVL_EXT4, + ENVL_FAT, + ENVL_FLASH, + ENVL_MMC, + ENVL_NAND, + ENVL_NVRAM, + ENVL_ONENAND, + ENVL_REMOTE, + ENVL_SPI_FLASH, + ENVL_UBI, + ENVL_NOWHERE, + + ENVL_COUNT, + ENVL_UNKNOWN, +}; + +struct env_driver { + enum env_location location; + + /** + * get_char() - Read a character from the environment + * + * This method is optional. If not provided, a default implementation + * will read from gd->env_addr. + * + * @index: Index of character to read (0=first) + * @return character read + */ + unsigned char (*get_char)(int index); + + /** + * load() - Load the environment from storage + * + * This method is optional. If not provided, no environment will be + * loaded. + */ + void (*load)(void); + + /** + * save() - Save the environment to storage + * + * This method is required for 'saveenv' to work. + * + * @return 0 if OK, -ve on error + */ + int (*save)(void); + + /** + * init() - Set up the initial pre-relocation environment + * + * This method is optional. + * + * @return 0 if OK, -ve on error + */ + int (*init)(void); +}; + +/* Declare a new environment location driver */ +#define U_BOOT_ENV_LOCATION(__name) \ + ll_entry_declare(struct env_driver, __name, env_driver) + +#ifdef CONFIG_CMD_SAVEENV +#define env_save_ptr(x) x +#else +#define env_save_ptr(x) NULL +#endif + extern struct hsearch_data env_htab; /* Function that returns a character from the environment */ -- 2.39.2