public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [PATCH v8 0/4] efi_vars: Implement SPI Flash storage for EFI
@ 2026-02-11 15:56 Michal Simek
  2026-02-11 15:56 ` [PATCH v8 1/4] efi_var_file: refactor to move buffer functions Michal Simek
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Michal Simek @ 2026-02-11 15:56 UTC (permalink / raw)
  To: u-boot, git
  Cc: Heinrich Schuchardt, Ilias Apalodimas, Jan Kiszka,
	Jonathan Humphreys, Neil Armstrong, Pranav Tilak, Shantur Rathore,
	Simon Glass, Sughosh Ganu, Tom Rini, Ying-Chun Liu (PaulLiu)


This is updated series based on v3 version sent here
https://lore.kernel.org/all/20231126220836.374956-1-i@shantur.com/

that's why I am continuing on v4 instead of starting from scratch.

Tested on kv260 with saving variables to location where User MTD partition
is.
CONFIG_EFI_VARIABLE_SF_STORE=y
CONFIG_EFI_RT_VOLATILE_STORE=y
CONFIG_EFI_VARIABLE_SF_OFFSET=0x22a0000

In Linux:
root@som:~# mount | grep efivars
none on /sys/firmware/efi/efivars type efivarfs (rw,relatime)
root@som:~# printf '\x07\x00\x00\x00Hello' \
  | sudo tee /sys/firmware/efi/efivars/TestVar-12345678-1234-1234-1234-123456789abc
Helloroot@som:~#
root@som:~# dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c \
       of=/tmp/vars skip=4 bs=1
1352+0 records in
1352+0 records out
1352 bytes (1.4 kB, 1.3 KiB) copied, 0.380992 s, 3.5 kB/s
root@som:~# flashcp /tmp/vars /dev/mtd16
root@som:~# reboot

Reboot and then in U-Boot:

ZynqMP> pri -e
...
TestVar:
    12345678-1234-1234-1234-123456789abc (12345678-1234-1234-1234-123456789abc)
    NV|BS|RT, DataSize = 0x5
    00000000: 48 65 6c 6c 6f                                   Hello
...

Thanks,
Michal

Changes in v8:
- new patch
- Add missing EFI_VARIABLE_SF_STORE dependency to EFI_VARIABLE_SF_DEVICE_INDEX

Changes in v7:
- sed -i 's/efi_var_from/efi_var_from_storage/g'
- sed -i 's/efi_var_from/efi_var_from_storage/g'

Changes in v6:
- Return EFI_SUCCESS in efi_set_variable_int() when
  CONFIG_EFI_VARIABLE_NO_STORE is enabled
- sed -i 's/efi_var_read/efi_var_from/g'
- sed -i 's/efi_var_write/efi_var_to_storage/g'
- sed -i 's/efi_var_read/efi_var_from/g'
- sed -i 's/efi_var_write/efi_var_to_storage/g'

Changes in v5:
- Invert logic in efi_variable.c and avoid #if

Changes in v4:
- New patch based on review comments from v3
- Extend Kconfig description
- Extend commit message and describe efivar missing part
- use unify methods for reading/writing variable

Changes in v3:
- Fixed compiler warnings.

Changes in v2:
- Refactored efi_var_file to move common parts out as requested
- Changed ifdefs to use CONFIG_IS_DEFINED
- Fixed typos

Michal Simek (2):
  efi_var: Unify read/write access helper function
  efi_loader: Setup default location for UEFI Variables storing

Shantur Rathore (2):
  efi_var_file: refactor to move buffer functions
  efi_vars: Implement SPI Flash store

 include/efi_variable.h          | 18 +++----
 lib/efi_loader/Kconfig          | 38 +++++++++++++-
 lib/efi_loader/Makefile         |  3 +-
 lib/efi_loader/efi_var_common.c | 42 +++++++++++++++
 lib/efi_loader/efi_var_file.c   | 65 ++---------------------
 lib/efi_loader/efi_var_sf.c     | 92 +++++++++++++++++++++++++++++++++
 lib/efi_loader/efi_variable.c   | 19 ++++---
 7 files changed, 198 insertions(+), 79 deletions(-)
 create mode 100644 lib/efi_loader/efi_var_sf.c

-- 
2.43.0

base-commit: 8fe0e8e4dd573290bf845ee3fb12b346509be028
branch: debian-sent3

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v8 1/4] efi_var_file: refactor to move buffer functions
  2026-02-11 15:56 [PATCH v8 0/4] efi_vars: Implement SPI Flash storage for EFI Michal Simek
@ 2026-02-11 15:56 ` Michal Simek
  2026-02-12  6:14   ` Ilias Apalodimas
  2026-02-11 15:56 ` [PATCH v8 2/4] efi_var: Unify read/write access helper function Michal Simek
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Michal Simek @ 2026-02-11 15:56 UTC (permalink / raw)
  To: u-boot, git
  Cc: Shantur Rathore, Neil Armstrong, Heinrich Schuchardt,
	Ilias Apalodimas, Pranav Tilak, Sughosh Ganu, Tom Rini,
	Ying-Chun Liu (PaulLiu)

From: Shantur Rathore <i@shantur.com>

Currently efi_var_file.c has functions to store/read
EFI variables to/from memory buffer. These functions
can be used with other EFI variable stores so move
them out to efi_var_common.c

Signed-off-by: Shantur Rathore <i@shantur.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC

---

(no changes since v6)

Changes in v6:
- Return EFI_SUCCESS in efi_set_variable_int() when
  CONFIG_EFI_VARIABLE_NO_STORE is enabled

Changes in v5:
- Invert logic in efi_variable.c and avoid #if

 include/efi_variable.h          |  5 +++
 lib/efi_loader/Makefile         |  2 +-
 lib/efi_loader/efi_var_common.c | 42 ++++++++++++++++++++++++
 lib/efi_loader/efi_var_file.c   | 57 ---------------------------------
 lib/efi_loader/efi_variable.c   | 17 +++++++---
 5 files changed, 60 insertions(+), 63 deletions(-)

diff --git a/include/efi_variable.h b/include/efi_variable.h
index 4065cf45ecaf..ee68fa4a885f 100644
--- a/include/efi_variable.h
+++ b/include/efi_variable.h
@@ -161,6 +161,11 @@ efi_status_t efi_var_to_file(void);
 efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t *lenp,
 					    u32 check_attr_mask);
 
+/* GUID used by Shim to store the MOK database */
+#define SHIM_LOCK_GUID \
+	EFI_GUID(0x605dab50, 0xe046, 0x4300, \
+		 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
+
 /**
  * efi_var_restore() - restore EFI variables from buffer
  *
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index f490081f6542..ca1775eb03be 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -53,7 +53,7 @@ ifeq ($(CONFIG_EFI_MM_COMM_TEE),y)
 obj-y += efi_variable_tee.o
 else
 obj-y += efi_variable.o
-obj-y += efi_var_file.o
+obj-$(CONFIG_EFI_VARIABLE_FILE_STORE) += efi_var_file.o
 obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o
 endif
 obj-y += efi_watchdog.o
diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
index 4b34a58b4cf7..5ea1688dca3d 100644
--- a/lib/efi_loader/efi_var_common.c
+++ b/lib/efi_loader/efi_var_common.c
@@ -41,6 +41,7 @@ static const struct efi_auth_var_name_type name_type[] = {
 
 static bool efi_secure_boot;
 static enum efi_secure_mode efi_secure_mode;
+static const efi_guid_t shim_lock_guid = SHIM_LOCK_GUID;
 
 /**
  * efi_efi_get_variable() - retrieve value of a UEFI variable
@@ -488,3 +489,44 @@ efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t *
 
 	return EFI_SUCCESS;
 }
+
+efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
+{
+	struct efi_var_entry *var, *last_var;
+	u16 *data;
+	efi_status_t ret;
+
+	if (buf->reserved || buf->magic != EFI_VAR_FILE_MAGIC ||
+	    buf->crc32 != crc32(0, (u8 *)buf->var,
+				buf->length - sizeof(struct efi_var_file))) {
+		log_err("Invalid EFI variables file\n");
+		return EFI_INVALID_PARAMETER;
+	}
+
+	last_var = (struct efi_var_entry *)((u8 *)buf + buf->length);
+	for (var = buf->var; var < last_var;
+	     var = (struct efi_var_entry *)ALIGN((uintptr_t)data + var->length, 8)) {
+		data = var->name + u16_strlen(var->name) + 1;
+
+		/*
+		 * Secure boot related and volatile variables shall only be
+		 * restored from U-Boot's preseed.
+		 */
+		if (!safe &&
+		    (efi_auth_var_get_type(var->name, &var->guid) !=
+		     EFI_AUTH_VAR_NONE ||
+		     !guidcmp(&var->guid, &shim_lock_guid) ||
+		     !(var->attr & EFI_VARIABLE_NON_VOLATILE)))
+			continue;
+		if (!var->length)
+			continue;
+		if (efi_var_mem_find(&var->guid, var->name, NULL))
+			continue;
+		ret = efi_var_mem_ins(var->name, &var->guid, var->attr,
+				      var->length, data, 0, NULL,
+				      var->time);
+		if (ret != EFI_SUCCESS)
+			log_err("Failed to set EFI variable %ls\n", var->name);
+	}
+	return EFI_SUCCESS;
+}
diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c
index f23a964a4180..4061a463b580 100644
--- a/lib/efi_loader/efi_var_file.c
+++ b/lib/efi_loader/efi_var_file.c
@@ -14,17 +14,9 @@
 #include <mapmem.h>
 #include <efi_loader.h>
 #include <efi_variable.h>
-#include <u-boot/crc.h>
 
 #define PART_STR_LEN 10
 
-/* GUID used by Shim to store the MOK database */
-#define SHIM_LOCK_GUID \
-	EFI_GUID(0x605dab50, 0xe046, 0x4300, \
-		 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
-
-static const efi_guid_t shim_lock_guid = SHIM_LOCK_GUID;
-
 /**
  * efi_set_blk_dev_to_system_partition() - select EFI system partition
  *
@@ -59,7 +51,6 @@ static efi_status_t __maybe_unused efi_set_blk_dev_to_system_partition(void)
  */
 efi_status_t efi_var_to_file(void)
 {
-#ifdef CONFIG_EFI_VARIABLE_FILE_STORE
 	efi_status_t ret;
 	struct efi_var_file *buf;
 	loff_t len;
@@ -91,52 +82,6 @@ error:
 out:
 	free(buf);
 	return ret;
-#else
-	return EFI_SUCCESS;
-#endif
-}
-
-efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
-{
-	struct efi_var_entry *var, *last_var;
-	u16 *data;
-	efi_status_t ret;
-
-	if (buf->reserved || buf->magic != EFI_VAR_FILE_MAGIC ||
-	    buf->crc32 != crc32(0, (u8 *)buf->var,
-				buf->length - sizeof(struct efi_var_file))) {
-		log_err("Invalid EFI variables file\n");
-		return EFI_INVALID_PARAMETER;
-	}
-
-	last_var = (struct efi_var_entry *)((u8 *)buf + buf->length);
-	for (var = buf->var; var < last_var;
-	     var = (struct efi_var_entry *)
-		   ALIGN((uintptr_t)data + var->length, 8)) {
-
-		data = var->name + u16_strlen(var->name) + 1;
-
-		/*
-		 * Secure boot related and volatile variables shall only be
-		 * restored from U-Boot's preseed.
-		 */
-		if (!safe &&
-		    (efi_auth_var_get_type(var->name, &var->guid) !=
-		     EFI_AUTH_VAR_NONE ||
-		     !guidcmp(&var->guid, &shim_lock_guid) ||
-		     !(var->attr & EFI_VARIABLE_NON_VOLATILE)))
-			continue;
-		if (!var->length)
-			continue;
-		if (efi_var_mem_find(&var->guid, var->name, NULL))
-			continue;
-		ret = efi_var_mem_ins(var->name, &var->guid, var->attr,
-				      var->length, data, 0, NULL,
-				      var->time);
-		if (ret != EFI_SUCCESS)
-			log_err("Failed to set EFI variable %ls\n", var->name);
-	}
-	return EFI_SUCCESS;
 }
 
 /**
@@ -155,7 +100,6 @@ efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
  */
 efi_status_t efi_var_from_file(void)
 {
-#ifdef CONFIG_EFI_VARIABLE_FILE_STORE
 	struct efi_var_file *buf;
 	loff_t len;
 	efi_status_t ret;
@@ -180,6 +124,5 @@ efi_status_t efi_var_from_file(void)
 		log_err("Invalid EFI variables file\n");
 error:
 	free(buf);
-#endif
 	return EFI_SUCCESS;
 }
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index f3533f4def3a..6e45134c61bf 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -397,11 +397,15 @@ efi_status_t efi_set_variable_int(const u16 *variable_name,
 		ret = EFI_SUCCESS;
 
 	/*
-	 * Write non-volatile EFI variables to file
+	 * Write non-volatile EFI variables
 	 * TODO: check if a value change has occured to avoid superfluous writes
 	 */
-	if (attributes & EFI_VARIABLE_NON_VOLATILE)
+	if (attributes & EFI_VARIABLE_NON_VOLATILE) {
+		if (IS_ENABLED(CONFIG_EFI_VARIABLE_NO_STORE))
+			return EFI_SUCCESS;
+
 		efi_var_to_file();
+	}
 
 	return EFI_SUCCESS;
 }
@@ -594,9 +598,12 @@ efi_status_t efi_init_variables(void)
 	if (ret != EFI_SUCCESS)
 		return ret;
 
-	ret = efi_var_from_file();
-	if (ret != EFI_SUCCESS)
-		return ret;
+	if (!IS_ENABLED(CONFIG_EFI_VARIABLE_NO_STORE)) {
+		ret = efi_var_from_file();
+		if (ret != EFI_SUCCESS)
+			return ret;
+	}
+
 	if (IS_ENABLED(CONFIG_EFI_VARIABLES_PRESEED)) {
 		ret = efi_var_restore((struct efi_var_file *)
 				      __efi_var_file_begin, true);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v8 2/4] efi_var: Unify read/write access helper function
  2026-02-11 15:56 [PATCH v8 0/4] efi_vars: Implement SPI Flash storage for EFI Michal Simek
  2026-02-11 15:56 ` [PATCH v8 1/4] efi_var_file: refactor to move buffer functions Michal Simek
@ 2026-02-11 15:56 ` Michal Simek
  2026-02-11 15:56 ` [PATCH v8 3/4] efi_loader: Setup default location for UEFI Variables storing Michal Simek
  2026-02-11 15:56 ` [PATCH v8 4/4] efi_vars: Implement SPI Flash store Michal Simek
  3 siblings, 0 replies; 15+ messages in thread
From: Michal Simek @ 2026-02-11 15:56 UTC (permalink / raw)
  To: u-boot, git
  Cc: Ilias Apalodimas, Neil Armstrong, Heinrich Schuchardt,
	Pranav Tilak, Shantur Rathore, Tom Rini

efi_var_to/from_file() suggest method where variables are placed. But there
is no reason for it and generic name can be used to wire also different
locations for variables.

Signed-off-by: Michal Simek <michal.simek@amd.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC

---

(no changes since v7)

Changes in v7:
- sed -i 's/efi_var_from/efi_var_from_storage/g'

Changes in v6:
- sed -i 's/efi_var_read/efi_var_from/g'
- sed -i 's/efi_var_write/efi_var_to_storage/g'

Changes in v4:
- New patch based on review comments from v3

 include/efi_variable.h        | 13 ++++---------
 lib/efi_loader/efi_var_file.c |  8 ++++----
 lib/efi_loader/efi_variable.c |  4 ++--
 3 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/include/efi_variable.h b/include/efi_variable.h
index ee68fa4a885f..fc1184e5ca1a 100644
--- a/include/efi_variable.h
+++ b/include/efi_variable.h
@@ -137,13 +137,11 @@ struct efi_var_file {
 };
 
 /**
- * efi_var_to_file() - save non-volatile variables as file
- *
- * File ubootefi.var is created on the EFI system partion.
+ * efi_var_to_storage() - save non-volatile variables
  *
  * Return:	status code
  */
-efi_status_t efi_var_to_file(void);
+efi_status_t efi_var_to_storage(void);
 
 /**
  * efi_var_collect() - collect variables in buffer
@@ -178,17 +176,14 @@ efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t *
 efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe);
 
 /**
- * efi_var_from_file() - read variables from file
- *
- * File ubootefi.var is read from the EFI system partitions and the variables
- * stored in the file are created.
+ * efi_var_from_storage() - read variables
  *
  * In case the file does not exist yet or a variable cannot be set EFI_SUCCESS
  * is returned.
  *
  * Return:	status code
  */
-efi_status_t efi_var_from_file(void);
+efi_status_t efi_var_from_storage(void);
 
 /**
  * efi_var_mem_init() - set-up variable list
diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c
index 4061a463b580..9cda38f319ee 100644
--- a/lib/efi_loader/efi_var_file.c
+++ b/lib/efi_loader/efi_var_file.c
@@ -43,13 +43,13 @@ static efi_status_t __maybe_unused efi_set_blk_dev_to_system_partition(void)
 }
 
 /**
- * efi_var_to_file() - save non-volatile variables as file
+ * efi_var_to_storage() - save non-volatile variables as file
  *
  * File ubootefi.var is created on the EFI system partion.
  *
  * Return:	status code
  */
-efi_status_t efi_var_to_file(void)
+efi_status_t efi_var_to_storage(void)
 {
 	efi_status_t ret;
 	struct efi_var_file *buf;
@@ -85,7 +85,7 @@ out:
 }
 
 /**
- * efi_var_from_file() - read variables from file
+ * efi_var_from_storage() - read variables from file
  *
  * File ubootefi.var is read from the EFI system partitions and the variables
  * stored in the file are created.
@@ -98,7 +98,7 @@ out:
  *
  * Return:	status code
  */
-efi_status_t efi_var_from_file(void)
+efi_status_t efi_var_from_storage(void)
 {
 	struct efi_var_file *buf;
 	loff_t len;
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 6e45134c61bf..8512bc20f11e 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -404,7 +404,7 @@ efi_status_t efi_set_variable_int(const u16 *variable_name,
 		if (IS_ENABLED(CONFIG_EFI_VARIABLE_NO_STORE))
 			return EFI_SUCCESS;
 
-		efi_var_to_file();
+		efi_var_to_storage();
 	}
 
 	return EFI_SUCCESS;
@@ -599,7 +599,7 @@ efi_status_t efi_init_variables(void)
 		return ret;
 
 	if (!IS_ENABLED(CONFIG_EFI_VARIABLE_NO_STORE)) {
-		ret = efi_var_from_file();
+		ret = efi_var_from_storage();
 		if (ret != EFI_SUCCESS)
 			return ret;
 	}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v8 3/4] efi_loader: Setup default location for UEFI Variables storing
  2026-02-11 15:56 [PATCH v8 0/4] efi_vars: Implement SPI Flash storage for EFI Michal Simek
  2026-02-11 15:56 ` [PATCH v8 1/4] efi_var_file: refactor to move buffer functions Michal Simek
  2026-02-11 15:56 ` [PATCH v8 2/4] efi_var: Unify read/write access helper function Michal Simek
@ 2026-02-11 15:56 ` Michal Simek
  2026-02-11 20:40   ` Ilias Apalodimas
  2026-02-11 15:56 ` [PATCH v8 4/4] efi_vars: Implement SPI Flash store Michal Simek
  3 siblings, 1 reply; 15+ messages in thread
From: Michal Simek @ 2026-02-11 15:56 UTC (permalink / raw)
  To: u-boot, git
  Cc: Tom Rini, Heinrich Schuchardt, Ilias Apalodimas, Jan Kiszka,
	Jonathan Humphreys, Shantur Rathore, Simon Glass,
	Ying-Chun Liu (PaulLiu)

EFI_VARIABLE_FILE_STORE is only available when FAT_WRITE is enabled but
that's not valid for all platforms and dependency should be covered.

Also Kconfig behavior is that if default option is not valid then Kconfig
selects the first presented valid option instead hence it is better to
record EFI_VARIABLE_NO_STORE as safe default option.

Suggested-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
---

Changes in v8:
- new patch

 lib/efi_loader/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 13e44be1d067..579eed658801 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -112,7 +112,8 @@ menu "UEFI Variables"
 
 choice
 	prompt "Store for non-volatile UEFI variables"
-	default EFI_VARIABLE_FILE_STORE
+	default EFI_VARIABLE_FILE_STORE if FAT_WRITE
+	default EFI_VARIABLE_NO_STORE
 	help
 	  Select where non-volatile UEFI variables shall be stored.
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-11 15:56 [PATCH v8 0/4] efi_vars: Implement SPI Flash storage for EFI Michal Simek
                   ` (2 preceding siblings ...)
  2026-02-11 15:56 ` [PATCH v8 3/4] efi_loader: Setup default location for UEFI Variables storing Michal Simek
@ 2026-02-11 15:56 ` Michal Simek
  2026-02-15  8:48   ` Heinrich Schuchardt
  3 siblings, 1 reply; 15+ messages in thread
From: Michal Simek @ 2026-02-11 15:56 UTC (permalink / raw)
  To: u-boot, git
  Cc: Shantur Rathore, Neil Armstrong, Ilias Apalodimas,
	Heinrich Schuchardt, Jonathan Humphreys, Simon Glass,
	Sughosh Ganu, Tom Rini, Ying-Chun Liu (PaulLiu)

From: Shantur Rathore <i@shantur.com>

Currently U-Boot uses ESP as storage for EFI variables.
Devices with SPI Flash are used for storing environment with this
commit we allow EFI variables to be stored on SPI Flash.

https://github.com/rhboot/efivar
is not updated to support this location that's why you can mimic it by
running:
dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c \
   of=/tmp/vars skip=4 bs=1
flashcp /tmp/vars /dev/mtdX

where mtdX should match location defined by
CONFIG_EFI_VARIABLE_SF_OFFSET/CONFIG_EFI_VAR_BUF_SIZE.

Signed-off-by: Shantur Rathore <i@shantur.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>

---

Changes in v8:
- Add missing EFI_VARIABLE_SF_STORE dependency to EFI_VARIABLE_SF_DEVICE_INDEX

Changes in v7:
- sed -i 's/efi_var_from/efi_var_from_storage/g'

Changes in v6:
- sed -i 's/efi_var_read/efi_var_from/g'
- sed -i 's/efi_var_write/efi_var_to_storage/g'

Changes in v4:
- Extend Kconfig description
- Extend commit message and describe efivar missing part
- use unify methods for reading/writing variable

Changes in v3:
- Fixed compiler warnings.

Changes in v2:
- Refactored efi_var_file to move common parts out as requested
- Changed ifdefs to use CONFIG_IS_DEFINED
- Fixed typos

 lib/efi_loader/Kconfig      | 35 +++++++++++++-
 lib/efi_loader/Makefile     |  1 +
 lib/efi_loader/efi_var_sf.c | 92 +++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+), 1 deletion(-)
 create mode 100644 lib/efi_loader/efi_var_sf.c

diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 579eed658801..0f6f927ddaf1 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -124,6 +124,24 @@ config EFI_VARIABLE_FILE_STORE
 	  Select this option if you want non-volatile UEFI variables to be
 	  stored as file /ubootefi.var on the EFI system partition.
 
+config EFI_VARIABLE_SF_STORE
+	bool "Store non-volatile UEFI variables in SPI Flash"
+	depends on SPI_FLASH
+	help
+	  Select this option if you want non-volatile UEFI variables to be
+	  stored in SPI Flash.
+
+	  Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
+	  the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
+	  needed.
+
+	  Note that SPI Flash devices have a limited number of program/erase
+	  cycles. Frequent updates to UEFI variables may cause excessive wear
+	  and can permanently damage the flash device, particularly on SPI NAND
+	  or low-end SPI NOR parts without wear leveling. This option should be
+	  used with care on such systems, and is not recommended for platforms
+	  where UEFI variables are updated frequently.
+
 config EFI_MM_COMM_TEE
 	bool "UEFI variables storage service via the trusted world"
 	depends on OPTEE
@@ -153,7 +171,7 @@ endchoice
 
 config EFI_RT_VOLATILE_STORE
 	bool "Allow variable runtime services in volatile storage (e.g RAM)"
-	depends on EFI_VARIABLE_FILE_STORE
+	depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE
 	help
 	  When EFI variables are stored on file we don't allow SetVariableRT,
 	  since the OS doesn't know how to write that file. At the same time
@@ -194,6 +212,21 @@ config FFA_SHARED_MM_BUF_ADDR
 	  the MM SP in secure world.
 	  It is assumed that the MM SP knows the address of the shared MM communication buffer.
 
+config EFI_VARIABLE_SF_OFFSET
+	hex "EFI variables in SPI flash offset"
+	depends on EFI_VARIABLE_SF_STORE
+	help
+	  Offset from the start of the SPI Flash where EFI variables will be stored.
+	  This should be aligned to the sector size of SPI Flash.
+
+config EFI_VARIABLE_SF_DEVICE_INDEX
+	int "Device Index for target SPI Flash"
+	depends on EFI_VARIABLE_SF_STORE
+	default 0
+	help
+	  The index of SPI Flash device used for storing EFI variables. This would be
+	  needed if there are more than 1 SPI Flash devices available to use.
+
 config EFI_VARIABLES_PRESEED
 	bool "Initial values for UEFI variables"
 	depends on !COMPILE_TEST
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index ca1775eb03be..d73ad43951b1 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -54,6 +54,7 @@ obj-y += efi_variable_tee.o
 else
 obj-y += efi_variable.o
 obj-$(CONFIG_EFI_VARIABLE_FILE_STORE) += efi_var_file.o
+obj-$(CONFIG_EFI_VARIABLE_SF_STORE) += efi_var_sf.o
 obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o
 endif
 obj-y += efi_watchdog.o
diff --git a/lib/efi_loader/efi_var_sf.c b/lib/efi_loader/efi_var_sf.c
new file mode 100644
index 000000000000..61d68f7c5c94
--- /dev/null
+++ b/lib/efi_loader/efi_var_sf.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SPI Flash interface for UEFI variables
+ *
+ * Copyright (c) 2023, Shantur Rathore
+ * Copyright (C) 2026, Advanced Micro Devices, Inc.
+ */
+
+#define LOG_CATEGORY LOGC_EFI
+
+#include <efi_loader.h>
+#include <efi_variable.h>
+#include <spi_flash.h>
+#include <dm.h>
+
+efi_status_t efi_var_to_storage(void)
+{
+	efi_status_t ret;
+	struct efi_var_file *buf;
+	loff_t len;
+	struct udevice *sfdev;
+
+	ret = efi_var_collect(&buf, &len, EFI_VARIABLE_NON_VOLATILE);
+	if (len > EFI_VAR_BUF_SIZE) {
+		log_err("EFI var buffer length more than target SPI Flash size");
+		ret = EFI_OUT_OF_RESOURCES;
+		goto error;
+	}
+
+	log_debug("%s - Got buffer to write buf->len : %d\n", __func__, buf->length);
+
+	if (ret != EFI_SUCCESS)
+		goto error;
+
+	ret = uclass_get_device(UCLASS_SPI_FLASH, CONFIG_EFI_VARIABLE_SF_DEVICE_INDEX, &sfdev);
+	if (ret)
+		goto error;
+
+	ret = spi_flash_erase_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, EFI_VAR_BUF_SIZE);
+	log_debug("%s - Erased SPI Flash offset %x\n", __func__, CONFIG_EFI_VARIABLE_SF_OFFSET);
+	if (ret)
+		goto error;
+
+	ret = spi_flash_write_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, len, buf);
+	log_debug("%s - Wrote buffer to SPI Flash : %ld\n", __func__, ret);
+
+	if (ret)
+		goto error;
+
+	ret = EFI_SUCCESS;
+error:
+	if (ret)
+		log_err("Failed to persist EFI variables in SF\n");
+	free(buf);
+	return ret;
+}
+
+efi_status_t efi_var_from_storage(void)
+{
+	struct efi_var_file *buf;
+	efi_status_t ret;
+	struct udevice *sfdev;
+
+	buf = calloc(1, EFI_VAR_BUF_SIZE);
+	if (!buf) {
+		log_err("%s - Unable to allocate buffer\n", __func__);
+		return EFI_OUT_OF_RESOURCES;
+	}
+
+	ret = uclass_get_device(UCLASS_SPI_FLASH, 0, &sfdev);
+	if (ret)
+		goto error;
+
+	ret = spi_flash_read_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET,
+				EFI_VAR_BUF_SIZE, buf);
+
+	log_debug("%s - read buffer buf->length: %x\n", __func__, buf->length);
+
+	if (ret || buf->length < sizeof(struct efi_var_file)) {
+		log_err("%s - buffer read from SPI Flash isn't valid\n", __func__);
+		goto error;
+	}
+
+	ret = efi_var_restore(buf, false);
+	if (ret != EFI_SUCCESS)
+		log_err("%s - Unable to restore EFI variables from buffer\n", __func__);
+
+	ret = EFI_SUCCESS;
+error:
+	free(buf);
+	return ret;
+}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 3/4] efi_loader: Setup default location for UEFI Variables storing
  2026-02-11 15:56 ` [PATCH v8 3/4] efi_loader: Setup default location for UEFI Variables storing Michal Simek
@ 2026-02-11 20:40   ` Ilias Apalodimas
  0 siblings, 0 replies; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-11 20:40 UTC (permalink / raw)
  To: Michal Simek
  Cc: u-boot, git, Tom Rini, Heinrich Schuchardt, Jan Kiszka,
	Jonathan Humphreys, Shantur Rathore, Simon Glass,
	Ying-Chun Liu (PaulLiu)

On Wed, 11 Feb 2026 at 17:56, Michal Simek <michal.simek@amd.com> wrote:
>
> EFI_VARIABLE_FILE_STORE is only available when FAT_WRITE is enabled but
> that's not valid for all platforms and dependency should be covered.
>
> Also Kconfig behavior is that if default option is not valid then Kconfig
> selects the first presented valid option instead hence it is better to
> record EFI_VARIABLE_NO_STORE as safe default option.
>
> Suggested-by: Tom Rini <trini@konsulko.com>
> Signed-off-by: Michal Simek <michal.simek@amd.com>
> ---

Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>

>
> Changes in v8:
> - new patch
>
>  lib/efi_loader/Kconfig | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 13e44be1d067..579eed658801 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -112,7 +112,8 @@ menu "UEFI Variables"
>
>  choice
>         prompt "Store for non-volatile UEFI variables"
> -       default EFI_VARIABLE_FILE_STORE
> +       default EFI_VARIABLE_FILE_STORE if FAT_WRITE
> +       default EFI_VARIABLE_NO_STORE
>         help
>           Select where non-volatile UEFI variables shall be stored.
>
> --
> 2.43.0
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 1/4] efi_var_file: refactor to move buffer functions
  2026-02-11 15:56 ` [PATCH v8 1/4] efi_var_file: refactor to move buffer functions Michal Simek
@ 2026-02-12  6:14   ` Ilias Apalodimas
  0 siblings, 0 replies; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-12  6:14 UTC (permalink / raw)
  To: Michal Simek
  Cc: u-boot, git, Shantur Rathore, Neil Armstrong, Heinrich Schuchardt,
	Pranav Tilak, Sughosh Ganu, Tom Rini, Ying-Chun Liu (PaulLiu)

On Wed, 11 Feb 2026 at 17:56, Michal Simek <michal.simek@amd.com> wrote:
>
> From: Shantur Rathore <i@shantur.com>
>
> Currently efi_var_file.c has functions to store/read
> EFI variables to/from memory buffer. These functions
> can be used with other EFI variable stores so move
> them out to efi_var_common.c
>
> Signed-off-by: Shantur Rathore <i@shantur.com>
> Signed-off-by: Michal Simek <michal.simek@amd.com>
> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC
>
> ---

Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>

>
> (no changes since v6)
>
> Changes in v6:
> - Return EFI_SUCCESS in efi_set_variable_int() when
>   CONFIG_EFI_VARIABLE_NO_STORE is enabled
>
> Changes in v5:
> - Invert logic in efi_variable.c and avoid #if
>
>  include/efi_variable.h          |  5 +++
>  lib/efi_loader/Makefile         |  2 +-
>  lib/efi_loader/efi_var_common.c | 42 ++++++++++++++++++++++++
>  lib/efi_loader/efi_var_file.c   | 57 ---------------------------------
>  lib/efi_loader/efi_variable.c   | 17 +++++++---
>  5 files changed, 60 insertions(+), 63 deletions(-)
>
> diff --git a/include/efi_variable.h b/include/efi_variable.h
> index 4065cf45ecaf..ee68fa4a885f 100644
> --- a/include/efi_variable.h
> +++ b/include/efi_variable.h
> @@ -161,6 +161,11 @@ efi_status_t efi_var_to_file(void);
>  efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t *lenp,
>                                             u32 check_attr_mask);
>
> +/* GUID used by Shim to store the MOK database */
> +#define SHIM_LOCK_GUID \
> +       EFI_GUID(0x605dab50, 0xe046, 0x4300, \
> +                0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
> +
>  /**
>   * efi_var_restore() - restore EFI variables from buffer
>   *
> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> index f490081f6542..ca1775eb03be 100644
> --- a/lib/efi_loader/Makefile
> +++ b/lib/efi_loader/Makefile
> @@ -53,7 +53,7 @@ ifeq ($(CONFIG_EFI_MM_COMM_TEE),y)
>  obj-y += efi_variable_tee.o
>  else
>  obj-y += efi_variable.o
> -obj-y += efi_var_file.o
> +obj-$(CONFIG_EFI_VARIABLE_FILE_STORE) += efi_var_file.o
>  obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o
>  endif
>  obj-y += efi_watchdog.o
> diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
> index 4b34a58b4cf7..5ea1688dca3d 100644
> --- a/lib/efi_loader/efi_var_common.c
> +++ b/lib/efi_loader/efi_var_common.c
> @@ -41,6 +41,7 @@ static const struct efi_auth_var_name_type name_type[] = {
>
>  static bool efi_secure_boot;
>  static enum efi_secure_mode efi_secure_mode;
> +static const efi_guid_t shim_lock_guid = SHIM_LOCK_GUID;
>
>  /**
>   * efi_efi_get_variable() - retrieve value of a UEFI variable
> @@ -488,3 +489,44 @@ efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t *
>
>         return EFI_SUCCESS;
>  }
> +
> +efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
> +{
> +       struct efi_var_entry *var, *last_var;
> +       u16 *data;
> +       efi_status_t ret;
> +
> +       if (buf->reserved || buf->magic != EFI_VAR_FILE_MAGIC ||
> +           buf->crc32 != crc32(0, (u8 *)buf->var,
> +                               buf->length - sizeof(struct efi_var_file))) {
> +               log_err("Invalid EFI variables file\n");
> +               return EFI_INVALID_PARAMETER;
> +       }
> +
> +       last_var = (struct efi_var_entry *)((u8 *)buf + buf->length);
> +       for (var = buf->var; var < last_var;
> +            var = (struct efi_var_entry *)ALIGN((uintptr_t)data + var->length, 8)) {
> +               data = var->name + u16_strlen(var->name) + 1;
> +
> +               /*
> +                * Secure boot related and volatile variables shall only be
> +                * restored from U-Boot's preseed.
> +                */
> +               if (!safe &&
> +                   (efi_auth_var_get_type(var->name, &var->guid) !=
> +                    EFI_AUTH_VAR_NONE ||
> +                    !guidcmp(&var->guid, &shim_lock_guid) ||
> +                    !(var->attr & EFI_VARIABLE_NON_VOLATILE)))
> +                       continue;
> +               if (!var->length)
> +                       continue;
> +               if (efi_var_mem_find(&var->guid, var->name, NULL))
> +                       continue;
> +               ret = efi_var_mem_ins(var->name, &var->guid, var->attr,
> +                                     var->length, data, 0, NULL,
> +                                     var->time);
> +               if (ret != EFI_SUCCESS)
> +                       log_err("Failed to set EFI variable %ls\n", var->name);
> +       }
> +       return EFI_SUCCESS;
> +}
> diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c
> index f23a964a4180..4061a463b580 100644
> --- a/lib/efi_loader/efi_var_file.c
> +++ b/lib/efi_loader/efi_var_file.c
> @@ -14,17 +14,9 @@
>  #include <mapmem.h>
>  #include <efi_loader.h>
>  #include <efi_variable.h>
> -#include <u-boot/crc.h>
>
>  #define PART_STR_LEN 10
>
> -/* GUID used by Shim to store the MOK database */
> -#define SHIM_LOCK_GUID \
> -       EFI_GUID(0x605dab50, 0xe046, 0x4300, \
> -                0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
> -
> -static const efi_guid_t shim_lock_guid = SHIM_LOCK_GUID;
> -
>  /**
>   * efi_set_blk_dev_to_system_partition() - select EFI system partition
>   *
> @@ -59,7 +51,6 @@ static efi_status_t __maybe_unused efi_set_blk_dev_to_system_partition(void)
>   */
>  efi_status_t efi_var_to_file(void)
>  {
> -#ifdef CONFIG_EFI_VARIABLE_FILE_STORE
>         efi_status_t ret;
>         struct efi_var_file *buf;
>         loff_t len;
> @@ -91,52 +82,6 @@ error:
>  out:
>         free(buf);
>         return ret;
> -#else
> -       return EFI_SUCCESS;
> -#endif
> -}
> -
> -efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
> -{
> -       struct efi_var_entry *var, *last_var;
> -       u16 *data;
> -       efi_status_t ret;
> -
> -       if (buf->reserved || buf->magic != EFI_VAR_FILE_MAGIC ||
> -           buf->crc32 != crc32(0, (u8 *)buf->var,
> -                               buf->length - sizeof(struct efi_var_file))) {
> -               log_err("Invalid EFI variables file\n");
> -               return EFI_INVALID_PARAMETER;
> -       }
> -
> -       last_var = (struct efi_var_entry *)((u8 *)buf + buf->length);
> -       for (var = buf->var; var < last_var;
> -            var = (struct efi_var_entry *)
> -                  ALIGN((uintptr_t)data + var->length, 8)) {
> -
> -               data = var->name + u16_strlen(var->name) + 1;
> -
> -               /*
> -                * Secure boot related and volatile variables shall only be
> -                * restored from U-Boot's preseed.
> -                */
> -               if (!safe &&
> -                   (efi_auth_var_get_type(var->name, &var->guid) !=
> -                    EFI_AUTH_VAR_NONE ||
> -                    !guidcmp(&var->guid, &shim_lock_guid) ||
> -                    !(var->attr & EFI_VARIABLE_NON_VOLATILE)))
> -                       continue;
> -               if (!var->length)
> -                       continue;
> -               if (efi_var_mem_find(&var->guid, var->name, NULL))
> -                       continue;
> -               ret = efi_var_mem_ins(var->name, &var->guid, var->attr,
> -                                     var->length, data, 0, NULL,
> -                                     var->time);
> -               if (ret != EFI_SUCCESS)
> -                       log_err("Failed to set EFI variable %ls\n", var->name);
> -       }
> -       return EFI_SUCCESS;
>  }
>
>  /**
> @@ -155,7 +100,6 @@ efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
>   */
>  efi_status_t efi_var_from_file(void)
>  {
> -#ifdef CONFIG_EFI_VARIABLE_FILE_STORE
>         struct efi_var_file *buf;
>         loff_t len;
>         efi_status_t ret;
> @@ -180,6 +124,5 @@ efi_status_t efi_var_from_file(void)
>                 log_err("Invalid EFI variables file\n");
>  error:
>         free(buf);
> -#endif
>         return EFI_SUCCESS;
>  }
> diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
> index f3533f4def3a..6e45134c61bf 100644
> --- a/lib/efi_loader/efi_variable.c
> +++ b/lib/efi_loader/efi_variable.c
> @@ -397,11 +397,15 @@ efi_status_t efi_set_variable_int(const u16 *variable_name,
>                 ret = EFI_SUCCESS;
>
>         /*
> -        * Write non-volatile EFI variables to file
> +        * Write non-volatile EFI variables
>          * TODO: check if a value change has occured to avoid superfluous writes
>          */
> -       if (attributes & EFI_VARIABLE_NON_VOLATILE)
> +       if (attributes & EFI_VARIABLE_NON_VOLATILE) {
> +               if (IS_ENABLED(CONFIG_EFI_VARIABLE_NO_STORE))
> +                       return EFI_SUCCESS;
> +
>                 efi_var_to_file();
> +       }
>
>         return EFI_SUCCESS;
>  }
> @@ -594,9 +598,12 @@ efi_status_t efi_init_variables(void)
>         if (ret != EFI_SUCCESS)
>                 return ret;
>
> -       ret = efi_var_from_file();
> -       if (ret != EFI_SUCCESS)
> -               return ret;
> +       if (!IS_ENABLED(CONFIG_EFI_VARIABLE_NO_STORE)) {
> +               ret = efi_var_from_file();
> +               if (ret != EFI_SUCCESS)
> +                       return ret;
> +       }
> +
>         if (IS_ENABLED(CONFIG_EFI_VARIABLES_PRESEED)) {
>                 ret = efi_var_restore((struct efi_var_file *)
>                                       __efi_var_file_begin, true);
> --
> 2.43.0
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-11 15:56 ` [PATCH v8 4/4] efi_vars: Implement SPI Flash store Michal Simek
@ 2026-02-15  8:48   ` Heinrich Schuchardt
  2026-02-15 21:55     ` Heinrich Schuchardt
                       ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Heinrich Schuchardt @ 2026-02-15  8:48 UTC (permalink / raw)
  To: Michal Simek, Vincent Stehlé, Ilias Apalodimas
  Cc: Shantur Rathore, Neil Armstrong, Jonathan Humphreys, Simon Glass,
	Sughosh Ganu, Tom Rini, Ying-Chun Liu (PaulLiu), git, u-boot

On 2/11/26 16:56, Michal Simek wrote:
> From: Shantur Rathore <i@shantur.com>
> 
> Currently U-Boot uses ESP as storage for EFI variables.
> Devices with SPI Flash are used for storing environment with this
> commit we allow EFI variables to be stored on SPI Flash.
> 
> https://github.com/rhboot/efivar
> is not updated to support this location that's why you can mimic it by
> running:
> dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c \
>     of=/tmp/vars skip=4 bs=1
> flashcp /tmp/vars /dev/mtdX
> 
> where mtdX should match location defined by
> CONFIG_EFI_VARIABLE_SF_OFFSET/CONFIG_EFI_VAR_BUF_SIZE.
> 
> Signed-off-by: Shantur Rathore <i@shantur.com>
> Signed-off-by: Michal Simek <michal.simek@amd.com>
> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC
> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> 
> ---
> 
> Changes in v8:
> - Add missing EFI_VARIABLE_SF_STORE dependency to EFI_VARIABLE_SF_DEVICE_INDEX
> 
> Changes in v7:
> - sed -i 's/efi_var_from/efi_var_from_storage/g'
> 
> Changes in v6:
> - sed -i 's/efi_var_read/efi_var_from/g'
> - sed -i 's/efi_var_write/efi_var_to_storage/g'
> 
> Changes in v4:
> - Extend Kconfig description
> - Extend commit message and describe efivar missing part
> - use unify methods for reading/writing variable
> 
> Changes in v3:
> - Fixed compiler warnings.
> 
> Changes in v2:
> - Refactored efi_var_file to move common parts out as requested
> - Changed ifdefs to use CONFIG_IS_DEFINED
> - Fixed typos
> 
>   lib/efi_loader/Kconfig      | 35 +++++++++++++-
>   lib/efi_loader/Makefile     |  1 +
>   lib/efi_loader/efi_var_sf.c | 92 +++++++++++++++++++++++++++++++++++++
>   3 files changed, 127 insertions(+), 1 deletion(-)
>   create mode 100644 lib/efi_loader/efi_var_sf.c
> 
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 579eed658801..0f6f927ddaf1 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -124,6 +124,24 @@ config EFI_VARIABLE_FILE_STORE
>   	  Select this option if you want non-volatile UEFI variables to be
>   	  stored as file /ubootefi.var on the EFI system partition.
>   
> +config EFI_VARIABLE_SF_STORE
> +	bool "Store non-volatile UEFI variables in SPI Flash"
> +	depends on SPI_FLASH
> +	help
> +	  Select this option if you want non-volatile UEFI variables to be
> +	  stored in SPI Flash.
> +
> +	  Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
> +	  the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
> +	  needed.
> +
> +	  Note that SPI Flash devices have a limited number of program/erase
> +	  cycles. Frequent updates to UEFI variables may cause excessive wear
> +	  and can permanently damage the flash device, particularly on SPI NAND
> +	  or low-end SPI NOR parts without wear leveling. This option should be
> +	  used with care on such systems, and is not recommended for platforms
> +	  where UEFI variables are updated frequently.
> +
>   config EFI_MM_COMM_TEE
>   	bool "UEFI variables storage service via the trusted world"
>   	depends on OPTEE
> @@ -153,7 +171,7 @@ endchoice
>   
>   config EFI_RT_VOLATILE_STORE
>   	bool "Allow variable runtime services in volatile storage (e.g RAM)"
> -	depends on EFI_VARIABLE_FILE_STORE
> +	depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE

Hello Michal,

If the backend store is SPI flash, we should not publish the variable 
"RTStorageVolatile" at runtime as currently defined.

For the background see this commit for the efivar library:

https://github.com/rhboot/efivar/commit/68daa04654acbe1bbaa17ebfc23c371b39e69c6b

The first three patches look correct to me and I will add them to a 
merge request for efi-next.

The usage of efi_var_mem_ins() and efi_var_mem_del() when SetVariable() 
does not change anything is not flash-friendly. Michal, do you want to 
have a look at this area?

@Ilias, @Vincent:
We currently lack documentation for the 3 variables.
Would it make sense to add the definition of the variables to chapter 
source/chapter5-variable-storage.rst.

Would an efivar helper for SPI flash make sense?
How should RTStorageVolatile describe a SPI flash location?

Best regards

Heinrich

>   	help
>   	  When EFI variables are stored on file we don't allow SetVariableRT,
>   	  since the OS doesn't know how to write that file. At the same time
> @@ -194,6 +212,21 @@ config FFA_SHARED_MM_BUF_ADDR
>   	  the MM SP in secure world.
>   	  It is assumed that the MM SP knows the address of the shared MM communication buffer.
>   
> +config EFI_VARIABLE_SF_OFFSET
> +	hex "EFI variables in SPI flash offset"
> +	depends on EFI_VARIABLE_SF_STORE
> +	help
> +	  Offset from the start of the SPI Flash where EFI variables will be stored.
> +	  This should be aligned to the sector size of SPI Flash.
> +
> +config EFI_VARIABLE_SF_DEVICE_INDEX
> +	int "Device Index for target SPI Flash"
> +	depends on EFI_VARIABLE_SF_STORE
> +	default 0
> +	help
> +	  The index of SPI Flash device used for storing EFI variables. This would be
> +	  needed if there are more than 1 SPI Flash devices available to use.
> +
>   config EFI_VARIABLES_PRESEED
>   	bool "Initial values for UEFI variables"
>   	depends on !COMPILE_TEST
> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> index ca1775eb03be..d73ad43951b1 100644
> --- a/lib/efi_loader/Makefile
> +++ b/lib/efi_loader/Makefile
> @@ -54,6 +54,7 @@ obj-y += efi_variable_tee.o
>   else
>   obj-y += efi_variable.o
>   obj-$(CONFIG_EFI_VARIABLE_FILE_STORE) += efi_var_file.o
> +obj-$(CONFIG_EFI_VARIABLE_SF_STORE) += efi_var_sf.o
>   obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o
>   endif
>   obj-y += efi_watchdog.o
> diff --git a/lib/efi_loader/efi_var_sf.c b/lib/efi_loader/efi_var_sf.c
> new file mode 100644
> index 000000000000..61d68f7c5c94
> --- /dev/null
> +++ b/lib/efi_loader/efi_var_sf.c
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * SPI Flash interface for UEFI variables
> + *
> + * Copyright (c) 2023, Shantur Rathore
> + * Copyright (C) 2026, Advanced Micro Devices, Inc.
> + */
> +
> +#define LOG_CATEGORY LOGC_EFI
> +
> +#include <efi_loader.h>
> +#include <efi_variable.h>
> +#include <spi_flash.h>
> +#include <dm.h>
> +
> +efi_status_t efi_var_to_storage(void)
> +{
> +	efi_status_t ret;
> +	struct efi_var_file *buf;
> +	loff_t len;
> +	struct udevice *sfdev;
> +
> +	ret = efi_var_collect(&buf, &len, EFI_VARIABLE_NON_VOLATILE);
> +	if (len > EFI_VAR_BUF_SIZE) {
> +		log_err("EFI var buffer length more than target SPI Flash size");
> +		ret = EFI_OUT_OF_RESOURCES;
> +		goto error;
> +	}
> +
> +	log_debug("%s - Got buffer to write buf->len : %d\n", __func__, buf->length);
> +
> +	if (ret != EFI_SUCCESS)
> +		goto error;
> +
> +	ret = uclass_get_device(UCLASS_SPI_FLASH, CONFIG_EFI_VARIABLE_SF_DEVICE_INDEX, &sfdev);
> +	if (ret)
> +		goto error;
> +
> +	ret = spi_flash_erase_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, EFI_VAR_BUF_SIZE);
> +	log_debug("%s - Erased SPI Flash offset %x\n", __func__, CONFIG_EFI_VARIABLE_SF_OFFSET);
> +	if (ret)
> +		goto error;
> +
> +	ret = spi_flash_write_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, len, buf);
> +	log_debug("%s - Wrote buffer to SPI Flash : %ld\n", __func__, ret);
> +
> +	if (ret)
> +		goto error;
> +
> +	ret = EFI_SUCCESS;
> +error:
> +	if (ret)
> +		log_err("Failed to persist EFI variables in SF\n");
> +	free(buf);
> +	return ret;
> +}
> +
> +efi_status_t efi_var_from_storage(void)
> +{
> +	struct efi_var_file *buf;
> +	efi_status_t ret;
> +	struct udevice *sfdev;
> +
> +	buf = calloc(1, EFI_VAR_BUF_SIZE);
> +	if (!buf) {
> +		log_err("%s - Unable to allocate buffer\n", __func__);
> +		return EFI_OUT_OF_RESOURCES;
> +	}
> +
> +	ret = uclass_get_device(UCLASS_SPI_FLASH, 0, &sfdev);
> +	if (ret)
> +		goto error;
> +
> +	ret = spi_flash_read_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET,
> +				EFI_VAR_BUF_SIZE, buf);
> +
> +	log_debug("%s - read buffer buf->length: %x\n", __func__, buf->length);
> +
> +	if (ret || buf->length < sizeof(struct efi_var_file)) {
> +		log_err("%s - buffer read from SPI Flash isn't valid\n", __func__);
> +		goto error;
> +	}
> +
> +	ret = efi_var_restore(buf, false);
> +	if (ret != EFI_SUCCESS)
> +		log_err("%s - Unable to restore EFI variables from buffer\n", __func__);
> +
> +	ret = EFI_SUCCESS;
> +error:
> +	free(buf);
> +	return ret;
> +}


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-15  8:48   ` Heinrich Schuchardt
@ 2026-02-15 21:55     ` Heinrich Schuchardt
  2026-02-16  7:24     ` Michal Simek
  2026-02-16  7:24     ` Ilias Apalodimas
  2 siblings, 0 replies; 15+ messages in thread
From: Heinrich Schuchardt @ 2026-02-15 21:55 UTC (permalink / raw)
  To: Michal Simek, Vincent Stehlé, Ilias Apalodimas
  Cc: Shantur Rathore, Neil Armstrong, Jonathan Humphreys, Simon Glass,
	Sughosh Ganu, Tom Rini, Ying-Chun Liu (PaulLiu), git, u-boot

Am 15. Februar 2026 09:48:39 MEZ schrieb Heinrich Schuchardt <xypron.glpk@gmx.de>:
>On 2/11/26 16:56, Michal Simek wrote:
>> From: Shantur Rathore <i@shantur.com>
>> 
>> Currently U-Boot uses ESP as storage for EFI variables.
>> Devices with SPI Flash are used for storing environment with this
>> commit we allow EFI variables to be stored on SPI Flash.
>> 
>> https://github.com/rhboot/efivar
>> is not updated to support this location that's why you can mimic it by
>> running:
>> dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c \
>>     of=/tmp/vars skip=4 bs=1
>> flashcp /tmp/vars /dev/mtdX
>> 
>> where mtdX should match location defined by
>> CONFIG_EFI_VARIABLE_SF_OFFSET/CONFIG_EFI_VAR_BUF_SIZE.
>> 
>> Signed-off-by: Shantur Rathore <i@shantur.com>
>> Signed-off-by: Michal Simek <michal.simek@amd.com>
>> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC
>> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
>> 
>> ---
>> 
>> Changes in v8:
>> - Add missing EFI_VARIABLE_SF_STORE dependency to EFI_VARIABLE_SF_DEVICE_INDEX
>> 
>> Changes in v7:
>> - sed -i 's/efi_var_from/efi_var_from_storage/g'
>> 
>> Changes in v6:
>> - sed -i 's/efi_var_read/efi_var_from/g'
>> - sed -i 's/efi_var_write/efi_var_to_storage/g'
>> 
>> Changes in v4:
>> - Extend Kconfig description
>> - Extend commit message and describe efivar missing part
>> - use unify methods for reading/writing variable
>> 
>> Changes in v3:
>> - Fixed compiler warnings.
>> 
>> Changes in v2:
>> - Refactored efi_var_file to move common parts out as requested
>> - Changed ifdefs to use CONFIG_IS_DEFINED
>> - Fixed typos
>> 
>>   lib/efi_loader/Kconfig      | 35 +++++++++++++-
>>   lib/efi_loader/Makefile     |  1 +
>>   lib/efi_loader/efi_var_sf.c | 92 +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 127 insertions(+), 1 deletion(-)
>>   create mode 100644 lib/efi_loader/efi_var_sf.c
>> 
>> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
>> index 579eed658801..0f6f927ddaf1 100644
>> --- a/lib/efi_loader/Kconfig
>> +++ b/lib/efi_loader/Kconfig
>> @@ -124,6 +124,24 @@ config EFI_VARIABLE_FILE_STORE
>>   	  Select this option if you want non-volatile UEFI variables to be
>>   	  stored as file /ubootefi.var on the EFI system partition.
>>   +config EFI_VARIABLE_SF_STORE
>> +	bool "Store non-volatile UEFI variables in SPI Flash"
>> +	depends on SPI_FLASH
>> +	help
>> +	  Select this option if you want non-volatile UEFI variables to be
>> +	  stored in SPI Flash.
>> +
>> +	  Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
>> +	  the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
>> +	  needed.
>> +
>> +	  Note that SPI Flash devices have a limited number of program/erase
>> +	  cycles. Frequent updates to UEFI variables may cause excessive wear
>> +	  and can permanently damage the flash device, particularly on SPI NAND
>> +	  or low-end SPI NOR parts without wear leveling. This option should be
>> +	  used with care on such systems, and is not recommended for platforms
>> +	  where UEFI variables are updated frequently.
>> +
>>   config EFI_MM_COMM_TEE
>>   	bool "UEFI variables storage service via the trusted world"
>>   	depends on OPTEE
>> @@ -153,7 +171,7 @@ endchoice
>>     config EFI_RT_VOLATILE_STORE
>>   	bool "Allow variable runtime services in volatile storage (e.g RAM)"
>> -	depends on EFI_VARIABLE_FILE_STORE
>> +	depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE
>
>Hello Michal,
>
>If the backend store is SPI flash, we should not publish the variable "RTStorageVolatile" at runtime as currently defined.
>
>For the background see this commit for the efivar library:
>
>https://github.com/rhboot/efivar/commit/68daa04654acbe1bbaa17ebfc23c371b39e69c6b
>
>The first three patches look correct to me and I will add them to a merge request for efi-next.

The 3 prerequisite patches are now in origin/next. Just this one left to be reworked.

Best regards

Heinrich


>
>The usage of efi_var_mem_ins() and efi_var_mem_del() when SetVariable() does not change anything is not flash-friendly. Michal, do you want to have a look at this area?
>
>@Ilias, @Vincent:
>We currently lack documentation for the 3 variables.
>Would it make sense to add the definition of the variables to chapter source/chapter5-variable-storage.rst.
>
>Would an efivar helper for SPI flash make sense?
>How should RTStorageVolatile describe a SPI flash location?
>
>Best regards
>
>Heinrich
>
>>   	help
>>   	  When EFI variables are stored on file we don't allow SetVariableRT,
>>   	  since the OS doesn't know how to write that file. At the same time
>> @@ -194,6 +212,21 @@ config FFA_SHARED_MM_BUF_ADDR
>>   	  the MM SP in secure world.
>>   	  It is assumed that the MM SP knows the address of the shared MM communication buffer.
>>   +config EFI_VARIABLE_SF_OFFSET
>> +	hex "EFI variables in SPI flash offset"
>> +	depends on EFI_VARIABLE_SF_STORE
>> +	help
>> +	  Offset from the start of the SPI Flash where EFI variables will be stored.
>> +	  This should be aligned to the sector size of SPI Flash.
>> +
>> +config EFI_VARIABLE_SF_DEVICE_INDEX
>> +	int "Device Index for target SPI Flash"
>> +	depends on EFI_VARIABLE_SF_STORE
>> +	default 0
>> +	help
>> +	  The index of SPI Flash device used for storing EFI variables. This would be
>> +	  needed if there are more than 1 SPI Flash devices available to use.
>> +
>>   config EFI_VARIABLES_PRESEED
>>   	bool "Initial values for UEFI variables"
>>   	depends on !COMPILE_TEST
>> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
>> index ca1775eb03be..d73ad43951b1 100644
>> --- a/lib/efi_loader/Makefile
>> +++ b/lib/efi_loader/Makefile
>> @@ -54,6 +54,7 @@ obj-y += efi_variable_tee.o
>>   else
>>   obj-y += efi_variable.o
>>   obj-$(CONFIG_EFI_VARIABLE_FILE_STORE) += efi_var_file.o
>> +obj-$(CONFIG_EFI_VARIABLE_SF_STORE) += efi_var_sf.o
>>   obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o
>>   endif
>>   obj-y += efi_watchdog.o
>> diff --git a/lib/efi_loader/efi_var_sf.c b/lib/efi_loader/efi_var_sf.c
>> new file mode 100644
>> index 000000000000..61d68f7c5c94
>> --- /dev/null
>> +++ b/lib/efi_loader/efi_var_sf.c
>> @@ -0,0 +1,92 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * SPI Flash interface for UEFI variables
>> + *
>> + * Copyright (c) 2023, Shantur Rathore
>> + * Copyright (C) 2026, Advanced Micro Devices, Inc.
>> + */
>> +
>> +#define LOG_CATEGORY LOGC_EFI
>> +
>> +#include <efi_loader.h>
>> +#include <efi_variable.h>
>> +#include <spi_flash.h>
>> +#include <dm.h>
>> +
>> +efi_status_t efi_var_to_storage(void)
>> +{
>> +	efi_status_t ret;
>> +	struct efi_var_file *buf;
>> +	loff_t len;
>> +	struct udevice *sfdev;
>> +
>> +	ret = efi_var_collect(&buf, &len, EFI_VARIABLE_NON_VOLATILE);
>> +	if (len > EFI_VAR_BUF_SIZE) {
>> +		log_err("EFI var buffer length more than target SPI Flash size");
>> +		ret = EFI_OUT_OF_RESOURCES;
>> +		goto error;
>> +	}
>> +
>> +	log_debug("%s - Got buffer to write buf->len : %d\n", __func__, buf->length);
>> +
>> +	if (ret != EFI_SUCCESS)
>> +		goto error;
>> +
>> +	ret = uclass_get_device(UCLASS_SPI_FLASH, CONFIG_EFI_VARIABLE_SF_DEVICE_INDEX, &sfdev);
>> +	if (ret)
>> +		goto error;
>> +
>> +	ret = spi_flash_erase_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, EFI_VAR_BUF_SIZE);
>> +	log_debug("%s - Erased SPI Flash offset %x\n", __func__, CONFIG_EFI_VARIABLE_SF_OFFSET);
>> +	if (ret)
>> +		goto error;
>> +
>> +	ret = spi_flash_write_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, len, buf);
>> +	log_debug("%s - Wrote buffer to SPI Flash : %ld\n", __func__, ret);
>> +
>> +	if (ret)
>> +		goto error;
>> +
>> +	ret = EFI_SUCCESS;
>> +error:
>> +	if (ret)
>> +		log_err("Failed to persist EFI variables in SF\n");
>> +	free(buf);
>> +	return ret;
>> +}
>> +
>> +efi_status_t efi_var_from_storage(void)
>> +{
>> +	struct efi_var_file *buf;
>> +	efi_status_t ret;
>> +	struct udevice *sfdev;
>> +
>> +	buf = calloc(1, EFI_VAR_BUF_SIZE);
>> +	if (!buf) {
>> +		log_err("%s - Unable to allocate buffer\n", __func__);
>> +		return EFI_OUT_OF_RESOURCES;
>> +	}
>> +
>> +	ret = uclass_get_device(UCLASS_SPI_FLASH, 0, &sfdev);
>> +	if (ret)
>> +		goto error;
>> +
>> +	ret = spi_flash_read_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET,
>> +				EFI_VAR_BUF_SIZE, buf);
>> +
>> +	log_debug("%s - read buffer buf->length: %x\n", __func__, buf->length);
>> +
>> +	if (ret || buf->length < sizeof(struct efi_var_file)) {
>> +		log_err("%s - buffer read from SPI Flash isn't valid\n", __func__);
>> +		goto error;
>> +	}
>> +
>> +	ret = efi_var_restore(buf, false);
>> +	if (ret != EFI_SUCCESS)
>> +		log_err("%s - Unable to restore EFI variables from buffer\n", __func__);
>> +
>> +	ret = EFI_SUCCESS;
>> +error:
>> +	free(buf);
>> +	return ret;
>> +}
>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-15  8:48   ` Heinrich Schuchardt
  2026-02-15 21:55     ` Heinrich Schuchardt
@ 2026-02-16  7:24     ` Michal Simek
  2026-02-16 11:39       ` Heinrich Schuchardt
  2026-02-16  7:24     ` Ilias Apalodimas
  2 siblings, 1 reply; 15+ messages in thread
From: Michal Simek @ 2026-02-16  7:24 UTC (permalink / raw)
  To: Heinrich Schuchardt, Vincent Stehlé, Ilias Apalodimas
  Cc: Shantur Rathore, Neil Armstrong, Jonathan Humphreys, Simon Glass,
	Sughosh Ganu, Tom Rini, Ying-Chun Liu (PaulLiu), git, u-boot



On 2/15/26 09:48, Heinrich Schuchardt wrote:
> On 2/11/26 16:56, Michal Simek wrote:
>> From: Shantur Rathore <i@shantur.com>
>>
>> Currently U-Boot uses ESP as storage for EFI variables.
>> Devices with SPI Flash are used for storing environment with this
>> commit we allow EFI variables to be stored on SPI Flash.
>>
>> https://github.com/rhboot/efivar
>> is not updated to support this location that's why you can mimic it by
>> running:
>> dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c \
>>     of=/tmp/vars skip=4 bs=1
>> flashcp /tmp/vars /dev/mtdX
>>
>> where mtdX should match location defined by
>> CONFIG_EFI_VARIABLE_SF_OFFSET/CONFIG_EFI_VAR_BUF_SIZE.
>>
>> Signed-off-by: Shantur Rathore <i@shantur.com>
>> Signed-off-by: Michal Simek <michal.simek@amd.com>
>> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC
>> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
>>
>> ---
>>
>> Changes in v8:
>> - Add missing EFI_VARIABLE_SF_STORE dependency to EFI_VARIABLE_SF_DEVICE_INDEX
>>
>> Changes in v7:
>> - sed -i 's/efi_var_from/efi_var_from_storage/g'
>>
>> Changes in v6:
>> - sed -i 's/efi_var_read/efi_var_from/g'
>> - sed -i 's/efi_var_write/efi_var_to_storage/g'
>>
>> Changes in v4:
>> - Extend Kconfig description
>> - Extend commit message and describe efivar missing part
>> - use unify methods for reading/writing variable
>>
>> Changes in v3:
>> - Fixed compiler warnings.
>>
>> Changes in v2:
>> - Refactored efi_var_file to move common parts out as requested
>> - Changed ifdefs to use CONFIG_IS_DEFINED
>> - Fixed typos
>>
>>   lib/efi_loader/Kconfig      | 35 +++++++++++++-
>>   lib/efi_loader/Makefile     |  1 +
>>   lib/efi_loader/efi_var_sf.c | 92 +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 127 insertions(+), 1 deletion(-)
>>   create mode 100644 lib/efi_loader/efi_var_sf.c
>>
>> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
>> index 579eed658801..0f6f927ddaf1 100644
>> --- a/lib/efi_loader/Kconfig
>> +++ b/lib/efi_loader/Kconfig
>> @@ -124,6 +124,24 @@ config EFI_VARIABLE_FILE_STORE
>>         Select this option if you want non-volatile UEFI variables to be
>>         stored as file /ubootefi.var on the EFI system partition.
>> +config EFI_VARIABLE_SF_STORE
>> +    bool "Store non-volatile UEFI variables in SPI Flash"
>> +    depends on SPI_FLASH
>> +    help
>> +      Select this option if you want non-volatile UEFI variables to be
>> +      stored in SPI Flash.
>> +
>> +      Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
>> +      the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
>> +      needed.
>> +
>> +      Note that SPI Flash devices have a limited number of program/erase
>> +      cycles. Frequent updates to UEFI variables may cause excessive wear
>> +      and can permanently damage the flash device, particularly on SPI NAND
>> +      or low-end SPI NOR parts without wear leveling. This option should be
>> +      used with care on such systems, and is not recommended for platforms
>> +      where UEFI variables are updated frequently.
>> +
>>   config EFI_MM_COMM_TEE
>>       bool "UEFI variables storage service via the trusted world"
>>       depends on OPTEE
>> @@ -153,7 +171,7 @@ endchoice
>>   config EFI_RT_VOLATILE_STORE
>>       bool "Allow variable runtime services in volatile storage (e.g RAM)"
>> -    depends on EFI_VARIABLE_FILE_STORE
>> +    depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE
> 
> Hello Michal,
> 
> If the backend store is SPI flash, we should not publish the variable 
> "RTStorageVolatile" at runtime as currently defined.
> 
> For the background see this commit for the efivar library:
> 
> https://github.com/rhboot/efivar/commit/68daa04654acbe1bbaa17ebfc23c371b39e69c6b
> 
> The first three patches look correct to me and I will add them to a merge 
> request for efi-next.

Do I read it that when I don't allow to select EFI_RT_VOLATILE_STORE you will be 
fine with the patch itself?


> The usage of efi_var_mem_ins() and efi_var_mem_del() when SetVariable() does not 
> change anything is not flash-friendly. Michal, do you want to have a look at 
> this area?

That's known limitation describe in EFI_VARIABLE_SF_STORE Kconfig Note.

Thanks,
Michal


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-15  8:48   ` Heinrich Schuchardt
  2026-02-15 21:55     ` Heinrich Schuchardt
  2026-02-16  7:24     ` Michal Simek
@ 2026-02-16  7:24     ` Ilias Apalodimas
  2 siblings, 0 replies; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-16  7:24 UTC (permalink / raw)
  To: Heinrich Schuchardt
  Cc: Michal Simek, Vincent Stehlé, Shantur Rathore,
	Neil Armstrong, Jonathan Humphreys, Simon Glass, Sughosh Ganu,
	Tom Rini, Ying-Chun Liu (PaulLiu), git, u-boot

Hi Heinrich

[...]

> >
> > +config EFI_VARIABLE_SF_STORE
> > +     bool "Store non-volatile UEFI variables in SPI Flash"
> > +     depends on SPI_FLASH
> > +     help
> > +       Select this option if you want non-volatile UEFI variables to be
> > +       stored in SPI Flash.
> > +
> > +       Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
> > +       the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
> > +       needed.
> > +
> > +       Note that SPI Flash devices have a limited number of program/erase
> > +       cycles. Frequent updates to UEFI variables may cause excessive wear
> > +       and can permanently damage the flash device, particularly on SPI NAND
> > +       or low-end SPI NOR parts without wear leveling. This option should be
> > +       used with care on such systems, and is not recommended for platforms
> > +       where UEFI variables are updated frequently.
> > +
> >   config EFI_MM_COMM_TEE
> >       bool "UEFI variables storage service via the trusted world"
> >       depends on OPTEE
> > @@ -153,7 +171,7 @@ endchoice
> >
> >   config EFI_RT_VOLATILE_STORE
> >       bool "Allow variable runtime services in volatile storage (e.g RAM)"
> > -     depends on EFI_VARIABLE_FILE_STORE
> > +     depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE
>
> Hello Michal,
>
> If the backend store is SPI flash, we should not publish the variable
> "RTStorageVolatile" at runtime as currently defined.

We had this discussion on a previous version. I asked Michal to either
update the commit message with instructions on how to update the SPI
flash, or remove the EFI_RT_VOLATILE_STORE from SPI flashes.
Technically writing these from a bash script would work, although I
agree that ideally we want this into efivar.
I don't mind if we currently prohibit EFI_RT_VOLATILE_STORE from SPI

>
> For the background see this commit for the efivar library:
>
> https://github.com/rhboot/efivar/commit/68daa04654acbe1bbaa17ebfc23c371b39e69c6b
>
> The first three patches look correct to me and I will add them to a
> merge request for efi-next.
>
> The usage of efi_var_mem_ins() and efi_var_mem_del() when SetVariable()
> does not change anything is not flash-friendly. Michal, do you want to
> have a look at this area?
>
> @Ilias, @Vincent:
> We currently lack documentation for the 3 variables.
> Would it make sense to add the definition of the variables to chapter
> source/chapter5-variable-storage.rst.

I'll send a patch to update the documentation and we can discuss it.

Regards
/Ilias
>
> Would an efivar helper for SPI flash make sense?
> How should RTStorageVolatile describe a SPI flash location?
>
> Best regards
>
> Heinrich
>
> >       help
> >         When EFI variables are stored on file we don't allow SetVariableRT,
> >         since the OS doesn't know how to write that file. At the same time
> > @@ -194,6 +212,21 @@ config FFA_SHARED_MM_BUF_ADDR
> >         the MM SP in secure world.
> >         It is assumed that the MM SP knows the address of the shared MM communication buffer.
> >
> > +config EFI_VARIABLE_SF_OFFSET
> > +     hex "EFI variables in SPI flash offset"
> > +     depends on EFI_VARIABLE_SF_STORE
> > +     help
> > +       Offset from the start of the SPI Flash where EFI variables will be stored.
> > +       This should be aligned to the sector size of SPI Flash.
> > +
> > +config EFI_VARIABLE_SF_DEVICE_INDEX
> > +     int "Device Index for target SPI Flash"
> > +     depends on EFI_VARIABLE_SF_STORE
> > +     default 0
> > +     help
> > +       The index of SPI Flash device used for storing EFI variables. This would be
> > +       needed if there are more than 1 SPI Flash devices available to use.
> > +
> >   config EFI_VARIABLES_PRESEED
> >       bool "Initial values for UEFI variables"
> >       depends on !COMPILE_TEST
> > diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> > index ca1775eb03be..d73ad43951b1 100644
> > --- a/lib/efi_loader/Makefile
> > +++ b/lib/efi_loader/Makefile
> > @@ -54,6 +54,7 @@ obj-y += efi_variable_tee.o
> >   else
> >   obj-y += efi_variable.o
> >   obj-$(CONFIG_EFI_VARIABLE_FILE_STORE) += efi_var_file.o
> > +obj-$(CONFIG_EFI_VARIABLE_SF_STORE) += efi_var_sf.o
> >   obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o
> >   endif
> >   obj-y += efi_watchdog.o
> > diff --git a/lib/efi_loader/efi_var_sf.c b/lib/efi_loader/efi_var_sf.c
> > new file mode 100644
> > index 000000000000..61d68f7c5c94
> > --- /dev/null
> > +++ b/lib/efi_loader/efi_var_sf.c
> > @@ -0,0 +1,92 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * SPI Flash interface for UEFI variables
> > + *
> > + * Copyright (c) 2023, Shantur Rathore
> > + * Copyright (C) 2026, Advanced Micro Devices, Inc.
> > + */
> > +
> > +#define LOG_CATEGORY LOGC_EFI
> > +
> > +#include <efi_loader.h>
> > +#include <efi_variable.h>
> > +#include <spi_flash.h>
> > +#include <dm.h>
> > +
> > +efi_status_t efi_var_to_storage(void)
> > +{
> > +     efi_status_t ret;
> > +     struct efi_var_file *buf;
> > +     loff_t len;
> > +     struct udevice *sfdev;
> > +
> > +     ret = efi_var_collect(&buf, &len, EFI_VARIABLE_NON_VOLATILE);
> > +     if (len > EFI_VAR_BUF_SIZE) {
> > +             log_err("EFI var buffer length more than target SPI Flash size");
> > +             ret = EFI_OUT_OF_RESOURCES;
> > +             goto error;
> > +     }
> > +
> > +     log_debug("%s - Got buffer to write buf->len : %d\n", __func__, buf->length);
> > +
> > +     if (ret != EFI_SUCCESS)
> > +             goto error;
> > +
> > +     ret = uclass_get_device(UCLASS_SPI_FLASH, CONFIG_EFI_VARIABLE_SF_DEVICE_INDEX, &sfdev);
> > +     if (ret)
> > +             goto error;
> > +
> > +     ret = spi_flash_erase_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, EFI_VAR_BUF_SIZE);
> > +     log_debug("%s - Erased SPI Flash offset %x\n", __func__, CONFIG_EFI_VARIABLE_SF_OFFSET);
> > +     if (ret)
> > +             goto error;
> > +
> > +     ret = spi_flash_write_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, len, buf);
> > +     log_debug("%s - Wrote buffer to SPI Flash : %ld\n", __func__, ret);
> > +
> > +     if (ret)
> > +             goto error;
> > +
> > +     ret = EFI_SUCCESS;
> > +error:
> > +     if (ret)
> > +             log_err("Failed to persist EFI variables in SF\n");
> > +     free(buf);
> > +     return ret;
> > +}
> > +
> > +efi_status_t efi_var_from_storage(void)
> > +{
> > +     struct efi_var_file *buf;
> > +     efi_status_t ret;
> > +     struct udevice *sfdev;
> > +
> > +     buf = calloc(1, EFI_VAR_BUF_SIZE);
> > +     if (!buf) {
> > +             log_err("%s - Unable to allocate buffer\n", __func__);
> > +             return EFI_OUT_OF_RESOURCES;
> > +     }
> > +
> > +     ret = uclass_get_device(UCLASS_SPI_FLASH, 0, &sfdev);
> > +     if (ret)
> > +             goto error;
> > +
> > +     ret = spi_flash_read_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET,
> > +                             EFI_VAR_BUF_SIZE, buf);
> > +
> > +     log_debug("%s - read buffer buf->length: %x\n", __func__, buf->length);
> > +
> > +     if (ret || buf->length < sizeof(struct efi_var_file)) {
> > +             log_err("%s - buffer read from SPI Flash isn't valid\n", __func__);
> > +             goto error;
> > +     }
> > +
> > +     ret = efi_var_restore(buf, false);
> > +     if (ret != EFI_SUCCESS)
> > +             log_err("%s - Unable to restore EFI variables from buffer\n", __func__);
> > +
> > +     ret = EFI_SUCCESS;
> > +error:
> > +     free(buf);
> > +     return ret;
> > +}
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-16  7:24     ` Michal Simek
@ 2026-02-16 11:39       ` Heinrich Schuchardt
  2026-02-16 11:43         ` Ilias Apalodimas
  2026-02-16 12:08         ` Ilias Apalodimas
  0 siblings, 2 replies; 15+ messages in thread
From: Heinrich Schuchardt @ 2026-02-16 11:39 UTC (permalink / raw)
  To: Michal Simek, Vincent Stehlé, Ilias Apalodimas
  Cc: Shantur Rathore, Neil Armstrong, Jonathan Humphreys, Simon Glass,
	Sughosh Ganu, Tom Rini, Ying-Chun Liu (PaulLiu), git, u-boot

Am 16. Februar 2026 08:24:19 MEZ schrieb Michal Simek <michal.simek@amd.com>:
>
>
>On 2/15/26 09:48, Heinrich Schuchardt wrote:
>> On 2/11/26 16:56, Michal Simek wrote:
>>> From: Shantur Rathore <i@shantur.com>
>>> 
>>> Currently U-Boot uses ESP as storage for EFI variables.
>>> Devices with SPI Flash are used for storing environment with this
>>> commit we allow EFI variables to be stored on SPI Flash.
>>> 
>>> https://github.com/rhboot/efivar
>>> is not updated to support this location that's why you can mimic it by
>>> running:
>>> dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c \
>>>     of=/tmp/vars skip=4 bs=1
>>> flashcp /tmp/vars /dev/mtdX
>>> 
>>> where mtdX should match location defined by
>>> CONFIG_EFI_VARIABLE_SF_OFFSET/CONFIG_EFI_VAR_BUF_SIZE.
>>> 
>>> Signed-off-by: Shantur Rathore <i@shantur.com>
>>> Signed-off-by: Michal Simek <michal.simek@amd.com>
>>> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC
>>> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
>>> 
>>> ---
>>> 
>>> Changes in v8:
>>> - Add missing EFI_VARIABLE_SF_STORE dependency to EFI_VARIABLE_SF_DEVICE_INDEX
>>> 
>>> Changes in v7:
>>> - sed -i 's/efi_var_from/efi_var_from_storage/g'
>>> 
>>> Changes in v6:
>>> - sed -i 's/efi_var_read/efi_var_from/g'
>>> - sed -i 's/efi_var_write/efi_var_to_storage/g'
>>> 
>>> Changes in v4:
>>> - Extend Kconfig description
>>> - Extend commit message and describe efivar missing part
>>> - use unify methods for reading/writing variable
>>> 
>>> Changes in v3:
>>> - Fixed compiler warnings.
>>> 
>>> Changes in v2:
>>> - Refactored efi_var_file to move common parts out as requested
>>> - Changed ifdefs to use CONFIG_IS_DEFINED
>>> - Fixed typos
>>> 
>>>   lib/efi_loader/Kconfig      | 35 +++++++++++++-
>>>   lib/efi_loader/Makefile     |  1 +
>>>   lib/efi_loader/efi_var_sf.c | 92 +++++++++++++++++++++++++++++++++++++
>>>   3 files changed, 127 insertions(+), 1 deletion(-)
>>>   create mode 100644 lib/efi_loader/efi_var_sf.c
>>> 
>>> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
>>> index 579eed658801..0f6f927ddaf1 100644
>>> --- a/lib/efi_loader/Kconfig
>>> +++ b/lib/efi_loader/Kconfig
>>> @@ -124,6 +124,24 @@ config EFI_VARIABLE_FILE_STORE
>>>         Select this option if you want non-volatile UEFI variables to be
>>>         stored as file /ubootefi.var on the EFI system partition.
>>> +config EFI_VARIABLE_SF_STORE
>>> +    bool "Store non-volatile UEFI variables in SPI Flash"
>>> +    depends on SPI_FLASH
>>> +    help
>>> +      Select this option if you want non-volatile UEFI variables to be
>>> +      stored in SPI Flash.
>>> +
>>> +      Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
>>> +      the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
>>> +      needed.
>>> +
>>> +      Note that SPI Flash devices have a limited number of program/erase
>>> +      cycles. Frequent updates to UEFI variables may cause excessive wear
>>> +      and can permanently damage the flash device, particularly on SPI NAND
>>> +      or low-end SPI NOR parts without wear leveling. This option should be
>>> +      used with care on such systems, and is not recommended for platforms
>>> +      where UEFI variables are updated frequently.
>>> +
>>>   config EFI_MM_COMM_TEE
>>>       bool "UEFI variables storage service via the trusted world"
>>>       depends on OPTEE
>>> @@ -153,7 +171,7 @@ endchoice
>>>   config EFI_RT_VOLATILE_STORE
>>>       bool "Allow variable runtime services in volatile storage (e.g RAM)"
>>> -    depends on EFI_VARIABLE_FILE_STORE
>>> +    depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE
>> 
>> Hello Michal,
>> 
>> If the backend store is SPI flash, we should not publish the variable "RTStorageVolatile" at runtime as currently defined.
>> 
>> For the background see this commit for the efivar library:
>> 
>> https://github.com/rhboot/efivar/commit/68daa04654acbe1bbaa17ebfc23c371b39e69c6b
>> 
>> The first three patches look correct to me and I will add them to a merge request for efi-next.
>
>Do I read it that when I don't allow to select EFI_RT_VOLATILE_STORE you will be fine with the patch itself?

This was my only concern.

Maybe setting the file name to /dev/mtd/by-name/<partition name> would work with efivar. But I have not tested it.

In U-Boot we could replace EFI_VARIABLE_SF_DEVICE_INDEX, SIZE, and OFFSET by a partition name, too. That way it would be the common device-tree for U-Boot and Linux controlling the placement of the variables store.

>
>
>> The usage of efi_var_mem_ins() and efi_var_mem_del() when SetVariable() does not change anything is not flash-friendly. Michal, do you want to have a look at this area?
>
>That's known limitation describe in EFI_VARIABLE_SF_STORE Kconfig Note.

This could be a topic for future work. 

Best regards

Heinrich


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-16 11:39       ` Heinrich Schuchardt
@ 2026-02-16 11:43         ` Ilias Apalodimas
  2026-02-16 12:08         ` Ilias Apalodimas
  1 sibling, 0 replies; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-16 11:43 UTC (permalink / raw)
  To: Heinrich Schuchardt
  Cc: Michal Simek, Vincent Stehlé, Shantur Rathore,
	Neil Armstrong, Jonathan Humphreys, Simon Glass, Sughosh Ganu,
	Tom Rini, Ying-Chun Liu (PaulLiu), git, u-boot

[...]

> >>> +
> >>>   config EFI_MM_COMM_TEE
> >>>       bool "UEFI variables storage service via the trusted world"
> >>>       depends on OPTEE
> >>> @@ -153,7 +171,7 @@ endchoice
> >>>   config EFI_RT_VOLATILE_STORE
> >>>       bool "Allow variable runtime services in volatile storage (e.g RAM)"
> >>> -    depends on EFI_VARIABLE_FILE_STORE
> >>> +    depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE
> >>
> >> Hello Michal,
> >>
> >> If the backend store is SPI flash, we should not publish the variable "RTStorageVolatile" at runtime as currently defined.
> >>
> >> For the background see this commit for the efivar library:
> >>
> >> https://github.com/rhboot/efivar/commit/68daa04654acbe1bbaa17ebfc23c371b39e69c6b
> >>
> >> The first three patches look correct to me and I will add them to a merge request for efi-next.
> >
> >Do I read it that when I don't allow to select EFI_RT_VOLATILE_STORE you will be fine with the patch itself?
>
> This was my only concern.
>
> Maybe setting the file name to /dev/mtd/by-name/<partition name> would work with efivar. But I have not tested it.

I don't think it wiill. That variables describes the filename relative
to the ESP

>
> In U-Boot we could replace EFI_VARIABLE_SF_DEVICE_INDEX, SIZE, and OFFSET by a partition name, too. That way it would be the common device-tree for U-Boot and Linux controlling the placement of the variables store.
>
> >
> >
> >> The usage of efi_var_mem_ins() and efi_var_mem_del() when SetVariable() does not change anything is not flash-friendly. Michal, do you want to have a look at this area?
> >
> >That's known limitation describe in EFI_VARIABLE_SF_STORE Kconfig Note.
>
> This could be a topic for future work.
>
> Best regards

Cheers
/Ilias
>
> Heinrich
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-16 11:39       ` Heinrich Schuchardt
  2026-02-16 11:43         ` Ilias Apalodimas
@ 2026-02-16 12:08         ` Ilias Apalodimas
  2026-02-16 13:18           ` Michal Simek
  1 sibling, 1 reply; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-16 12:08 UTC (permalink / raw)
  To: Heinrich Schuchardt
  Cc: Michal Simek, Vincent Stehlé, Shantur Rathore,
	Neil Armstrong, Jonathan Humphreys, Simon Glass, Sughosh Ganu,
	Tom Rini, Ying-Chun Liu (PaulLiu), git, u-boot

On Mon, 16 Feb 2026 at 13:39, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> Am 16. Februar 2026 08:24:19 MEZ schrieb Michal Simek <michal.simek@amd.com>:
> >
> >
> >On 2/15/26 09:48, Heinrich Schuchardt wrote:
> >> On 2/11/26 16:56, Michal Simek wrote:
> >>> From: Shantur Rathore <i@shantur.com>
> >>>
> >>> Currently U-Boot uses ESP as storage for EFI variables.
> >>> Devices with SPI Flash are used for storing environment with this
> >>> commit we allow EFI variables to be stored on SPI Flash.
> >>>
> >>> https://github.com/rhboot/efivar
> >>> is not updated to support this location that's why you can mimic it by
> >>> running:
> >>> dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c \
> >>>     of=/tmp/vars skip=4 bs=1
> >>> flashcp /tmp/vars /dev/mtdX
> >>>
> >>> where mtdX should match location defined by
> >>> CONFIG_EFI_VARIABLE_SF_OFFSET/CONFIG_EFI_VAR_BUF_SIZE.
> >>>
> >>> Signed-off-by: Shantur Rathore <i@shantur.com>
> >>> Signed-off-by: Michal Simek <michal.simek@amd.com>
> >>> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC
> >>> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> >>>
> >>> ---
> >>>
> >>> Changes in v8:
> >>> - Add missing EFI_VARIABLE_SF_STORE dependency to EFI_VARIABLE_SF_DEVICE_INDEX
> >>>
> >>> Changes in v7:
> >>> - sed -i 's/efi_var_from/efi_var_from_storage/g'
> >>>
> >>> Changes in v6:
> >>> - sed -i 's/efi_var_read/efi_var_from/g'
> >>> - sed -i 's/efi_var_write/efi_var_to_storage/g'
> >>>
> >>> Changes in v4:
> >>> - Extend Kconfig description
> >>> - Extend commit message and describe efivar missing part
> >>> - use unify methods for reading/writing variable
> >>>
> >>> Changes in v3:
> >>> - Fixed compiler warnings.
> >>>
> >>> Changes in v2:
> >>> - Refactored efi_var_file to move common parts out as requested
> >>> - Changed ifdefs to use CONFIG_IS_DEFINED
> >>> - Fixed typos
> >>>
> >>>   lib/efi_loader/Kconfig      | 35 +++++++++++++-
> >>>   lib/efi_loader/Makefile     |  1 +
> >>>   lib/efi_loader/efi_var_sf.c | 92 +++++++++++++++++++++++++++++++++++++
> >>>   3 files changed, 127 insertions(+), 1 deletion(-)
> >>>   create mode 100644 lib/efi_loader/efi_var_sf.c
> >>>
> >>> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> >>> index 579eed658801..0f6f927ddaf1 100644
> >>> --- a/lib/efi_loader/Kconfig
> >>> +++ b/lib/efi_loader/Kconfig
> >>> @@ -124,6 +124,24 @@ config EFI_VARIABLE_FILE_STORE
> >>>         Select this option if you want non-volatile UEFI variables to be
> >>>         stored as file /ubootefi.var on the EFI system partition.
> >>> +config EFI_VARIABLE_SF_STORE
> >>> +    bool "Store non-volatile UEFI variables in SPI Flash"
> >>> +    depends on SPI_FLASH
> >>> +    help
> >>> +      Select this option if you want non-volatile UEFI variables to be
> >>> +      stored in SPI Flash.
> >>> +
> >>> +      Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
> >>> +      the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
> >>> +      needed.
> >>> +
> >>> +      Note that SPI Flash devices have a limited number of program/erase
> >>> +      cycles. Frequent updates to UEFI variables may cause excessive wear
> >>> +      and can permanently damage the flash device, particularly on SPI NAND
> >>> +      or low-end SPI NOR parts without wear leveling. This option should be
> >>> +      used with care on such systems, and is not recommended for platforms
> >>> +      where UEFI variables are updated frequently.
> >>> +
> >>>   config EFI_MM_COMM_TEE
> >>>       bool "UEFI variables storage service via the trusted world"
> >>>       depends on OPTEE
> >>> @@ -153,7 +171,7 @@ endchoice
> >>>   config EFI_RT_VOLATILE_STORE
> >>>       bool "Allow variable runtime services in volatile storage (e.g RAM)"
> >>> -    depends on EFI_VARIABLE_FILE_STORE
> >>> +    depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE
> >>
> >> Hello Michal,
> >>
> >> If the backend store is SPI flash, we should not publish the variable "RTStorageVolatile" at runtime as currently defined.
> >>
> >> For the background see this commit for the efivar library:
> >>
> >> https://github.com/rhboot/efivar/commit/68daa04654acbe1bbaa17ebfc23c371b39e69c6b
> >>
> >> The first three patches look correct to me and I will add them to a merge request for efi-next.
> >
> >Do I read it that when I don't allow to select EFI_RT_VOLATILE_STORE you will be fine with the patch itself?
>
> This was my only concern.

Thinking about it again, this is the right thing to do right now.
efivar will try to create a file in the ESP if the speacial variables
in linux are found. So we are better off disabling this option for SPI
variables atm

Cheers
/Ilias
>
> Maybe setting the file name to /dev/mtd/by-name/<partition name> would work with efivar. But I have not tested it.
>
> In U-Boot we could replace EFI_VARIABLE_SF_DEVICE_INDEX, SIZE, and OFFSET by a partition name, too. That way it would be the common device-tree for U-Boot and Linux controlling the placement of the variables store.
>
> >
> >
> >> The usage of efi_var_mem_ins() and efi_var_mem_del() when SetVariable() does not change anything is not flash-friendly. Michal, do you want to have a look at this area?
> >
> >That's known limitation describe in EFI_VARIABLE_SF_STORE Kconfig Note.
>
> This could be a topic for future work.
>
> Best regards
>
> Heinrich
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 4/4] efi_vars: Implement SPI Flash store
  2026-02-16 12:08         ` Ilias Apalodimas
@ 2026-02-16 13:18           ` Michal Simek
  0 siblings, 0 replies; 15+ messages in thread
From: Michal Simek @ 2026-02-16 13:18 UTC (permalink / raw)
  To: Ilias Apalodimas, Heinrich Schuchardt
  Cc: Vincent Stehlé, Shantur Rathore, Neil Armstrong,
	Jonathan Humphreys, Simon Glass, Sughosh Ganu, Tom Rini,
	Ying-Chun Liu (PaulLiu), git, u-boot



On 2/16/26 13:08, Ilias Apalodimas wrote:
> On Mon, 16 Feb 2026 at 13:39, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>>
>> Am 16. Februar 2026 08:24:19 MEZ schrieb Michal Simek <michal.simek@amd.com>:
>>>
>>>
>>> On 2/15/26 09:48, Heinrich Schuchardt wrote:
>>>> On 2/11/26 16:56, Michal Simek wrote:
>>>>> From: Shantur Rathore <i@shantur.com>
>>>>>
>>>>> Currently U-Boot uses ESP as storage for EFI variables.
>>>>> Devices with SPI Flash are used for storing environment with this
>>>>> commit we allow EFI variables to be stored on SPI Flash.
>>>>>
>>>>> https://github.com/rhboot/efivar
>>>>> is not updated to support this location that's why you can mimic it by
>>>>> running:
>>>>> dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c \
>>>>>      of=/tmp/vars skip=4 bs=1
>>>>> flashcp /tmp/vars /dev/mtdX
>>>>>
>>>>> where mtdX should match location defined by
>>>>> CONFIG_EFI_VARIABLE_SF_OFFSET/CONFIG_EFI_VAR_BUF_SIZE.
>>>>>
>>>>> Signed-off-by: Shantur Rathore <i@shantur.com>
>>>>> Signed-off-by: Michal Simek <michal.simek@amd.com>
>>>>> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905D3-CC
>>>>> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
>>>>>
>>>>> ---
>>>>>
>>>>> Changes in v8:
>>>>> - Add missing EFI_VARIABLE_SF_STORE dependency to EFI_VARIABLE_SF_DEVICE_INDEX
>>>>>
>>>>> Changes in v7:
>>>>> - sed -i 's/efi_var_from/efi_var_from_storage/g'
>>>>>
>>>>> Changes in v6:
>>>>> - sed -i 's/efi_var_read/efi_var_from/g'
>>>>> - sed -i 's/efi_var_write/efi_var_to_storage/g'
>>>>>
>>>>> Changes in v4:
>>>>> - Extend Kconfig description
>>>>> - Extend commit message and describe efivar missing part
>>>>> - use unify methods for reading/writing variable
>>>>>
>>>>> Changes in v3:
>>>>> - Fixed compiler warnings.
>>>>>
>>>>> Changes in v2:
>>>>> - Refactored efi_var_file to move common parts out as requested
>>>>> - Changed ifdefs to use CONFIG_IS_DEFINED
>>>>> - Fixed typos
>>>>>
>>>>>    lib/efi_loader/Kconfig      | 35 +++++++++++++-
>>>>>    lib/efi_loader/Makefile     |  1 +
>>>>>    lib/efi_loader/efi_var_sf.c | 92 +++++++++++++++++++++++++++++++++++++
>>>>>    3 files changed, 127 insertions(+), 1 deletion(-)
>>>>>    create mode 100644 lib/efi_loader/efi_var_sf.c
>>>>>
>>>>> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
>>>>> index 579eed658801..0f6f927ddaf1 100644
>>>>> --- a/lib/efi_loader/Kconfig
>>>>> +++ b/lib/efi_loader/Kconfig
>>>>> @@ -124,6 +124,24 @@ config EFI_VARIABLE_FILE_STORE
>>>>>          Select this option if you want non-volatile UEFI variables to be
>>>>>          stored as file /ubootefi.var on the EFI system partition.
>>>>> +config EFI_VARIABLE_SF_STORE
>>>>> +    bool "Store non-volatile UEFI variables in SPI Flash"
>>>>> +    depends on SPI_FLASH
>>>>> +    help
>>>>> +      Select this option if you want non-volatile UEFI variables to be
>>>>> +      stored in SPI Flash.
>>>>> +
>>>>> +      Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
>>>>> +      the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
>>>>> +      needed.
>>>>> +
>>>>> +      Note that SPI Flash devices have a limited number of program/erase
>>>>> +      cycles. Frequent updates to UEFI variables may cause excessive wear
>>>>> +      and can permanently damage the flash device, particularly on SPI NAND
>>>>> +      or low-end SPI NOR parts without wear leveling. This option should be
>>>>> +      used with care on such systems, and is not recommended for platforms
>>>>> +      where UEFI variables are updated frequently.
>>>>> +
>>>>>    config EFI_MM_COMM_TEE
>>>>>        bool "UEFI variables storage service via the trusted world"
>>>>>        depends on OPTEE
>>>>> @@ -153,7 +171,7 @@ endchoice
>>>>>    config EFI_RT_VOLATILE_STORE
>>>>>        bool "Allow variable runtime services in volatile storage (e.g RAM)"
>>>>> -    depends on EFI_VARIABLE_FILE_STORE
>>>>> +    depends on EFI_VARIABLE_FILE_STORE || EFI_VARIABLE_SF_STORE
>>>>
>>>> Hello Michal,
>>>>
>>>> If the backend store is SPI flash, we should not publish the variable "RTStorageVolatile" at runtime as currently defined.
>>>>
>>>> For the background see this commit for the efivar library:
>>>>
>>>> https://github.com/rhboot/efivar/commit/68daa04654acbe1bbaa17ebfc23c371b39e69c6b
>>>>
>>>> The first three patches look correct to me and I will add them to a merge request for efi-next.
>>>
>>> Do I read it that when I don't allow to select EFI_RT_VOLATILE_STORE you will be fine with the patch itself?
>>
>> This was my only concern.
> 
> Thinking about it again, this is the right thing to do right now.
> efivar will try to create a file in the ESP if the speacial variables
> in linux are found. So we are better off disabling this option for SPI
> variables atm

I have sent v9 with removing EFI_RT_VOLATILE_STORE and we can deal with efivar 
separately.

M

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-02-16 13:18 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-11 15:56 [PATCH v8 0/4] efi_vars: Implement SPI Flash storage for EFI Michal Simek
2026-02-11 15:56 ` [PATCH v8 1/4] efi_var_file: refactor to move buffer functions Michal Simek
2026-02-12  6:14   ` Ilias Apalodimas
2026-02-11 15:56 ` [PATCH v8 2/4] efi_var: Unify read/write access helper function Michal Simek
2026-02-11 15:56 ` [PATCH v8 3/4] efi_loader: Setup default location for UEFI Variables storing Michal Simek
2026-02-11 20:40   ` Ilias Apalodimas
2026-02-11 15:56 ` [PATCH v8 4/4] efi_vars: Implement SPI Flash store Michal Simek
2026-02-15  8:48   ` Heinrich Schuchardt
2026-02-15 21:55     ` Heinrich Schuchardt
2026-02-16  7:24     ` Michal Simek
2026-02-16 11:39       ` Heinrich Schuchardt
2026-02-16 11:43         ` Ilias Apalodimas
2026-02-16 12:08         ` Ilias Apalodimas
2026-02-16 13:18           ` Michal Simek
2026-02-16  7:24     ` Ilias Apalodimas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox