[PATCH v3] env: spi: Fix gd->env_valid for the first write
Michal Simek
michal.simek at amd.com
Mon Sep 22 18:03:39 CEST 2025
When both SPI environment locations are invalid (gd->env_valid ==
ENV_INVALID), the first call to saveenv writes to the primary location and
sets the active flag. However, the logic for updating gd->env_valid
incorrectly sets it to ENV_REDUND, which does not match the actual location
written. This causes the first two writes to target the same location, and
alternation only begins after the second write.
Update the logic to alternate gd->env_valid based on whether the last write
was to the primary or redundant location, ensuring the first write sets
ENV_VALID and subsequent writes alternate as expected. This aligns
env_valid with the actual storage location and fixes the alternation
sequence from the first write.
With this change, the "Valid environment" printout correctly reflects the
active location after each save, and the alternation between primary and
redundant locations works as intended from the start.
Signed-off-by: Michal Simek <michal.simek at amd.com>
---
Changes in v3:
- Polish commit message
Changes in v2:
- Simplify commit message
Origin commit message with more technical details.
When both location for variables are not valid (or empty) gd->env_valid is
0 (ENV_INVALID) which is setup by
env_sf_load()/env_import_redund()/env_check_redund() calls.
When saveenv is called in case of SPI env_sf_save() is called which
contains logic which describes new/old variable locations.
if (gd->env_valid == ENV_VALID) {
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;
}
In case of ENV_INVALID option the first location is used (else part)
and variables are saved with ENV_REDUND_ACTIVE flag.
The second location flag is rewritten to ENV_REDUND_OBSOLETE.
And
gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
is executed. env_valid is ENV_INVALID that's why ENV_REDUND is setup
but that's not correct because the first location has been written and not
the second one.
That is confirmed by
printf("Valid environment: %d\n", (int)gd->env_valid);
which is showing number 2 (ENV_REDUND).
That's why change the logic how env_valid is setup to be aligned with
offset calculation which also cover the case where initial state is
ENV_INVALID.
Then print about Valid environment is showing proper location where
variables are saved for the first time.
But also it is fixing behavior where the first two writes are going to the
first location instead of the first to the first location and second to
second location. Alternation is happening after it.
v1: https://lore.kernel.org/r/03aa59f72f47fe0ecafd1e1ca52cbb8a5a8f0446.1755613540.git.michal.simek@amd.com
v2: https://lore.kernel.org/r/7a6ffee423f45507af680c63a86cc50fb9e3a5df.1757489188.git.michal.simek@amd.com
---
env/sf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/env/sf.c b/env/sf.c
index 0b70e18b9afa..0e27a020643e 100644
--- a/env/sf.c
+++ b/env/sf.c
@@ -148,7 +148,7 @@ static int env_sf_save(void)
puts("done\n");
- gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
+ gd->env_valid = gd->env_valid == ENV_VALID ? ENV_REDUND : ENV_VALID;
printf("Valid environment: %d\n", (int)gd->env_valid);
--
2.43.0
base-commit: 281f39d07226d7c7239c22a0a42088780a78bccb
More information about the U-Boot
mailing list