Skip to content
Snippets Groups Projects
Commit a3110f01 authored by Stefano Babic's avatar Stefano Babic Committed by Wolfgang Denk
Browse files

env_sf: updated to the new environment code


Functions to store/retrieve the environment from a SPI flash was not updated
to the new environment code. The non-redundant case was
not working correctly, reporting ""Environment SPI flash not initialized"
and the code was not compiled clean in the redundant case.

The patch fixes these issue and makes the code more coherent
with other environment storage (nand, flash).

Signed-off-by: default avatarStefano Babic <sbabic@denx.de>
parent f0fee6a6
No related branches found
No related tags found
No related merge requests found
...@@ -51,7 +51,7 @@ static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND; ...@@ -51,7 +51,7 @@ static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND;
#define ACTIVE_FLAG 1 #define ACTIVE_FLAG 1
#define OBSOLETE_FLAG 0 #define OBSOLETE_FLAG 0
#endif /* CONFIG_ENV_ADDR_REDUND */ #endif /* CONFIG_ENV_OFFSET_REDUND */
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
...@@ -69,13 +69,6 @@ uchar env_get_char_spec(int index) ...@@ -69,13 +69,6 @@ uchar env_get_char_spec(int index)
} }
#if defined(CONFIG_ENV_OFFSET_REDUND) #if defined(CONFIG_ENV_OFFSET_REDUND)
void swap_env(void)
{
ulong tmp_offset = env_offset;
env_offset = env_new_offset;
env_new_offset = tmp_offset;
}
int saveenv(void) int saveenv(void)
{ {
...@@ -89,9 +82,14 @@ int saveenv(void) ...@@ -89,9 +82,14 @@ int saveenv(void)
char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG;
if (!env_flash) { if (!env_flash) {
puts("Environment SPI flash not initialized\n"); env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
CONFIG_ENV_SPI_CS,
CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
if (!env_flash) {
set_default_env("!spi_flash_probe() failed");
return 1; return 1;
} }
}
res = (char *)&env_new.data; res = (char *)&env_new.data;
len = hexport('\0', &res, ENV_SIZE); len = hexport('\0', &res, ENV_SIZE);
...@@ -102,6 +100,14 @@ int saveenv(void) ...@@ -102,6 +100,14 @@ int saveenv(void)
env_new.crc = crc32(0, env_new.data, ENV_SIZE); env_new.crc = crc32(0, env_new.data, ENV_SIZE);
env_new.flags = ACTIVE_FLAG; env_new.flags = ACTIVE_FLAG;
if (gd->env_valid == 1) {
env_new_offset = CONFIG_ENV_OFFSET_REDUND;
env_offset = CONFIG_ENV_OFFSET;
} else {
env_new_offset = CONFIG_ENV_OFFSET;
env_offset = CONFIG_ENV_OFFSET_REDUND;
}
/* Is the sector larger than the env (i.e. embedded) */ /* Is the sector larger than the env (i.e. embedded) */
if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
...@@ -130,17 +136,18 @@ int saveenv(void) ...@@ -130,17 +136,18 @@ int saveenv(void)
goto done; goto done;
puts("Writing to SPI flash..."); puts("Writing to SPI flash...");
ret = spi_flash_write(env_flash,
env_new_offset + offsetof(env_t, data), ret = spi_flash_write(env_flash, env_new_offset,
sizeof(env_new.data), env_new.data); CONFIG_ENV_SIZE, &env_new);
if (ret) if (ret)
goto done; goto done;
ret = spi_flash_write(env_flash, if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
env_new_offset + offsetof(env_t, crc), ret = spi_flash_write(env_flash, saved_offset,
sizeof(env_new.crc), &env_new.crc); saved_size, saved_buffer);
if (ret) if (ret)
goto done; goto done;
}
ret = spi_flash_write(env_flash, ret = spi_flash_write(env_flash,
env_offset + offsetof(env_t, flags), env_offset + offsetof(env_t, flags),
...@@ -148,23 +155,11 @@ int saveenv(void) ...@@ -148,23 +155,11 @@ int saveenv(void)
if (ret) if (ret)
goto done; goto done;
ret = spi_flash_write(env_flash, puts("done\n");
env_new_offset + offsetof(env_t, flags),
sizeof(env_new.flags), &new_flag);
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;
}
swap_env(); gd->env_valid = (gd->env_valid == 2 ? 1 : 2);
ret = 0; printf("Valid environment: %d\n", gd->env_valid);
puts("done\n");
done: done:
if (saved_buffer) if (saved_buffer)
...@@ -178,7 +173,7 @@ void env_relocate_spec(void) ...@@ -178,7 +173,7 @@ void env_relocate_spec(void)
int crc1_ok = 0, crc2_ok = 0; int crc1_ok = 0, crc2_ok = 0;
env_t *tmp_env1 = NULL; env_t *tmp_env1 = NULL;
env_t *tmp_env2 = NULL; env_t *tmp_env2 = NULL;
env_t ep; env_t *ep = NULL;
uchar flag1, flag2; uchar flag1, flag2;
/* current_env is set only in case both areas are valid! */ /* current_env is set only in case both areas are valid! */
int current_env = 0; int current_env = 0;
...@@ -219,90 +214,57 @@ void env_relocate_spec(void) ...@@ -219,90 +214,57 @@ void env_relocate_spec(void)
flag2 = tmp_env2->flags; flag2 = tmp_env2->flags;
} }
if (!crc1_ok && !crc2_ok) if (!crc1_ok && !crc2_ok) {
goto err_crc; free(tmp_env1);
else if (crc1_ok && !crc2_ok) { free(tmp_env2);
set_default_env("!bad CRC");
return;
} else if (crc1_ok && !crc2_ok) {
gd->env_valid = 1; gd->env_valid = 1;
ep = tmp_env1; ep = tmp_env1;
} else if (!crc1_ok && crc2_ok) { } else if (!crc1_ok && crc2_ok) {
gd->env_valid = 1; gd->env_valid = 1;
ep = tmp_env2;
swap_env();
} else if (flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG) { } else if (flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG) {
gd->env_valid = 1; gd->env_valid = 1;
ep = tmp_env1;
} else if (flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG) { } else if (flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG) {
gd->env_valid = 1; gd->env_valid = 2;
ep = tmp_env2;
swap_env();
} else if (flag1 == flag2) { } else if (flag1 == flag2) {
gd->env_valid = 2; gd->env_valid = 2;
ep = tmp_env1;
current_env = 1;
} else if (flag1 == 0xFF) { } else if (flag1 == 0xFF) {
gd->env_valid = 2; gd->env_valid = 2;
ep = tmp_env1;
current_env = 1;
} else { } else {
/* /*
* this differs from code in env_flash.c, but I think a sane * this differs from code in env_flash.c, but I think a sane
* default path is desirable. * default path is desirable.
*/ */
gd->env_valid = 2; gd->env_valid = 2;
ep = tmp_env2;
swap_env();
current_env = 2;
} }
rc = env_import((char *)ep, 0); free(env_ptr);
if (!rc) {
error("Cannot import environment: errno = %d\n", errno);
goto out;
}
if (current_env == 1) { if (gd->env_valid == 1)
if (flag2 != OBSOLETE_FLAG) { ep = tmp_env1;
flag2 = OBSOLETE_FLAG; else
spi_flash_write(env_flash, ep = tmp_env2;
env_new_offset + offsetof(env_t, flags),
sizeof(env_new.flags), &flag2); ret = env_import((char *)ep, 0);
} if (!ret) {
if (flag1 != ACTIVE_FLAG) { error("Cannot import environment: errno = %d\n", errno);
flag1 = ACTIVE_FLAG; set_default_env("env_import failed");
spi_flash_write(env_flash,
env_offset + offsetof(env_t, flags),
sizeof(env_new.flags), &flag1);
}
} else if (current_env == 2) {
if (flag1 != OBSOLETE_FLAG) {
flag1 = OBSOLETE_FLAG;
spi_flash_write(env_flash,
env_new_offset + offsetof(env_t, flags),
sizeof(env_new.flags), &flag1);
}
if (flag2 != ACTIVE_FLAG) {
flag2 = ACTIVE_FLAG;
spi_flash_write(env_flash,
env_offset + offsetof(env_t, flags),
sizeof(env_new.flags), &flag2);
}
}
if (gd->env_valid == 2) {
puts("*** Warning - some problems detected "
"reading environment; recovered successfully\n\n");
} }
if (tmp_env1)
free(tmp_env1);
if (tmp_env2)
free(tmp_env2);
return;
err_read: err_read:
spi_flash_free(env_flash); spi_flash_free(env_flash);
env_flash = NULL; env_flash = NULL;
out: out:
if (tmp_env1)
free(tmp_env1); free(tmp_env1);
if (tmp_env2)
free(tmp_env2); free(tmp_env2);
free(tmp_env1);
free(tmp_env2);
return;
} }
#else #else
int saveenv(void) int saveenv(void)
...@@ -311,11 +273,19 @@ int saveenv(void) ...@@ -311,11 +273,19 @@ int saveenv(void)
char *saved_buffer = NULL; char *saved_buffer = NULL;
u32 sector = 1; u32 sector = 1;
int ret; int ret;
env_t env_new;
char *res;
ssize_t len;
if (!env_flash) { if (!env_flash) {
puts("Environment SPI flash not initialized\n"); env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
CONFIG_ENV_SPI_CS,
CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
if (!env_flash) {
set_default_env("!spi_flash_probe() failed");
return 1; return 1;
} }
}
/* Is the sector larger than the env (i.e. embedded) */ /* Is the sector larger than the env (i.e. embedded) */
if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
...@@ -326,7 +296,8 @@ int saveenv(void) ...@@ -326,7 +296,8 @@ int saveenv(void)
ret = 1; ret = 1;
goto done; goto done;
} }
ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); ret = spi_flash_read(env_flash, saved_offset,
saved_size, saved_buffer);
if (ret) if (ret)
goto done; goto done;
} }
...@@ -337,18 +308,29 @@ int saveenv(void) ...@@ -337,18 +308,29 @@ int saveenv(void)
sector++; sector++;
} }
res = (char *)&env_new.data;
len = hexport('\0', &res, ENV_SIZE);
if (len < 0) {
error("Cannot export environment: errno = %d\n", errno);
goto done;
}
env_new.crc = crc32(0, env_new.data, ENV_SIZE);
puts("Erasing SPI flash..."); puts("Erasing SPI flash...");
ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET,
sector * CONFIG_ENV_SECT_SIZE);
if (ret) if (ret)
goto done; goto done;
puts("Writing to SPI flash..."); puts("Writing to SPI flash...");
ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET,
CONFIG_ENV_SIZE, &env_new);
if (ret) if (ret)
goto done; goto done;
if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); ret = spi_flash_write(env_flash, saved_offset,
saved_size, saved_buffer);
if (ret) if (ret)
goto done; goto done;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment