mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 0/4] i.mx: hab/ocotop: extend field return to i.MX6
@ 2025-12-19  9:06 Fabian Pflug
  2025-12-19  9:06 ` [PATCH v2 1/4] arm: mach-imx6: use kconfig for field return Fabian Pflug
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Fabian Pflug @ 2025-12-19  9:06 UTC (permalink / raw)
  To: Marco Felsch, BAREBOX; +Cc: Fabian Pflug

Field return handling was only implemented for the i.MX8* processors.
Extend this with support for i.MX6 and extend the hab command with an
option to burn the field return fuse in case the field return sticky bit
might be unlocked.

Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
Changes in v2:
- Added reviewed-by
- Added imx6_hab_field_return_ocotp and reintroduced the
  imx8m_hab_field_return_ocotp, but also add a new helperfunction for
  both to call.
- Implemented Marcos changes for commands/hab.c, but changed
  indentation.
- Link to v1: https://lore.kernel.org/r/20251218-v2025-11-0-topic-imx6-field-return-v1-0-3781143198d6@pengutronix.de

---
Fabian Pflug (4):
      arm: mach-imx6: use kconfig for field return
      nvmem: ocotp: extend support to query the sticky bit
      i.MX: HAB: extend field_return support to imx6
      commands: hab: extend by field_return fuse burn

 arch/arm/mach-imx/Kconfig                     |  6 +++++-
 commands/hab.c                                | 24 ++++++++++++++++++++----
 drivers/hab/hab.c                             | 22 +++++++++++++++-------
 drivers/nvmem/ocotp.c                         | 12 ++++++++----
 include/mach/imx/habv4-imx6-gencsf-template.h | 11 +++--------
 include/mach/imx/ocotp-fusemap.h              |  1 +
 6 files changed, 52 insertions(+), 24 deletions(-)
---
base-commit: d6f0974673c0e3da00f8d0789d6302a43f3e478d
change-id: 20251218-v2025-11-0-topic-imx6-field-return-d3b4f2e55afb

Best regards,
-- 
Fabian Pflug <f.pflug@pengutronix.de>




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

* [PATCH v2 1/4] arm: mach-imx6: use kconfig for field return
  2025-12-19  9:06 [PATCH v2 0/4] i.mx: hab/ocotop: extend field return to i.MX6 Fabian Pflug
@ 2025-12-19  9:06 ` Fabian Pflug
  2025-12-19  9:14   ` Ahmad Fatoum
  2025-12-19  9:06 ` [PATCH v2 2/4] nvmem: ocotp: extend support to query the sticky bit Fabian Pflug
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Fabian Pflug @ 2025-12-19  9:06 UTC (permalink / raw)
  To: Marco Felsch, BAREBOX; +Cc: Fabian Pflug

There is a Kconfig option for the field return, that is also documented,
so using it here instead of providing a headerfile to patch.

Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
 include/mach/imx/habv4-imx6-gencsf-template.h | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/include/mach/imx/habv4-imx6-gencsf-template.h b/include/mach/imx/habv4-imx6-gencsf-template.h
index 45da2981cb..c24bf84b85 100644
--- a/include/mach/imx/habv4-imx6-gencsf-template.h
+++ b/include/mach/imx/habv4-imx6-gencsf-template.h
@@ -39,17 +39,12 @@ hab Engine = SETUP_HABV4_ENGINE
 hab Features = SETUP_HABV4_FEATURES
 #endif
 
-/*
-// allow fusing FIELD_RETURN
-// # ocotp0.permanent_write_enable=1
-// # mw -l -d /dev/imx-ocotp 0xb8 0x1
+#if defined(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN)
 hab [Unlock]
 hab Engine = OCOTP
 hab Features = FIELD RETURN
-// device-specific UID:
-// $ dd if=/sys/bus/nvmem/devices/imx-ocotp0/nvmem bs=4 skip=1 count=2 status=none | hexdump -ve '1/1 "0x%.2x, "' | sed 's/, $//'
-hab UID = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
-*/
+hab UID = HABV4_CSF_UNLOCK_UID
+#endif
 
 hab [Install Key]
 /* verification key index in key store (0, 2...4) */

-- 
2.47.3




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

* [PATCH v2 2/4] nvmem: ocotp: extend support to query the sticky bit
  2025-12-19  9:06 [PATCH v2 0/4] i.mx: hab/ocotop: extend field return to i.MX6 Fabian Pflug
  2025-12-19  9:06 ` [PATCH v2 1/4] arm: mach-imx6: use kconfig for field return Fabian Pflug
@ 2025-12-19  9:06 ` Fabian Pflug
  2025-12-19  9:06 ` [PATCH v2 3/4] i.MX: HAB: extend field_return support to imx6 Fabian Pflug
  2025-12-19  9:06 ` [PATCH v2 4/4] commands: hab: extend by field_return fuse burn Fabian Pflug
  3 siblings, 0 replies; 10+ messages in thread
From: Fabian Pflug @ 2025-12-19  9:06 UTC (permalink / raw)
  To: Marco Felsch, BAREBOX; +Cc: Fabian Pflug

The i.MX* devices do have an sticky bit which indicates if the
field-return fuse can be written. Before only support for i.MX8* was
provided. Extend this for the i.MX6* series.

Since i.MX8 and i.MX6 share the same code, rename
imx8m_field_return_locked to imx_field_return_locked to not confuse the
user.

Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
 drivers/nvmem/ocotp.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/nvmem/ocotp.c b/drivers/nvmem/ocotp.c
index 7bca275404..1f74fddb60 100644
--- a/drivers/nvmem/ocotp.c
+++ b/drivers/nvmem/ocotp.c
@@ -294,7 +294,7 @@ static void imx8m_lock_srk_revoke(struct ocotp_priv *priv)
 	writel(val, priv->base + OCOTP_SW_STICKY);
 }
 
-static bool imx8m_field_return_locked(struct ocotp_priv *priv)
+static bool imx_field_return_locked(struct ocotp_priv *priv)
 {
 	return readl(priv->base + OCOTP_SW_STICKY) & OCOTP_SW_STICKY_FIELD_RETURN_LOCK;
 }
@@ -990,6 +990,7 @@ static struct imx_ocotp_data imx6q_ocotp_data = {
 	.fuse_blow = imx6_fuse_blow_addr,
 	.fuse_read = imx6_fuse_read_addr,
 	.ctrl = &ocotp_ctrl_reg_default,
+	.field_return_locked = imx_field_return_locked,
 };
 
 static struct imx_ocotp_data imx6sl_ocotp_data = {
@@ -1002,6 +1003,7 @@ static struct imx_ocotp_data imx6sl_ocotp_data = {
 	.fuse_blow = imx6_fuse_blow_addr,
 	.fuse_read = imx6_fuse_read_addr,
 	.ctrl = &ocotp_ctrl_reg_default,
+	.field_return_locked = imx_field_return_locked,
 };
 
 static struct imx_ocotp_data imx6ul_ocotp_data = {
@@ -1014,6 +1016,7 @@ static struct imx_ocotp_data imx6ul_ocotp_data = {
 	.fuse_blow = imx6_fuse_blow_addr,
 	.fuse_read = imx6_fuse_read_addr,
 	.ctrl = &ocotp_ctrl_reg_default,
+	.field_return_locked = imx_field_return_locked,
 };
 
 static struct imx_ocotp_data imx6ull_ocotp_data = {
@@ -1026,6 +1029,7 @@ static struct imx_ocotp_data imx6ull_ocotp_data = {
 	.fuse_blow = imx6_fuse_blow_addr,
 	.fuse_read = imx6_fuse_read_addr,
 	.ctrl = &ocotp_ctrl_reg_default,
+	.field_return_locked = imx_field_return_locked,
 };
 
 static struct imx_ocotp_data vf610_ocotp_data = {
@@ -1063,7 +1067,7 @@ static struct imx_ocotp_data imx8mp_ocotp_data = {
 	.fuse_read = imx6_fuse_read_addr,
 	.srk_revoke_locked = imx8m_srk_revoke_locked,
 	.lock_srk_revoke = imx8m_lock_srk_revoke,
-	.field_return_locked = imx8m_field_return_locked,
+	.field_return_locked = imx_field_return_locked,
 	.ctrl = &ocotp_ctrl_reg_8mp,
 };
 
@@ -1095,7 +1099,7 @@ static struct imx_ocotp_data imx8mm_ocotp_data = {
 	.fuse_read = imx6_fuse_read_addr,
 	.srk_revoke_locked = imx8m_srk_revoke_locked,
 	.lock_srk_revoke = imx8m_lock_srk_revoke,
-	.field_return_locked = imx8m_field_return_locked,
+	.field_return_locked = imx_field_return_locked,
 	.feat = &imx8mm_featctrl_data,
 	.ctrl = &ocotp_ctrl_reg_default,
 };
@@ -1116,7 +1120,7 @@ static struct imx_ocotp_data imx8mn_ocotp_data = {
 	.fuse_read = imx6_fuse_read_addr,
 	.srk_revoke_locked = imx8m_srk_revoke_locked,
 	.lock_srk_revoke = imx8m_lock_srk_revoke,
-	.field_return_locked = imx8m_field_return_locked,
+	.field_return_locked = imx_field_return_locked,
 	.feat = &imx8mn_featctrl_data,
 	.ctrl = &ocotp_ctrl_reg_default,
 };

-- 
2.47.3




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

* [PATCH v2 3/4] i.MX: HAB: extend field_return support to imx6
  2025-12-19  9:06 [PATCH v2 0/4] i.mx: hab/ocotop: extend field return to i.MX6 Fabian Pflug
  2025-12-19  9:06 ` [PATCH v2 1/4] arm: mach-imx6: use kconfig for field return Fabian Pflug
  2025-12-19  9:06 ` [PATCH v2 2/4] nvmem: ocotp: extend support to query the sticky bit Fabian Pflug
@ 2025-12-19  9:06 ` Fabian Pflug
  2025-12-19  9:56   ` Marco Felsch
  2025-12-19  9:06 ` [PATCH v2 4/4] commands: hab: extend by field_return fuse burn Fabian Pflug
  3 siblings, 1 reply; 10+ messages in thread
From: Fabian Pflug @ 2025-12-19  9:06 UTC (permalink / raw)
  To: Marco Felsch, BAREBOX; +Cc: Fabian Pflug

Extend the helper for imx_fuse_burn with support for i.MX6 devices.
Create a helper function for i.MX8 and i.MX6 rom the old i.MX8M
function, as they all share the same pattern.

Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
 drivers/hab/hab.c                | 22 +++++++++++++++-------
 include/mach/imx/ocotp-fusemap.h |  1 +
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/hab/hab.c b/drivers/hab/hab.c
index 1c747e8a3e..3c9739871b 100644
--- a/drivers/hab/hab.c
+++ b/drivers/hab/hab.c
@@ -262,7 +262,7 @@ static int imx8m_hab_revoke_key_ocotp(unsigned key_idx)
  */
 #define MX8MP_FIELD_RETURN_PATTERN	0x28001401
 
-static int imx8m_hab_field_return_ocotp(void)
+static int imx_hab_field_return_ocotp(unint32_t field, unsigned int value)
 {
 	int ret;
 
@@ -274,13 +274,20 @@ static int imx8m_hab_field_return_ocotp(void)
 	if (ret == 1)
 		return -EINVAL;
 
-	if (cpu_is_mx8mp())
-		ret = imx_ocotp_write_field(MX8MP_OCOTP_FIELD_RETURN,
-					    MX8MP_FIELD_RETURN_PATTERN);
-	else
-		ret = imx_ocotp_write_field(MX8M_OCOTP_FIELD_RETURN, 1);
+	return imx_ocotp_write_field(field, value);
+}
 
-	return ret;
+static int imx6_hab_field_return_ocotp(void)
+{
+	return imx_hab_field_return_ocotp(MX6_OCOTP_FIELD_RETURN, 1);
+}
+
+static int imx8m_hab_field_return_ocotp(void)
+{
+	if (cpu_is_mx8mp())
+		return imx_hab_field_return_ocotp(MX8MP_OCOTP_FIELD_RETURN,
+						  MX8MP_FIELD_RETURN_PATTERN);
+	return imx_hab_field_return_ocotp(MX8M_OCOTP_FIELD_RETURN, 1);
 }
 
 struct imx_hab_ops {
@@ -310,6 +317,7 @@ static struct imx_hab_ops imx6_hab_ops_ocotp = {
 	.device_locked_down = imx6_hab_device_locked_down_ocotp,
 	.permanent_write_enable = imx_hab_permanent_write_enable_ocotp,
 	.print_status = imx6_hab_print_status,
+	.field_return = imx6_hab_field_return_ocotp,
 };
 
 static struct imx_hab_ops imx8m_hab_ops_ocotp = {
diff --git a/include/mach/imx/ocotp-fusemap.h b/include/mach/imx/ocotp-fusemap.h
index ae10dcef2a..3fd9d6df24 100644
--- a/include/mach/imx/ocotp-fusemap.h
+++ b/include/mach/imx/ocotp-fusemap.h
@@ -103,6 +103,7 @@
 #define MX8M_OCOTP_TZASC_EN		(OCOTP_WORD(0x480) | OCOTP_BIT(11) | OCOTP_WIDTH(1))
 #define MX8MP_OCOTP_ROM_NO_LOG		(OCOTP_WORD(0x480) | OCOTP_BIT(22) | OCOTP_WIDTH(1))
 #define MX8M_OCOTP_RECOVERY_SDMMC_BOOT_DIS	(OCOTP_WORD(0x490) | OCOTP_BIT(23) | OCOTP_WIDTH(1))
+#define MX6_OCOTP_FIELD_RETURN		(OCOTP_WORD(0x6E0) | OCOTP_BIT(0) | OCOTP_WIDTH(1))
 #define MX8M_OCOTP_FIELD_RETURN		(OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(1))
 #define MX8MP_OCOTP_FIELD_RETURN	(OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
 #define MX8M_OCOTP_SRK_REVOKE		(OCOTP_WORD(0x670) | OCOTP_BIT(0) | OCOTP_WIDTH(4))

-- 
2.47.3




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

* [PATCH v2 4/4] commands: hab: extend by field_return fuse burn
  2025-12-19  9:06 [PATCH v2 0/4] i.mx: hab/ocotop: extend field return to i.MX6 Fabian Pflug
                   ` (2 preceding siblings ...)
  2025-12-19  9:06 ` [PATCH v2 3/4] i.MX: HAB: extend field_return support to imx6 Fabian Pflug
@ 2025-12-19  9:06 ` Fabian Pflug
  2025-12-19  9:57   ` Marco Felsch
  2025-12-19 10:03   ` Lucas Stach
  3 siblings, 2 replies; 10+ messages in thread
From: Fabian Pflug @ 2025-12-19  9:06 UTC (permalink / raw)
  To: Marco Felsch, BAREBOX; +Cc: Fabian Pflug

Extend hab command with an additional parameter to burn the field return
fuse.
Since there is now a convenient way to burn the field return fuse, give
a hint at the Kconfig option about this, as it already describes what to
do in order to burn the fuse to make it complete.

Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig |  6 +++++-
 commands/hab.c            | 24 ++++++++++++++++++++----
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 5f50d1a823..5fea0bbbca 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -926,13 +926,17 @@ config HABV4_CSF_UNLOCK_UID
           feature. This value must match the per device UNIQUE_ID fuses.
 
 	  The below example shows the expected format. The UNIQUE_ID is
-	  queried by Linux via:
+	  printed during boot by barebox:
+	    i.MX___ unique ID: 7766554433221100
+	  or it can be queried by Linux via:
             - cat /sys/devices/soc0/serial_number
 	      7766554433221100
 
 	  So this value have to be set:
 	    - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
 
+	  Afterwards, the `hab -p -r` command can be used to burn the fuse.
+
 config HABV4_IMG_CRT_PEM
 	string "Path to IMG certificate"
 	default "../crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
diff --git a/commands/hab.c b/commands/hab.c
index 8ae943a4c8..1e168af4b9 100644
--- a/commands/hab.c
+++ b/commands/hab.c
@@ -16,9 +16,9 @@ static int do_hab(int argc, char *argv[])
 	char *srkhashfile = NULL, *srkhash = NULL;
 	unsigned flags = 0;
 	u8 srk[SRK_HASH_SIZE];
-	int lockdown = 0, info = 0;
+	int lockdown = 0, info = 0, field_return = 0;
 
-	while ((opt = getopt(argc, argv, "s:fpx:li")) > 0) {
+	while ((opt = getopt(argc, argv, "s:fpx:lir")) > 0) {
 		switch (opt) {
 		case 's':
 			srkhashfile = optarg;
@@ -38,12 +38,15 @@ static int do_hab(int argc, char *argv[])
 		case 'i':
 			info = 1;
 			break;
+		case 'r':
+			field_return = 1;
+			break;
 		default:
 			return COMMAND_ERROR_USAGE;
 		}
 	}
 
-	if (!info && !lockdown && !srkhashfile && !srkhash) {
+	if (!info && !lockdown && !srkhashfile && !srkhash && !field_return) {
 		printf("Nothing to do\n");
 		return COMMAND_ERROR_USAGE;
 	}
@@ -94,7 +97,19 @@ static int do_hab(int argc, char *argv[])
 		printf("Device successfully locked down\n");
 	}
 
-	return 0;
+	if (field_return) {
+		ret = imx_hab_field_return(flags & IMX_SRK_HASH_WRITE_PERMANENT);
+		if (ret == -EINVAL && IS_ENABLED(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN))
+			printf("Field-return burn failed, check HABV4_CSF_UNLOCK_UID!\n");
+		else if (ret == -EINVAL && !IS_ENABLED(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN))
+			printf("Field-return burn failed because CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN=n\n");
+		else if (ret)
+			printf("Field-return burn failed\n");
+		else
+			printf("Field return fuse successfully burnt\n");
+	}
+
+	return ret;
 }
 
 BAREBOX_CMD_HELP_START(hab)
@@ -105,6 +120,7 @@ BAREBOX_CMD_HELP_OPT ("-x <sha256>",  "Burn Super Root Key hash from hex string"
 BAREBOX_CMD_HELP_OPT ("-i",  "Print HAB info")
 BAREBOX_CMD_HELP_OPT ("-f",  "Force. Write even when a key is already written")
 BAREBOX_CMD_HELP_OPT ("-l",  "Lockdown device. Dangerous! After executing only signed images can be booted")
+BAREBOX_CMD_HELP_OPT ("-r",  "Field Return. Dangerous! After executing signed images are disabled forever.")
 BAREBOX_CMD_HELP_OPT ("-p",  "Permanent. Really burn fuses. Be careful!")
 BAREBOX_CMD_HELP_END
 

-- 
2.47.3




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

* Re: [PATCH v2 1/4] arm: mach-imx6: use kconfig for field return
  2025-12-19  9:06 ` [PATCH v2 1/4] arm: mach-imx6: use kconfig for field return Fabian Pflug
@ 2025-12-19  9:14   ` Ahmad Fatoum
  2025-12-19 10:06     ` Marco Felsch
  0 siblings, 1 reply; 10+ messages in thread
From: Ahmad Fatoum @ 2025-12-19  9:14 UTC (permalink / raw)
  To: Fabian Pflug, Marco Felsch, BAREBOX

Hi,

On 12/19/25 10:06 AM, Fabian Pflug wrote:
> There is a Kconfig option for the field return, that is also documented,
> so using it here instead of providing a headerfile to patch.
> 
> Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
> Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
> ---
>  include/mach/imx/habv4-imx6-gencsf-template.h | 11 +++--------
>  1 file changed, 3 insertions(+), 8 deletions(-)
> 
> diff --git a/include/mach/imx/habv4-imx6-gencsf-template.h b/include/mach/imx/habv4-imx6-gencsf-template.h
> index 45da2981cb..c24bf84b85 100644
> --- a/include/mach/imx/habv4-imx6-gencsf-template.h
> +++ b/include/mach/imx/habv4-imx6-gencsf-template.h
> @@ -39,17 +39,12 @@ hab Engine = SETUP_HABV4_ENGINE
>  hab Features = SETUP_HABV4_FEATURES
>  #endif
>  
> -/*
> -// allow fusing FIELD_RETURN
> -// # ocotp0.permanent_write_enable=1
> -// # mw -l -d /dev/imx-ocotp 0xb8 0x1
> +#if defined(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN)
>  hab [Unlock]
>  hab Engine = OCOTP
>  hab Features = FIELD RETURN
> -// device-specific UID:
> -// $ dd if=/sys/bus/nvmem/devices/imx-ocotp0/nvmem bs=4 skip=1 count=2 status=none | hexdump -ve '1/1 "0x%.2x, "' | sed 's/, $//'
> -hab UID = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
> -*/
> +hab UID = HABV4_CSF_UNLOCK_UID

How can this work without a CONFIG_ in front of the option?

Thanks,
Ahmad

> +#endif
>  
>  hab [Install Key]
>  /* verification key index in key store (0, 2...4) */
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




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

* Re: [PATCH v2 3/4] i.MX: HAB: extend field_return support to imx6
  2025-12-19  9:06 ` [PATCH v2 3/4] i.MX: HAB: extend field_return support to imx6 Fabian Pflug
@ 2025-12-19  9:56   ` Marco Felsch
  0 siblings, 0 replies; 10+ messages in thread
From: Marco Felsch @ 2025-12-19  9:56 UTC (permalink / raw)
  To: Fabian Pflug; +Cc: BAREBOX

On 25-12-19, Fabian Pflug wrote:
> Extend the helper for imx_fuse_burn with support for i.MX6 devices.
> Create a helper function for i.MX8 and i.MX6 rom the old i.MX8M
> function, as they all share the same pattern.
> 
> Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
> ---
>  drivers/hab/hab.c                | 22 +++++++++++++++-------
>  include/mach/imx/ocotp-fusemap.h |  1 +
>  2 files changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/hab/hab.c b/drivers/hab/hab.c
> index 1c747e8a3e..3c9739871b 100644
> --- a/drivers/hab/hab.c
> +++ b/drivers/hab/hab.c
> @@ -262,7 +262,7 @@ static int imx8m_hab_revoke_key_ocotp(unsigned key_idx)
>   */
>  #define MX8MP_FIELD_RETURN_PATTERN	0x28001401

Nit: I would like to keep this define close to the
imx8m_hab_field_return_ocotp().

Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>


> -static int imx8m_hab_field_return_ocotp(void)
> +static int imx_hab_field_return_ocotp(unint32_t field, unsigned int value)
>  {
>  	int ret;
>  
> @@ -274,13 +274,20 @@ static int imx8m_hab_field_return_ocotp(void)
>  	if (ret == 1)
>  		return -EINVAL;
>  
> -	if (cpu_is_mx8mp())
> -		ret = imx_ocotp_write_field(MX8MP_OCOTP_FIELD_RETURN,
> -					    MX8MP_FIELD_RETURN_PATTERN);
> -	else
> -		ret = imx_ocotp_write_field(MX8M_OCOTP_FIELD_RETURN, 1);
> +	return imx_ocotp_write_field(field, value);
> +}
>  
> -	return ret;
> +static int imx6_hab_field_return_ocotp(void)
> +{
> +	return imx_hab_field_return_ocotp(MX6_OCOTP_FIELD_RETURN, 1);
> +}
> +
> +static int imx8m_hab_field_return_ocotp(void)
> +{
> +	if (cpu_is_mx8mp())
> +		return imx_hab_field_return_ocotp(MX8MP_OCOTP_FIELD_RETURN,
> +						  MX8MP_FIELD_RETURN_PATTERN);
> +	return imx_hab_field_return_ocotp(MX8M_OCOTP_FIELD_RETURN, 1);
>  }
>  
>  struct imx_hab_ops {
> @@ -310,6 +317,7 @@ static struct imx_hab_ops imx6_hab_ops_ocotp = {
>  	.device_locked_down = imx6_hab_device_locked_down_ocotp,
>  	.permanent_write_enable = imx_hab_permanent_write_enable_ocotp,
>  	.print_status = imx6_hab_print_status,
> +	.field_return = imx6_hab_field_return_ocotp,
>  };
>  
>  static struct imx_hab_ops imx8m_hab_ops_ocotp = {
> diff --git a/include/mach/imx/ocotp-fusemap.h b/include/mach/imx/ocotp-fusemap.h
> index ae10dcef2a..3fd9d6df24 100644
> --- a/include/mach/imx/ocotp-fusemap.h
> +++ b/include/mach/imx/ocotp-fusemap.h
> @@ -103,6 +103,7 @@
>  #define MX8M_OCOTP_TZASC_EN		(OCOTP_WORD(0x480) | OCOTP_BIT(11) | OCOTP_WIDTH(1))
>  #define MX8MP_OCOTP_ROM_NO_LOG		(OCOTP_WORD(0x480) | OCOTP_BIT(22) | OCOTP_WIDTH(1))
>  #define MX8M_OCOTP_RECOVERY_SDMMC_BOOT_DIS	(OCOTP_WORD(0x490) | OCOTP_BIT(23) | OCOTP_WIDTH(1))
> +#define MX6_OCOTP_FIELD_RETURN		(OCOTP_WORD(0x6E0) | OCOTP_BIT(0) | OCOTP_WIDTH(1))
>  #define MX8M_OCOTP_FIELD_RETURN		(OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(1))
>  #define MX8MP_OCOTP_FIELD_RETURN	(OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
>  #define MX8M_OCOTP_SRK_REVOKE		(OCOTP_WORD(0x670) | OCOTP_BIT(0) | OCOTP_WIDTH(4))
> 
> -- 
> 2.47.3
> 
> 

-- 
#gernperDu 
#CallMeByMyFirstName

Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | https://www.pengutronix.de/ |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-9    |



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

* Re: [PATCH v2 4/4] commands: hab: extend by field_return fuse burn
  2025-12-19  9:06 ` [PATCH v2 4/4] commands: hab: extend by field_return fuse burn Fabian Pflug
@ 2025-12-19  9:57   ` Marco Felsch
  2025-12-19 10:03   ` Lucas Stach
  1 sibling, 0 replies; 10+ messages in thread
From: Marco Felsch @ 2025-12-19  9:57 UTC (permalink / raw)
  To: Fabian Pflug; +Cc: BAREBOX

On 25-12-19, Fabian Pflug wrote:
> Extend hab command with an additional parameter to burn the field return
> fuse.
> Since there is now a convenient way to burn the field return fuse, give
> a hint at the Kconfig option about this, as it already describes what to
> do in order to burn the fuse to make it complete.
> 
> Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>

Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>

> ---
>  arch/arm/mach-imx/Kconfig |  6 +++++-
>  commands/hab.c            | 24 ++++++++++++++++++++----
>  2 files changed, 25 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 5f50d1a823..5fea0bbbca 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -926,13 +926,17 @@ config HABV4_CSF_UNLOCK_UID
>            feature. This value must match the per device UNIQUE_ID fuses.
>  
>  	  The below example shows the expected format. The UNIQUE_ID is
> -	  queried by Linux via:
> +	  printed during boot by barebox:
> +	    i.MX___ unique ID: 7766554433221100
> +	  or it can be queried by Linux via:
>              - cat /sys/devices/soc0/serial_number
>  	      7766554433221100
>  
>  	  So this value have to be set:
>  	    - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
>  
> +	  Afterwards, the `hab -p -r` command can be used to burn the fuse.
> +
>  config HABV4_IMG_CRT_PEM
>  	string "Path to IMG certificate"
>  	default "../crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
> diff --git a/commands/hab.c b/commands/hab.c
> index 8ae943a4c8..1e168af4b9 100644
> --- a/commands/hab.c
> +++ b/commands/hab.c
> @@ -16,9 +16,9 @@ static int do_hab(int argc, char *argv[])
>  	char *srkhashfile = NULL, *srkhash = NULL;
>  	unsigned flags = 0;
>  	u8 srk[SRK_HASH_SIZE];
> -	int lockdown = 0, info = 0;
> +	int lockdown = 0, info = 0, field_return = 0;
>  
> -	while ((opt = getopt(argc, argv, "s:fpx:li")) > 0) {
> +	while ((opt = getopt(argc, argv, "s:fpx:lir")) > 0) {
>  		switch (opt) {
>  		case 's':
>  			srkhashfile = optarg;
> @@ -38,12 +38,15 @@ static int do_hab(int argc, char *argv[])
>  		case 'i':
>  			info = 1;
>  			break;
> +		case 'r':
> +			field_return = 1;
> +			break;
>  		default:
>  			return COMMAND_ERROR_USAGE;
>  		}
>  	}
>  
> -	if (!info && !lockdown && !srkhashfile && !srkhash) {
> +	if (!info && !lockdown && !srkhashfile && !srkhash && !field_return) {
>  		printf("Nothing to do\n");
>  		return COMMAND_ERROR_USAGE;
>  	}
> @@ -94,7 +97,19 @@ static int do_hab(int argc, char *argv[])
>  		printf("Device successfully locked down\n");
>  	}
>  
> -	return 0;
> +	if (field_return) {
> +		ret = imx_hab_field_return(flags & IMX_SRK_HASH_WRITE_PERMANENT);
> +		if (ret == -EINVAL && IS_ENABLED(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN))
> +			printf("Field-return burn failed, check HABV4_CSF_UNLOCK_UID!\n");
> +		else if (ret == -EINVAL && !IS_ENABLED(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN))
> +			printf("Field-return burn failed because CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN=n\n");
> +		else if (ret)
> +			printf("Field-return burn failed\n");
> +		else
> +			printf("Field return fuse successfully burnt\n");
> +	}
> +
> +	return ret;
>  }
>  
>  BAREBOX_CMD_HELP_START(hab)
> @@ -105,6 +120,7 @@ BAREBOX_CMD_HELP_OPT ("-x <sha256>",  "Burn Super Root Key hash from hex string"
>  BAREBOX_CMD_HELP_OPT ("-i",  "Print HAB info")
>  BAREBOX_CMD_HELP_OPT ("-f",  "Force. Write even when a key is already written")
>  BAREBOX_CMD_HELP_OPT ("-l",  "Lockdown device. Dangerous! After executing only signed images can be booted")
> +BAREBOX_CMD_HELP_OPT ("-r",  "Field Return. Dangerous! After executing signed images are disabled forever.")
>  BAREBOX_CMD_HELP_OPT ("-p",  "Permanent. Really burn fuses. Be careful!")
>  BAREBOX_CMD_HELP_END
>  
> 
> -- 
> 2.47.3
> 
> 

-- 
#gernperDu 
#CallMeByMyFirstName

Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | https://www.pengutronix.de/ |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-9    |



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

* Re: [PATCH v2 4/4] commands: hab: extend by field_return fuse burn
  2025-12-19  9:06 ` [PATCH v2 4/4] commands: hab: extend by field_return fuse burn Fabian Pflug
  2025-12-19  9:57   ` Marco Felsch
@ 2025-12-19 10:03   ` Lucas Stach
  1 sibling, 0 replies; 10+ messages in thread
From: Lucas Stach @ 2025-12-19 10:03 UTC (permalink / raw)
  To: Fabian Pflug, Marco Felsch, BAREBOX

Am Freitag, dem 19.12.2025 um 10:06 +0100 schrieb Fabian Pflug:
> Extend hab command with an additional parameter to burn the field return
> fuse.
> Since there is now a convenient way to burn the field return fuse, give
> a hint at the Kconfig option about this, as it already describes what to
> do in order to burn the fuse to make it complete.
> 
> Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
> ---
>  arch/arm/mach-imx/Kconfig |  6 +++++-
>  commands/hab.c            | 24 ++++++++++++++++++++----
>  2 files changed, 25 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 5f50d1a823..5fea0bbbca 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -926,13 +926,17 @@ config HABV4_CSF_UNLOCK_UID
>            feature. This value must match the per device UNIQUE_ID fuses.
>  
>  	  The below example shows the expected format. The UNIQUE_ID is
> -	  queried by Linux via:
> +	  printed during boot by barebox:
> +	    i.MX___ unique ID: 7766554433221100
> +	  or it can be queried by Linux via:
>              - cat /sys/devices/soc0/serial_number
>  	      7766554433221100
>  
>  	  So this value have to be set:
>  	    - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
>  
> +	  Afterwards, the `hab -p -r` command can be used to burn the fuse.
> +
>  config HABV4_IMG_CRT_PEM
>  	string "Path to IMG certificate"
>  	default "../crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
> diff --git a/commands/hab.c b/commands/hab.c
> index 8ae943a4c8..1e168af4b9 100644
> --- a/commands/hab.c
> +++ b/commands/hab.c
> @@ -16,9 +16,9 @@ static int do_hab(int argc, char *argv[])
>  	char *srkhashfile = NULL, *srkhash = NULL;
>  	unsigned flags = 0;
>  	u8 srk[SRK_HASH_SIZE];
> -	int lockdown = 0, info = 0;
> +	int lockdown = 0, info = 0, field_return = 0;
>  
> -	while ((opt = getopt(argc, argv, "s:fpx:li")) > 0) {
> +	while ((opt = getopt(argc, argv, "s:fpx:lir")) > 0) {
>  		switch (opt) {
>  		case 's':
>  			srkhashfile = optarg;
> @@ -38,12 +38,15 @@ static int do_hab(int argc, char *argv[])
>  		case 'i':
>  			info = 1;
>  			break;
> +		case 'r':
> +			field_return = 1;
> +			break;
>  		default:
>  			return COMMAND_ERROR_USAGE;
>  		}
>  	}
>  
> -	if (!info && !lockdown && !srkhashfile && !srkhash) {
> +	if (!info && !lockdown && !srkhashfile && !srkhash && !field_return) {
>  		printf("Nothing to do\n");
>  		return COMMAND_ERROR_USAGE;
>  	}
> @@ -94,7 +97,19 @@ static int do_hab(int argc, char *argv[])
>  		printf("Device successfully locked down\n");
>  	}
>  
> -	return 0;
> +	if (field_return) {
> +		ret = imx_hab_field_return(flags & IMX_SRK_HASH_WRITE_PERMANENT);
> +		if (ret == -EINVAL && IS_ENABLED(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN))
> +			printf("Field-return burn failed, check HABV4_CSF_UNLOCK_UID!\n");
> +		else if (ret == -EINVAL && !IS_ENABLED(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN))
> +			printf("Field-return burn failed because CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN=n\n");
> +		else if (ret)
> +			printf("Field-return burn failed\n");
> +		else
> +			printf("Field return fuse successfully burnt\n");
> +	}
> +
> +	return ret;
>  }
>  
>  BAREBOX_CMD_HELP_START(hab)
> @@ -105,6 +120,7 @@ BAREBOX_CMD_HELP_OPT ("-x <sha256>",  "Burn Super Root Key hash from hex string"
>  BAREBOX_CMD_HELP_OPT ("-i",  "Print HAB info")
>  BAREBOX_CMD_HELP_OPT ("-f",  "Force. Write even when a key is already written")
>  BAREBOX_CMD_HELP_OPT ("-l",  "Lockdown device. Dangerous! After executing only signed images can be booted")
> +BAREBOX_CMD_HELP_OPT ("-r",  "Field Return. Dangerous! After executing signed images are disabled forever.")

Not an expert on this, but IIRC after the field return fuse is blown
the ROM still accepts signed images, just all access to SoC device keys
is disabled.

Regards,
Lucas

>  BAREBOX_CMD_HELP_OPT ("-p",  "Permanent. Really burn fuses. Be careful!")
>  BAREBOX_CMD_HELP_END
>  
> 




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

* Re: [PATCH v2 1/4] arm: mach-imx6: use kconfig for field return
  2025-12-19  9:14   ` Ahmad Fatoum
@ 2025-12-19 10:06     ` Marco Felsch
  0 siblings, 0 replies; 10+ messages in thread
From: Marco Felsch @ 2025-12-19 10:06 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Fabian Pflug, BAREBOX

On 25-12-19, Ahmad Fatoum wrote:
> Hi,
> 
> On 12/19/25 10:06 AM, Fabian Pflug wrote:
> > There is a Kconfig option for the field return, that is also documented,
> > so using it here instead of providing a headerfile to patch.
> > 
> > Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
> > Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
> > ---
> >  include/mach/imx/habv4-imx6-gencsf-template.h | 11 +++--------
> >  1 file changed, 3 insertions(+), 8 deletions(-)
> > 
> > diff --git a/include/mach/imx/habv4-imx6-gencsf-template.h b/include/mach/imx/habv4-imx6-gencsf-template.h
> > index 45da2981cb..c24bf84b85 100644
> > --- a/include/mach/imx/habv4-imx6-gencsf-template.h
> > +++ b/include/mach/imx/habv4-imx6-gencsf-template.h
> > @@ -39,17 +39,12 @@ hab Engine = SETUP_HABV4_ENGINE
> >  hab Features = SETUP_HABV4_FEATURES
> >  #endif
> >  
> > -/*
> > -// allow fusing FIELD_RETURN
> > -// # ocotp0.permanent_write_enable=1
> > -// # mw -l -d /dev/imx-ocotp 0xb8 0x1
> > +#if defined(CONFIG_HABV4_CSF_UNLOCK_FIELD_RETURN)
> >  hab [Unlock]
> >  hab Engine = OCOTP
> >  hab Features = FIELD RETURN
> > -// device-specific UID:
> > -// $ dd if=/sys/bus/nvmem/devices/imx-ocotp0/nvmem bs=4 skip=1 count=2 status=none | hexdump -ve '1/1 "0x%.2x, "' | sed 's/, $//'
> > -hab UID = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
> > -*/
> > +hab UID = HABV4_CSF_UNLOCK_UID
> 
> How can this work without a CONFIG_ in front of the option?

Good catch Ahmad! I think Fabian just copied the broken mainlined
version from the i.MX8M.

My v2
(https://lore.barebox.org/barebox/20240703-v2024-05-0-topic-hab-v2-8-17419aa5d3a3@pengutronix.de/)
used another abroach to set the define which didn't made it into
mainline :/

So mainline is broken for i.MX8M as well :/

@Fabian
Could you please include a patch which fixes this for the i.MX8M as
well?

Regards,
  Marco


> 
> Thanks,
> Ahmad
> 
> > +#endif
> >  
> >  hab [Install Key]
> >  /* verification key index in key store (0, 2...4) */
> > 
> 
> -- 
> Pengutronix e.K.                  |                             |
> Steuerwalder Str. 21              | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |
> 
> 

-- 
#gernperDu 
#CallMeByMyFirstName

Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | https://www.pengutronix.de/ |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-9    |



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

end of thread, other threads:[~2025-12-19 10:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-19  9:06 [PATCH v2 0/4] i.mx: hab/ocotop: extend field return to i.MX6 Fabian Pflug
2025-12-19  9:06 ` [PATCH v2 1/4] arm: mach-imx6: use kconfig for field return Fabian Pflug
2025-12-19  9:14   ` Ahmad Fatoum
2025-12-19 10:06     ` Marco Felsch
2025-12-19  9:06 ` [PATCH v2 2/4] nvmem: ocotp: extend support to query the sticky bit Fabian Pflug
2025-12-19  9:06 ` [PATCH v2 3/4] i.MX: HAB: extend field_return support to imx6 Fabian Pflug
2025-12-19  9:56   ` Marco Felsch
2025-12-19  9:06 ` [PATCH v2 4/4] commands: hab: extend by field_return fuse burn Fabian Pflug
2025-12-19  9:57   ` Marco Felsch
2025-12-19 10:03   ` Lucas Stach

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