summaryrefslogtreecommitdiff
path: root/env
diff options
context:
space:
mode:
authorHoratiu Vultur <horatiu.vultur@microchip.com>2018-12-11 10:13:56 +0100
committerTom Rini <trini@konsulko.com>2019-01-16 16:14:46 -0500
commit9a9d66f5eff0f443de4c2c6ca3e27771ed14b1b4 (patch)
tree0cc4030df921f70bbdd87cb482f552df439a3463 /env
parenta38c3af868ad2a7a7c04667e559570d5f81b1d51 (diff)
env: add spi_flash_read_env function
The spi_flash_read_env function is a wrapper over spi_flash_read, which enables the env to read multiple flash page size from flash until '\0\0' is read or the end of env partition is reached. Instead of reading the entire env size. When it reads '\0\0', it stops reading further the env and assumes that the rest of env is '\0'. This is an optimization for large environments that contain few bytes environment variables. In this case it doesn't need to read the entire environment and only few pages. Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Diffstat (limited to 'env')
-rw-r--r--env/sf.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/env/sf.c b/env/sf.c
index 23cbad5d88..b3dec82c35 100644
--- a/env/sf.c
+++ b/env/sf.c
@@ -81,6 +81,40 @@ static int setup_flash_device(void)
return 0;
}
+static int is_end(const char *addr, size_t size)
+{
+ /* The end of env variables is marked by '\0\0' */
+ int i = 0;
+
+ for (i = 0; i < size - 1; ++i)
+ if (addr[i] == 0x0 && addr[i + 1] == 0x0)
+ return 1;
+ return 0;
+}
+
+static int spi_flash_read_env(struct spi_flash *flash, u32 offset, size_t len,
+ void *buf)
+{
+ u32 addr = 0;
+ u32 page_size = flash->page_size;
+
+ memset(buf, 0x0, len);
+ for (int i = 0; i < len / page_size; ++i) {
+ int ret = spi_flash_read(flash, offset, page_size,
+ &((char *)buf)[addr]);
+
+ if (ret < 0)
+ return ret;
+
+ if (is_end(&((char *)buf)[addr], page_size))
+ return 0;
+
+ addr += page_size;
+ offset += page_size;
+ }
+ return 0;
+}
+
#if defined(CONFIG_ENV_OFFSET_REDUND)
#ifdef CMD_SAVEENV
static int env_sf_save(void)
@@ -116,8 +150,8 @@ static int env_sf_save(void)
ret = -ENOMEM;
goto done;
}
- ret = spi_flash_read(env_flash, saved_offset,
- saved_size, saved_buffer);
+ ret = spi_flash_read_env(env_flash, saved_offset,
+ saved_size, saved_buffer);
if (ret)
goto done;
}
@@ -183,10 +217,10 @@ static int env_sf_load(void)
if (ret)
goto out;
- read1_fail = spi_flash_read(env_flash, CONFIG_ENV_OFFSET,
- CONFIG_ENV_SIZE, tmp_env1);
- read2_fail = spi_flash_read(env_flash, CONFIG_ENV_OFFSET_REDUND,
- CONFIG_ENV_SIZE, tmp_env2);
+ read1_fail = spi_flash_read_env(env_flash, CONFIG_ENV_OFFSET,
+ CONFIG_ENV_SIZE, tmp_env1);
+ read2_fail = spi_flash_read_env(env_flash, CONFIG_ENV_OFFSET_REDUND,
+ CONFIG_ENV_SIZE, tmp_env2);
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
read2_fail);
@@ -220,8 +254,8 @@ static int env_sf_save(void)
if (!saved_buffer)
goto done;
- ret = spi_flash_read(env_flash, saved_offset,
- saved_size, saved_buffer);
+ ret = spi_flash_read_env(env_flash, saved_offset,
+ saved_size, saved_buffer);
if (ret)
goto done;
}
@@ -277,10 +311,10 @@ static int env_sf_load(void)
if (ret)
goto out;
- ret = spi_flash_read(env_flash,
- CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, buf);
+ ret = spi_flash_read_env(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
+ buf);
if (ret) {
- set_default_env("spi_flash_read() failed", 0);
+ set_default_env("spi_flash_read_env() failed", 0);
goto err_read;
}