Inquiry regarding UICR OTP access on nRF54L series via TF-M

Hello.

I am considering using the UICR OTP to store device-specific identification information.
My understanding is that when accessing this area from a Non-secure application, it is necessary to use the TF-M IOCTL library and perform the read through 'tfm_platform_mem_read'.

I referred to the following document:

https://docs.nordicsemi.com/bundle/ps_nrf54L15/page/uicr.html
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf54l/otp_map_nrf54l.html
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/libraries/security/tfm/tfm_ioctl_api.html#read_service

However, upon checking 'tfm_platform_user_memory_ranges.h' in the nRF Connect SDK (NCS), I noticed that the OTP range is not included for the nRF54L series, whereas it is present for the nRF91 and nRF53 series.

https://github.com/nrfconnect/sdk-nrf/blob/v3.2-branch/modules/trusted-firmware-m/tfm_boards/services/include/tfm_platform_user_memory_ranges.h#L54

#if defined(NRF91_SERIES) || defined(NRF53_SERIES)
#define UICR_OTP_ADDR (NRF_UICR_S_BASE + offsetof(NRF_UICR_Type, OTP))
#define UICR_OTP_SIZE (sizeof(NRF_UICR_S->OTP))
#endif

I have the following questions:

  • Is the exclusion of the OTP range for the nRF54L series intentional or by design?
  • If I need to include the OTP range in the allowed memory regions, is there a recommended method other than directly modifying 'tfm_platform_user_memory_ranges.h' within the SDK?

Best regards,

a.da

Parents
  • Hello,

    Like it says a bit further up in tfm_platform_user_memory_ranges.h,  "On platforms like nrf53 we provide a service for reading out FICR. But on platforms like nrf54l, FICR is hardware fixed to NS so the non-secure image can just read it directly.". That is why 54L is omitted here, it is by design Slight smile

    • If I need to include the OTP range in the allowed memory regions, is there a recommended method other than directly modifying 'tfm_platform_user_memory_ranges.h' within the SDK?

    Could you expand a bit on your use-case? I just want to make sure that your use-case really requires changing the SDK. 

    Regards,

    Elfving

Reply
  • Hello,

    Like it says a bit further up in tfm_platform_user_memory_ranges.h,  "On platforms like nrf53 we provide a service for reading out FICR. But on platforms like nrf54l, FICR is hardware fixed to NS so the non-secure image can just read it directly.". That is why 54L is omitted here, it is by design Slight smile

    • If I need to include the OTP range in the allowed memory regions, is there a recommended method other than directly modifying 'tfm_platform_user_memory_ranges.h' within the SDK?

    Could you expand a bit on your use-case? I just want to make sure that your use-case really requires changing the SDK. 

    Regards,

    Elfving

Children
  • Hi Elfving, thanks for your reply.

    Could you expand a bit on your use-case? I just want to make sure that your use-case really requires changing the SDK.

    I intend to store product-specific, read-only unique information in the SoC during production.
    These values are custom-defined and independent of FICR.
    Since the UICR OTP area is intended for custom user purposes, I am specifically looking for a method to access the UICR, not the FICR.

    To test this, I added the following code to the main() function of a Non-secure application:

    uint32_t result = 0;
    uint32_t addr_min = (intptr_t)(&(NRF_UICR_S->OTP[(288UL)]));
    uint32_t addr_max = (intptr_t)(&(NRF_UICR_S->OTP[UICR_OTP_MaxIndex]));
    uint32_t data[32] = {0};
    enum tfm_platform_err_t tfm_err = TFM_PLATFORM_ERR_SUCCESS;
    
    tfm_err = tfm_platform_mem_read(&data, addr_min, sizeof(data), &result);
    LOG_INF("otp custom usage addr: 0x%08x-0x%08x, result: %d, tfm_err: %d", addr_min, addr_max, result, tfm_err);

    Additionally, I found that 'UICR_OTP_MaxIndex' is defined 'nrf54l15_types.h' as follows:

    C:\ncs\v3.2.2\modules\hal\nordic\nrfx\bsp\stable\mdk

    /* UICR_OTP: One time programmable memory */
      #define UICR_OTP_MaxCount (320UL)                  /*!< Max size of OTP[320] array.                                          */
      #define UICR_OTP_MaxIndex (319UL)                  /*!< Max index of OTP[320] array.                                         */
      #define UICR_OTP_MinIndex (0UL)                    /*!< Min index of OTP[320] array.                                         */
      #define UICR_OTP_ResetValue (0xFFFFFFFFUL)         /*!< Reset value of OTP[320] register.                                    */

    Below are the logs when using the SDK as-is, and the logs after applying modifications to the SDK:

    Log 1 (Original SDK):

    [00:00:00.006,609] <inf> main: otp custom usage addr: 0x00ffd980-0x00ffd9fc, result: -1, tfm_err: 2

    Log 2 (Modified SDK):

    [00:00:00.007,396] <inf> main: otp custom usage addr: 0x00ffd980-0x00ffd9fc, result: 0, tfm_err: 0

    I applied the following modification to 'tfm_platform_user_memory_ranges.h' in the SDK:

    // #if defined(NRF91_SERIES) || defined(NRF53_SERIES)
    #if defined(NRF91_SERIES) || defined(NRF53_SERIES) || defined(NRF54L_SERIES)
    #define UICR_OTP_ADDR (NRF_UICR_S_BASE + offsetof(NRF_UICR_Type, OTP))
    #define UICR_OTP_SIZE (sizeof(NRF_UICR_S->OTP))
    #endif

    I am using NCS v3.2.2 as the base.
    These results confirm that I can access the OTP area if I modify the SDK.
    However, I want to avoid modifying the SDK locally, so I would like to confirm if there is an alternative method to enable this access.

    Best regards,

    a.da

  • Hi a.da,

    I will continue to help with this ticket.

    I agree with you, and this functionality seems to be missing from the SDK.

    The suggested modification you have made seems reasonable to me. I will test it and then make a PR to sdk-nrf with this change. Then the devs will review the PR to make sure we are correct, and it will eventually be merged and maintained in the SDK.

    I will link to the PR here once I made it, so you can follow the progress.

    In the meantime, I think your best option is to use your modified SDK. Then you can update once the SDK is updated to a version containing the official fix.

    Does this sound good to you?

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd, thanks for your reply.

    I am glad to hear that my suggestion was helpful and is being integrated into the official SDK.

    I really appreciate your quick response and for taking prompt action on this matter.
    I agree with the plan to use the modified SDK for the time being, and I look forward to the official SDK release that includes this fix.

    Thank you again for your excellent support!

    a.da

Related