All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Delaunay <patrick.delaunay@foss.st.com>
To: <u-boot@lists.denx.de>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>,
	Johann Neuhauser <jneuhauser@dh-electronics.com>,
	Patrice Chotard <patrice.chotard@foss.st.com>,
	U-Boot STM32 <uboot-stm32@st-md-mailman.stormreply.com>
Subject: [PATCH 1/2] stm32mp: bsec: add permanent lock write support
Date: Tue, 15 Feb 2022 16:08:50 +0100	[thread overview]
Message-ID: <20220215160841.1.Ieacd0bc93c53f5b38d6e1d228a498bc40758f121@changeid> (raw)

Add support of the permanent lock support in U-Boot proper
when BSEC is not managed by secure monitor (TF-A SP_MIN or OP-TEE).

This patch avoid issue with stm32key command and fuse command
on basic boot for this missing feature of U-Boot BSEC driver.

Reported-by: Johann Neuhauser <jneuhauser@dh-electronics.com>
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

 arch/arm/mach-stm32mp/bsec.c | 90 +++++++++++++++++++++++++++++++++---
 1 file changed, 84 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
index 27d1829501..fd6e1a3957 100644
--- a/arch/arm/mach-stm32mp/bsec.c
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -18,6 +18,7 @@
 #include <linux/iopoll.h>
 
 #define BSEC_OTP_MAX_VALUE		95
+#define BSEC_OTP_UPPER_START		32
 #define BSEC_TIMEOUT_US			10000
 
 /* BSEC REGISTER OFFSET (base relative) */
@@ -41,6 +42,7 @@
 /* BSEC_CONTROL Register */
 #define BSEC_READ			0x000
 #define BSEC_WRITE			0x100
+#define BSEC_LOCK			0x200
 
 /* LOCK Register */
 #define OTP_LOCK_MASK			0x1F
@@ -61,6 +63,11 @@
  */
 #define BSEC_LOCK_PROGRAM		0x04
 
+/*
+ * OTP status: bit 0 permanent lock
+ */
+#define BSEC_LOCK_PERM			BIT(0)
+
 /**
  * bsec_lock() - manage lock for each type SR/SP/SW
  * @address: address of bsec IP register
@@ -284,6 +291,65 @@ static int bsec_program_otp(struct udevice *dev, long base, u32 val, u32 otp)
 	return ret;
 }
 
+/**
+ * bsec_permanent_lock_otp() - permanent lock of OTP in SAFMEM
+ * @dev: bsec IP device
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error
+ */
+static int bsec_permanent_lock_otp(struct udevice *dev, long base, uint32_t otp)
+{
+	int ret;
+	bool power_up = false;
+	u32 val, addr;
+
+	/* check if safemem is power up */
+	if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
+		ret = bsec_power_safmem(base, true);
+		if (ret)
+			return ret;
+
+		power_up = true;
+	}
+
+	/*
+	 * low OTPs = 2 bits word for low OTPs, 1 bits per word for upper OTP
+	 * and only 16 bits used in WRDATA
+	 */
+	if (otp < BSEC_OTP_UPPER_START) {
+		addr = otp / 8;
+		val = 0x03 << ((otp * 2) & 0xF);
+	} else {
+		addr = BSEC_OTP_UPPER_START / 8 +
+		       ((otp - BSEC_OTP_UPPER_START) / 16);
+		val = 0x01 << (otp & 0xF);
+	}
+
+	/* set value in write register*/
+	writel(val, base + BSEC_OTP_WRDATA_OFF);
+
+	/* set BSEC_OTP_CTRL_OFF with the otp addr and lock request*/
+	writel(addr | BSEC_WRITE | BSEC_LOCK, base + BSEC_OTP_CTRL_OFF);
+
+	/* check otp status*/
+	ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
+				 val, (val & BSEC_MODE_BUSY_MASK) == 0,
+				 BSEC_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	if (val & BSEC_MODE_PROGFAIL_MASK)
+		ret = -EACCES;
+	else
+		ret = bsec_check_error(base, otp);
+
+	if (power_up)
+		bsec_power_safmem(base, false);
+
+	return ret;
+}
+
 /* BSEC MISC driver *******************************************************/
 struct stm32mp_bsec_plat {
 	u32 base;
@@ -339,9 +405,14 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
 static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp)
 {
 	struct stm32mp_bsec_plat *plat = dev_get_plat(dev);
+	u32 wrlock;
 
 	/* return OTP permanent write lock status */
-	*val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
+	wrlock = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
+
+	*val = 0;
+	if (wrlock)
+		*val = BSEC_LOCK_PERM;
 
 	return 0;
 }
@@ -377,15 +448,22 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
 
 static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
 {
-	if (!IS_ENABLED(CONFIG_ARM_SMCCC) || IS_ENABLED(CONFIG_SPL_BUILD))
-		return -ENOTSUPP;
+	struct stm32mp_bsec_plat *plat;
+
+	/* only permanent write lock is supported in U-Boot */
+	if (!(val & BSEC_LOCK_PERM)) {
+		dev_dbg(dev, "lock option without BSEC_LOCK_PERM: %x\n", val);
+		return 0; /* nothing to do */
+	}
 
-	if (val == 1)
+	if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD))
 		return stm32_smc_exec(STM32_SMC_BSEC,
 				      STM32_SMC_WRLOCK_OTP,
 				      otp, 0);
-	if (val == 0)
-		return 0; /* nothing to do */
+
+	plat = dev_get_plat(dev);
+
+	return bsec_permanent_lock_otp(dev, plat->base, otp);
 
 	return -EINVAL;
 }
-- 
2.25.1


             reply	other threads:[~2022-02-15 15:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-15 15:08 Patrick Delaunay [this message]
2022-02-15 15:08 ` [PATCH 2/2] stm32mp1: bsec: add missing dev in function comment Patrick Delaunay
2022-02-23  8:28   ` Patrice CHOTARD
2022-03-15  8:00   ` Patrice CHOTARD
2022-02-16  9:40 ` [PATCH 1/2] stm32mp: bsec: add permanent lock write support Johann Neuhauser
2022-02-23  8:27 ` Patrice CHOTARD
2022-03-15  8:00 ` Patrice CHOTARD

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220215160841.1.Ieacd0bc93c53f5b38d6e1d228a498bc40758f121@changeid \
    --to=patrick.delaunay@foss.st.com \
    --cc=jneuhauser@dh-electronics.com \
    --cc=patrice.chotard@foss.st.com \
    --cc=u-boot@lists.denx.de \
    --cc=uboot-stm32@st-md-mailman.stormreply.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.