mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Oleksij Rempel <o.rempel@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Subject: [PATCH v1 2/2] Documentation: user: Add OTP support and parameter descriptions
Date: Thu, 30 Jan 2025 13:08:14 +0100	[thread overview]
Message-ID: <20250130120814.1053382-2-o.rempel@pengutronix.de> (raw)
In-Reply-To: <20250130120814.1053382-1-o.rempel@pengutronix.de>

Provide an overview of OTP support in Barebox.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 Documentation/user/otp.rst         | 199 +++++++++++++++++++++++++++++
 Documentation/user/user-manual.rst |   1 +
 2 files changed, 200 insertions(+)
 create mode 100644 Documentation/user/otp.rst

diff --git a/Documentation/user/otp.rst b/Documentation/user/otp.rst
new file mode 100644
index 000000000000..24a1f81fa449
--- /dev/null
+++ b/Documentation/user/otp.rst
@@ -0,0 +1,199 @@
+OTP (One-Time Programmable) Support
+====================================
+
+Overview
+========
+
+One-Time Programmable (OTP) memory is a type of non-volatile storage that
+allows data to be written only once. After programming, the data cannot be
+changed, or in some cases, only certain bits can transition from `0` to `1`.
+OTP is commonly used for:
+
+- Storing unique device identifiers (serial numbers, MAC addresses, etc.).
+- Configuring security settings (keys, fuses, hardware feature locks).
+- Setting permanent device configurations.
+
+In Barebox, most OTP drivers are implemented on top of the `nvmem` framework.
+Each specific driver may introduce device-specific parameters, but developers
+are encouraged to follow a common pattern when implementing OTP access.
+
+Supported Parameters
+====================
+
+Several parameters are used in different OTP drivers to provide consistent
+access to the hardware. These include:
+
+permanent_write_enable
+----------------------
+Controls whether OTP programming is done directly or via shadow memory.
+
+- This is a global setting per OTP device.
+- permanent_write_enable=1 -> All writes go directly to OTP fuses
+  (permanent)
+- permanent_write_enable=0 -> All writes go to shadow memory (volatile)
+  if supported.
+- Toggling `permanent_write_enable` does not automatically commit shadow
+  memory.
+- If shadow memory is not supported, writes always go directly to OTP.
+
+Understanding Shadow Memory
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Shadow memory acts as a volatile cache that holds OTP values temporarily.
+- Shadow values are lost on power cycle unless explicitly committed.
+- On some SoCs, shadow memory can be used for testing. The system can
+  reboot (without power cycling) and use shadow values temporarily before
+  committing them.
+
+Writing to OTP with and without Shadow Memory
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Example 1: Immediate Permanent Write (Bypassing Shadow Memory)
+::
+
+    # Enable direct OTP write mode (all writes will be permanent)
+    bsec0.permanent_write_enable=1
+
+    # Write directly to an OTP register (bypasses shadow)
+    mw -l -d /dev/stm32-bsec 0x00000170+4 0x12345678
+
+    # Disable OTP write mode (future writes go to shadow, if available)
+    bsec0.permanent_write_enable=0
+
+Example 2: Using Shadow Memory Without Committing
+::
+
+    # Ensure shadow writes are enabled
+    bsec0.permanent_write_enable=0
+
+    # Write to shadow memory (not permanent yet)
+    mw -l -d /dev/imx-ocotp 0x20+4 0xAABBCCDD
+
+    # On power cycle, this data will be lost
+    # After reboot, OTP value remains unchanged
+
+Example 3: Using Shadow Memory for Testing Before Committing
+::
+
+    # Ensure shadow writes are enabled
+    ocotp0.permanent_write_enable=0
+
+    # Write to the shadow memory (not yet permanent)
+    mw -l -d /dev/imx-ocotp 0x20+4 0xAABBCCDD
+
+    # Perform a warm reboot (shadow memory is still active)
+    reset -w
+
+    # If configuration works as expected, commit shadow to OTP
+    ocotp0.permanent_write_enable=1
+    mw -l -d /dev/imx-ocotp 0x20+4 0xAABBCCDD
+    ocotp0.permanent_write_enable=0
+
+    # Now the value is permanently written to OTP fuses
+
+**Caution**
+^^^^^^^^^^^
+
+- Setting `permanent_write_enable=1` makes all writes permanent
+  immediately.
+- Setting `permanent_write_enable=0` does not commit shadow memory
+  automatically.
+- Shadow memory is lost on power cycle unless explicitly committed.
+
+writelock
+---------
+
+Permanently locks an OTP word after it is written.
+
+- writelock=1 -> Any OTP word written while this is enabled will be
+  permanently locked after writing.
+- writelock=0 -> Writes remain modifiable unless explicitly locked later.
+- Only the OTP words written while `writelock=1` is active will be locked.
+- Not all hardware or drivers support this functionality, or they may
+  implement locking differently.
+
+How OTP Word Locking Works
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Some OTP technologies allow bitwise OR-ing (changing `0` bits to `1` but
+  not back to `0`).
+- Without `writelock=1`, an attacker could modify certain bits after
+  provisioning (e.g., enabling additional security features but keeping a
+  backdoor open).
+- Setting `writelock=1` ensures that only the OTP words written while it is
+  active are locked, preventing further modification.
+
+Usage Example: Permanently Locking an OTP Word
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    # Enable OTP write mode (writes will be permanent)
+    bsec0.permanent_write_enable=1
+    bsec0.writelock=1
+
+    # Write data to OTP (this specific word will be permanently locked)
+    mw -l -d /dev/stm32-bsec 0x00000170+4 0x12345678
+
+    # Disable write mode and writelock (future writes will not be locked)
+    bsec0.permanent_write_enable=0
+    bsec0.writelock=0
+
+**Caution**
+^^^^^^^^^^^
+
+- Only the OTP words written while `writelock=1` is active will be locked.
+- Other OTP words remain modifiable unless explicitly written and locked.
+- Not all hardware or drivers support this functionality, or they may
+  implement locking differently.
+- If shadow memory is used (`permanent_write_enable=0`), writelock does not
+  apply.
+- Ensure all OTP values are correct before enabling `writelock=1`.
+
+sense_enable
+------------
+
+Controls whether OTP values are read from shadow memory or directly from the
+fuses.
+
+- sense_enable=1 -> Reads are performed directly from the OTP fuses.
+- sense_enable=0 -> Reads are performed from shadow memory (if supported).
+- If shadow memory is supported, `sense_enable=0` may return outdated values
+  if the shadow memory has not been updated.
+- If shadow memory is not supported, reads always come from OTP fuses, making
+  `sense_enable` ineffective.
+
+Use Cases
+^^^^^^^^^
+
+- Ensuring accuracy: Reading directly from the OTP fuses (`sense_enable=1`)
+  guarantees that the retrieved value reflects the actual state of the OTP
+  memory.
+- Avoiding outdated values: If `sense_enable=0` is used and the shadow
+  memory has not been refreshed, the read value may differ from the true OTP
+  fuse state.
+- Debugging & Validation: Direct OTP fuse reads can be used to confirm
+  whether a value has been successfully programmed.
+
+Usage Example
+^^^^^^^^^^^^^
+
+::
+
+    # Read OTP directly from fuses (ensures accuracy)
+    ocotp0.sense_enable=1
+    md -l /dev/nvmem/imx-ocotp
+
+    # Read OTP from shadow memory (may return outdated values if not refreshed)
+    ocotp0.sense_enable=0
+    md -l /dev/nvmem/imx-ocotp
+
+**Caution**
+^^^^^^^^^^^
+
+- If `sense_enable=0`, values may not reflect the actual OTP state until the
+  shadow memory is refreshed.
+- If `sense_enable=1`, the read is guaranteed to return the true OTP fuse
+  value.
+- Not all hardware supports shadow memory, making `sense_enable` ineffective
+  on some devices.
diff --git a/Documentation/user/user-manual.rst b/Documentation/user/user-manual.rst
index 565e6c11f82f..9f53f3aa449b 100644
--- a/Documentation/user/user-manual.rst
+++ b/Documentation/user/user-manual.rst
@@ -34,6 +34,7 @@ Contents:
    state
    random
    optee
+   otp
    debugging
    watchdog
    reboot-mode
-- 
2.39.5




  reply	other threads:[~2025-01-30 12:08 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-30 12:08 [PATCH v1 1/2] nvmem: bsec: Add support for OTP permanent write lock Oleksij Rempel
2025-01-30 12:08 ` Oleksij Rempel [this message]
2025-01-31 13:03   ` [PATCH v1 2/2] Documentation: user: Add OTP support and parameter descriptions Sascha Hauer
2025-01-31 13:07 ` [PATCH v1 1/2] nvmem: bsec: Add support for OTP permanent write lock Sascha Hauer

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=20250130120814.1053382-2-o.rempel@pengutronix.de \
    --to=o.rempel@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox