Skip to content

Conversation

SebastianBoe
Copy link
Contributor

@SebastianBoe SebastianBoe commented Oct 10, 2025

Increase support for IronSide SE UICR features

Copy link
Contributor

@hakonfam hakonfam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a mechanism stopping users from enabling UICR.LOCK and UICR.ERASEPROTECT at the same time by accident.

This configuration does not give much value as one would typically complete the device lock down in run time in the final stages of production.

"GEN_UICR_SECURESTORAGE",
"GEN_UICR_WDTSTART",
"GEN_UICR_WDTSTART_CRV",
"GEN_UICR_WDTSTART_INSTANCE_CODE", # Used in specialized build tool, not part of main Kconfig
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is the purpose here to only have the comment on the last entry? If so the top entry still has the comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You resolved the comment, but there are still two entries with a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The descriptive comments seem to be established standard in this list, is it really kosher to just drop them?
First and last entry for the GEN_UICR_* entries seemed like a good compromise to me? Maybe "# Used by designated gen_uicr.py build tool, not part of main Kconfig" would even be a bit better than "not part of main Kconfig"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with having at the beginning and end is that alphabetical sorting is required so the comment would have to move from time to time, and this pollutes commits with unrelated changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, aight works as a reason for me

Comment on lines 52 to 54
When enabled, the UICR generator will configure the
watchdog timer to start automatically before the
application core is booted.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention that its the local watchdog timer instance as opposed to the global one?

Copy link
Contributor Author

@SebastianBoe SebastianBoe Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  When enabled, the UICR generator will configure the
  application domain's watchdog timer to start automaticall
  before the application core is booted.

Like this maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is specific to the app local domain, I figure we don't need to use the generic local domain term.

Comment on lines 38 to 39
When enabled, the UICR generator will lock the entire UICR
configuration in NVR0. Once locked, the UICR can only be modified
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't it lock all NVR0? Should we specify that its the NVR0 in MRAM10? Which includes BICR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

in production devices to prevent unauthorized modification of the
UICR configuration.

config GEN_UICR_ERASEPROTECT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should prevent users from enabling this by accident as it will practically brick their device.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

@hakonfam hakonfam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NACK since IMO we need further hardening against creating "bricking" UICRs.

"GEN_UICR_SECURESTORAGE",
"GEN_UICR_WDTSTART",
"GEN_UICR_WDTSTART_CRV",
"GEN_UICR_WDTSTART_INSTANCE_CODE", # Used in specialized build tool, not part of main Kconfig
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You resolved the comment, but there are still two entries with a comment.

Comment on lines 627 to 632
# Handle LOCK configuration
if args.lock:
uicr.LOCK = ENABLED_VALUE
# Handle ERASEPROTECT configuration
if args.eraseprotect:
uicr.ERASEPROTECT = ENABLED_VALUE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since bricking devices is very costly, should we have a check in place here as well?

My experience is that these types of script is often pulled out from the context they are made for and brutally exploited to solve some users dire needs. We should help even those users not bricking their boards IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about a

--permanently-transition-device-to-deployed

option to allow this script to be used by:

Users that want to send their device into LCS Deployed, i.e. for production testing purposes.
Users that work on a simulated device and are therefore able to transition back.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

hakonfam
hakonfam previously approved these changes Oct 15, 2025
karstenkoenig
karstenkoenig previously approved these changes Oct 15, 2025
Copy link
Contributor

@karstenkoenig karstenkoenig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only cosmetic feedback

"GEN_UICR_SECURESTORAGE",
"GEN_UICR_WDTSTART",
"GEN_UICR_WDTSTART_CRV",
"GEN_UICR_WDTSTART_INSTANCE_CODE", # Used in specialized build tool, not part of main Kconfig
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The descriptive comments seem to be established standard in this list, is it really kosher to just drop them?
First and last entry for the GEN_UICR_* entries seemed like a good compromise to me? Maybe "# Used by designated gen_uicr.py build tool, not part of main Kconfig" would even be a bit better than "not part of main Kconfig"

hakonfam
hakonfam previously approved these changes Oct 15, 2025
Add support for UICR.WDTSTART.

UICR.WDTSTART configures the automatic start of a local watchdog timer
before the application core is booted. This provides early system
protection ensuring that the system can recover from early boot
failures.

Signed-off-by: Sebastian Bøe <[email protected]>
Add support for UICR.SECONDARY.TRIGGER configuration, which enables
automatic booting of secondary firmware based on specific reset reasons.

This introduces Kconfig options for configuring:
- UICR.SECONDARY.TRIGGER.ENABLE - Enable/disable automatic triggers
- UICR.SECONDARY.TRIGGER.RESETREAS - Bitmask of reset reasons that
  trigger secondary firmware boot

Individual Kconfig options are provided for each reset reason:
- APPLICATIONWDT0/1 - Application core watchdog timeouts
- APPLICATIONLOCKUP - Application core CPU lockup
- RADIOCOREWDT0/1 - Radio core watchdog timeouts
- RADIOCORELOCKUP - Radio core CPU lockup

Signed-off-by: Sebastian Bøe <[email protected]>
Add support for UICR.SECONDARY.PROTECTEDMEM configuration, which enables
configuration of the protected memory region for secondary firmware.

This introduces Kconfig options for configuring:
- GEN_UICR_SECONDARY_PROTECTEDMEM - Enable/disable protected memory
  for secondary firmware
- GEN_UICR_SECONDARY_PROTECTEDMEM_SIZE_BYTES - Size of the protected
  memory region in bytes

The implementation validates that the configured size is divisible by
4096 bytes (4 KiB) as required by the hardware, and converts it to
4 KiB units when writing to UICR.SECONDARY.PROTECTEDMEM.SIZE4KB.

Signed-off-by: Sebastian Bøe <[email protected]>
Add support for UICR.LOCK configuration, which locks the entire UICR
configuration in NVR0 to prevent unauthorized modifications.

This introduces a Kconfig option GEN_UICR_LOCK that enables locking
of the UICR. Once locked, the UICR can only be modified by performing
an ERASEALL operation.

This is a critical security feature for production devices, typically
enabled alongside UICR.APPROTECT, UICR.PROTECTEDMEM, and
UICR.ERASEPROTECT to establish a complete device protection scheme.

When enabled, the gen_uicr.py script sets UICR.LOCK to 0xFFFFFFFF,
which configures the NVR0 page as read-only and enforces integrity
checks on the UICR content.

Signed-off-by: Sebastian Bøe <[email protected]>
Add support for UICR.ERASEPROTECT configuration, which blocks ERASEALL
operations to prevent bulk erasure of protected memory.

This introduces a Kconfig option GEN_UICR_ERASEPROTECT that enables
blocking of ERASEALL operations on NVR0, preserving UICR settings even
if an attacker attempts a full-chip erase.

This is a critical security feature for production devices. When enabled
together with UICR.LOCK, it becomes impossible to modify the UICR in
any way, establishing a permanent device protection scheme. Due to this
irreversibility, it should only be enabled during the final stages of
production.

When enabled, the gen_uicr.py script sets UICR.ERASEPROTECT to
0xFFFFFFFF, which prevents the ERASEALL command from affecting the
NVR0 page.

Signed-off-by: Sebastian Bøe <[email protected]>
Add support for UICR.APPROTECT configuration, which controls debugger
and access-port permissions through the TAMPC peripheral.

This introduces three Kconfig options that allow independent control
over access port protection for different processor domains:

- GEN_UICR_APPROTECT_APPLICATION_PROTECTED: Controls debug access to
  the application domain processor
- GEN_UICR_APPROTECT_RADIOCORE_PROTECTED: Controls debug access to
  the radio core processor
- GEN_UICR_APPROTECT_CORESIGHT_PROTECTED: Controls access to the
  CoreSight debug infrastructure

When enabled, each option sets the corresponding UICR.APPROTECT
register to PROTECTED (0xFFFFFFFF), which disables debug access for
that domain. When disabled, the registers remain at their erased value
(UNPROTECTED), allowing full debug access.

This feature is critical for production devices where debug access must
be restricted to prevent unauthorized access to sensitive code and data.

Signed-off-by: Sebastian Bøe <[email protected]>
Add --permit-permanently-transitioning-device-to-deployed safety flag
to gen_uicr.py, required when enabling both UICR.LOCK and
UICR.ERASEPROTECT together. This prevents accidental permanent locking
of devices since this combination makes the configuration irreversible.

Signed-off-by: Sebastian Bøe <[email protected]>
Copy link

@cfriedt cfriedt merged commit 35b89ab into zephyrproject-rtos:main Oct 15, 2025
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants