General concepts

nRF54L15 | nRF54L10 | nRF54L05 Datasheet

The SPU provides the register interface to configure and enforce the access privileges per peripheral, and where applicable, individual features of the peripheral such as GPIO pins, DPPI channels, etc.

Any accesses to a peripheral or a peripheral feature are validated against the SPU configuration for the security attributes.

Security attributes of a peripheral normally applies to all registers of the peripheral. However, some peripherals have split security to individual features within the peripheral, such as individual pins or DPPI channels. For these split feature peripherals, access is granted on a per-bit or per-register level. Unless mentioned otherwise, the term peripheral is used in the remainder of this section to refer to both a peripheral and an individual peripheral feature.

Each APB bus has its own SPU instance that controls the resource of that bus. The SPU must be configured for security attributes of the peripherals. The SPU is always a secure peripheral.
  • See Instantiation to find the SPU instance used by the peripheral.
  • The APB bus number can be extracted from the peripheral address. See Address format to find the APB bus number for a peripheral.
  • See Block diagram for an overview over APB buses, the peripherals on that bus, and their controlling SPU instance.

See Address format for information on extracting the Peripheral slave index from a peripheral address.

The following example shows which SPU instance to use for SAADC peripheral to configure the peripheral permissions using PERIPH[n].PERM:

        #define SPU_CORTEX_ADDRESS_REGION    (0x50000000)

        uint32_t perip_addr = NRF_SAADC_S_BASE;


        uint32_t apb_bus_number = (perip_addr & 0x00FC0000);
        uint32_t apb_slave_index = (perip_addr & 0x0003F000) >> 12;

        // Get the address to the SPU instance
        NRF_SPU_Type *p_spu = (NRF_SPU_Type*)(SPU_CORTEX_ADDRESS_REGION |
        apb_bus_number);

        // Configure PERIPH[n].PERM.SECATTR to secure for SAADC
        p_spu->PERIPH[apb_slave_index].PERM =
        (p_spu->PERIPH[apb_slave_index].PERM &
        ~SPU_PERIPH_PERM_SECATTR_Msk) |
        (SPU_PERIPH_PERM_SECATTR_Secure <<
        SPU_PERIPH_PERM_SECATTR_Pos)
      

See Instantiation to find the value of SLAVE_BITS for each SPU instance.

SPU supports secure and non-secure accesses based on TrustZone. On each access to a peripheral address, the security state of the master initiating the transaction is verified against the SPU security attribute configuration of the peripheral. The following figure shows a simplified view of the SPU registers controlling several internal modules.

Figure 1. Simplified view of peripherals and peripheral features using SPU
Page-1 Sheet.6 SPU SPU Sheet.7 APB bridge APB bridge Sheet.8 Sheet.9 Sheet.10 APB APB Sheet.11 Peripherals Peripherals Sheet.12 Sheet.13 APB APB Sheet.14 Sheet.15 Feature control Feature control Sheet.16 PERIPH[n].PERM PERIPH[n].PERM Sheet.17 FEATURE.xxxx FEATURE.xxxx
The protection logic implements a read-as-zero/write-ignore (RAZ/WI) policy:
  • A read operation that is not allowed by the SPU will always return a zero value on the bus, preventing information leak.
  • A write operation that is not allowed by the SPU will be ignored.

An access error on peripherals managed by an SPU result in the PERIPHACCERR event on the SPU.