summaryrefslogtreecommitdiffstats
path: root/common/env_sf.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2008-12-11 06:23:37 -0500
committerWolfgang Denk <wd@denx.de>2008-12-16 00:47:10 +0100
commit5b3375ac8c36c29c87abb132fede0509eb21e5c9 (patch)
treef44ea206e43139a95a3f4340409b7e2c6016dac8 /common/env_sf.c
parentecf5f077c8e77454f532eaac3e3afb7cfc48c62d (diff)
downloadblackbird-obmc-uboot-5b3375ac8c36c29c87abb132fede0509eb21e5c9.tar.gz
blackbird-obmc-uboot-5b3375ac8c36c29c87abb132fede0509eb21e5c9.zip
env_sf: support embedded environments
If both CONFIG_ENV_SECT_SIZE and CONFIG_ENV_SIZE are defined, and the sect size is larger than the env size, then it means the env is embedded in a block. So we have to save/restore the part of the sector which is not the environment. Previously, saving the environment in SPI flash in this setup would probably brick the board as the rest of the sector tends to contain actual U-Boot data/code. Signed-off-by: Mike Frysinger <vapier@gentoo.org> Acked-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Diffstat (limited to 'common/env_sf.c')
-rw-r--r--common/env_sf.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/common/env_sf.c b/common/env_sf.c
index 1bbf93fdfa..2f52e2561b 100644
--- a/common/env_sf.c
+++ b/common/env_sf.c
@@ -27,6 +27,7 @@
*/
#include <common.h>
#include <environment.h>
+#include <malloc.h>
#include <spi_flash.h>
#ifndef CONFIG_ENV_SPI_BUS
@@ -60,13 +61,30 @@ uchar env_get_char_spec(int index)
int saveenv(void)
{
+ u32 saved_size, saved_offset;
+ char *saved_buffer = NULL;
u32 sector = 1;
+ int ret;
if (!env_flash) {
puts("Environment SPI flash not initialized\n");
return 1;
}
+ /* Is the sector larger than the env (i.e. embedded) */
+ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
+ saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
+ saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE;
+ saved_buffer = malloc(saved_size);
+ if (!saved_buffer) {
+ ret = 1;
+ goto done;
+ }
+ ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer);
+ if (ret)
+ goto done;
+ }
+
if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) {
sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE;
if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE)
@@ -74,15 +92,28 @@ int saveenv(void)
}
puts("Erasing SPI flash...");
- if (spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE))
- return 1;
+ ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE);
+ if (ret)
+ goto done;
puts("Writing to SPI flash...");
- if (spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr))
- return 1;
+ ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr);
+ if (ret)
+ goto done;
+
+ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
+ ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer);
+ if (ret)
+ goto done;
+ }
+ ret = 0;
puts("done\n");
- return 0;
+
+ done:
+ if (saved_buffer)
+ free(saved_buffer);
+ return ret;
}
void env_relocate_spec(void)
OpenPOWER on IntegriCloud