This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Can't get RAM-based Secure Entry functions to work

I'm having trouble getting the Secure Entry gateway functions to work out of RAM. The nRF9160 datasheet has RAMNSC configurations, so it should be possible. We're able to get flash-based ones to work. Has anyone been able to have RAM-based Secure Entry functions?

I've confirmed the configuration of RAMNSC as well as RAMREGION in the SPU. It looks like the nRF9160 documentation has an error, however: it says the RAMNSC regions are 8K each, but there are only enough bits for 16K. Can anyone confirm if that's an error? Or perhaps it just doesn't support the full RAM range as NSC?

The only real difference I've noticed (beyond the annoying wrangling to get GCC to do what I want it to) is that there are "veneer" function calls for RAM functions that aren't used when calling the flash counterparts. In particular, it looks like the branch to the SG instruction in flash is a BL, while the branch to the SG instruction in RAM from the veneer is BX. I haven't been able to find any documentation on whether or not various branching methods work or don't work with TrustZone transitions. Is there any info on if BX will work?

  • Hi Erik,

     

    My apologies for the long waiting time. 

    I've confirmed the configuration of RAMNSC as well as RAMREGION in the SPU. It looks like the nRF9160 documentation has an error, however: it says the RAMNSC regions are 8K each, but there are only enough bits for 16K. Can anyone confirm if that's an error? Or perhaps it just doesn't support the full RAM range as NSC?

    After a bit of back-and-forth, I can confirm that the *NSC[n].SIZE registers can be configured up to 4k each.

    Each NSC function will generate a 2 word veneer (see linker symbols __sg_start / __sg_end), placed in section "sgstubs" (linker script found here). Here's an example from secure_services:

     .gnu.sgstubs.__stub
                    0x0000000000007fe0       0x18 linker stubs
                    0x0000000000007fe0                spm_firmware_info_nse
                    0x0000000000007fe8                spm_request_random_number_nse
                    0x0000000000007ff0                spm_request_read_nse
                    0x0000000000008000                __sg_end = .
                    0x0000000000000020                __sg_size = (__sg_end - __sg_start)
                    0x0000000000008000                . = ALIGN (0x8000)
                    0x0000000000000020                __nsc_size = (. - __sg_start)
                    0x0000000000000001                ASSERT (((__sg_size == 0x0) || ((((0x1 << LOG2CEIL ((0x8000 - (__sg_start % 0x8000)))) == (0x8000 - (__sg_start % 0x8000))) && ((0x8000 - (__sg_start % 0x8000)) >= 0x20)) && ((0x8000 - (__sg_start % 0x8000)) <= 0x1000))), The Non-Secure Callable region size must be a power of 2 between 32 and 4096 bytes.)

    This is a limiting factor on the total amount of NSCallable functions, where its maximum allocation is 512 functions (4096 / 8 bytes) per region.

     

    The only real difference I've noticed (beyond the annoying wrangling to get GCC to do what I want it to) is that there are "veneer" function calls for RAM functions that aren't used when calling the flash counterparts. In particular, it looks like the branch to the SG instruction in flash is a BL, while the branch to the SG instruction in RAM from the veneer is BX. I haven't been able to find any documentation on whether or not various branching methods work or don't work with TrustZone transitions. Is there any info on if BX will work?

    I am sorry, but I do not have an update for this issue yet. I'm still checking internally. Consider this item still open from our side.

     

    Kind regards,

    Håkon 

  • Hi,

     

    My apologies for the late response.

    I am in contact with key personnel in R&D related to your questions, and I hope to give you a response within a few working days, and if not; a status on the progress.

     

    Kind regards,

    Håkon

  • Two updates:

    1) Looks like RAMNSC will hold more than 4 bits. I would assume the documentation (and the "mask" in nrf9160.h) is incorrect that it only holds 4 bits, but rather it holds 5 and is in increments of 8K still?

    2) I made a manual "veneer" RAM function that used BX to jump to the SG instruction in flash, but that succeeded, unlike when in RAM. So, it seems like there's no limitation on BL versus BX. Which means I've now run out of ideas as to what's going on.

    Hopefully either someone in the community or at least at Nordic has accomplished this at some point...

Related