# nRF54L15 NS+TFM: `soc_flash_nrf_rram` driver missing secure-flash read for DTS-only partitioning → SECURE FAULT on `mcumgr image list`

Summary

The Zephyr RRAM driver drivers/flash/soc_flash_nrf_rram.c does not pass NS-side reads of TF-M secure flash through soc_secure_mem_read when the device tree uses the modern, pure-DTS partition layout. Any NS code issuing a flash_area_read() whose physical address falls inside the TF-M secure sub-partition (i.e. between slot0_partition start and slot0_ns_partition start) hits an SAU/IDAU attribution-unit violation and SecureFaults the application core.

The legacy Partition Manager path is already handled correctly by an existing PM_APP_ADDRESS guard. The DTS-only path was never ported when NCS deprecated PM in favour of DTS partitioning, so any NS+TFM nRF54L15 build that follows the recommended flow crashes the moment a host queries slot state.

Reproducer

  1. Build any *_cpuapp/ns application on nrf54l15 with TF-M, MCUboot sub-partitioned slots (slot0_partition spans slot0_s_partition + slot0_ns_partition), MCUmgr image group enabled, pure-DTS partitioning (no PM).
  2. Boot the NS app, attach mcumgr-cli over SMP.
  3. Run: mcumgr --conntype serial --connstring "dev=/dev/ttyACM0,baud=115200" image list
  4. Host times out. Device log: os: ***** SECURE FAULT ***** os: Address: 0xc000 os: Attribution unit violation os: r0/a1: 0x2002d588 r1/a2: 0x0000c000 r2/a3: 0x0000c020 os: Faulting instruction address (r15/pc): 0x0008f6fc os: >>> ZEPHYR FATAL ERROR 41: Unknown error on CPU 0

0xc000 is slot0_partition base = first byte of slot0_s_partition (TF-M, MPC-locked). The 32-byte read (r2 - r1 == 0x20) is the standard MCUboot image_header fetch in zephyr_img_mgmt.c::img_mgmt_read_info().

I think its caused by: 

In drivers/flash/soc_flash_nrf_rram.c, nrf_rram_read() currently does:

#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER && PM_APP_ADDRESS
if (addr < PM_APP_ADDRESS) {
return soc_secure_mem_read(data, (void *)addr, len);
}
#endif
memcpy(data, (void *)addr, len);

The legacy drivers/flash/soc_flash_nrf.c (nRF52/nRF53) already has a parallel #elif arm for the DTS-only case using slot0_ns_partition. The RRAM driver was never given the equivalent.

#if CONFIG_TRUSTED_EXECUTION_NONSECURE
#if USE_PARTITION_MANAGER && PM_APP_ADDRESS
if (addr < PM_APP_ADDRESS) {
return soc_secure_mem_read(data, (void *)addr, len);
}
#elif !USE_PARTITION_MANAGER && DT_NODE_EXISTS(DT_NODELABEL(slot0_ns_partition))
if ((uintptr_t)addr < DT_REG_ADDR(DT_NODELABEL(slot0_ns_partition))) {
return soc_secure_mem_read(data, (void *)addr, len);
}
#endif
#endif

And relax the soc_secure.h include guard so it's pulled in for both PM and DTS-only NS builds:

#if CONFIG_TRUSTED_EXECUTION_NONSECURE
#include <soc_secure.h>
#if USE_PARTITION_MANAGER
#include <pm_config.h>
#endif
#endif

This is what my patching is currently doing.

Many thanks and hope this help. 

Dom

Related