Prot (Protection Unit)

group group_prot

The Protection Unit driver provides an API to configure the Memory Protection Units (MPU), Shared Memory Protection Units (SMPU), and Peripheral Protection Units (PPU).

These are separate from the ARM Core MPUs and provide additional mechanisms for securing resource accesses. The Protection units address the following concerns in an embedded design:

  • Security requirements: This includes the prevention of malicious attacks to access secure memory or peripherals.

  • Safety requirements: This includes detection of accidental (non-malicious) SW errors and random HW errors. It is important to enable failure analysis to investigate the root cause of a safety violation.

The functions and other declarations used in this driver are in cy_prot.h. You can include cy_pdl.h to get access to all functions and declarations in the PDL.

Protection Types

Protection units are hardware configuration structures that control bus accesses to the resources that they protect. By combining these individual configuration structures, a system is built to allow strict restrictions on the capabilities of individual bus masters (e.g. CM0+, CM4, Crypt) and their operating modes. This architecture can then be integrated into the overall security system of the end application. To build this system, 3 main protection unit types are available; MPU, SMPU and PPU. When a resource is accessed (memory/register), it must pass the evaluation performed for each category. These access evaluations are prioritized, where MPU has the highest priority, followed by SMPU, followed by PPU. i.e. if an SMPU and a PPU protect the same resource and if access is denied by the SMPU, then the PPU access evaluation is skipped. This can lead to a denial-of-service scenario and the application should pay special attention in taking ownership of the protection unit configurations.

Memory Protection

Memory access control for a bus master is controlled using an MPU. These are most often used to distinguish user and privileged accesses from a single bus master such as task switching in an OS/kernel. For ARM cores (CM0+, CM4), the core MPUs are used to perform this task. For other non-ARM bus masters such as Crypto, MPU structs are available, which can be used in a similar manner as the ARM core MPUs. These MPUs however must be configured by the ARM cores. Other bus masters that do not have an MPU, such as DMA (DW), inherit the access control attributes of the bus master that configured the channel. Also note that unlike other protection units, MPUs do not support protection context evaluation. MPU structs have a descending priority, where larger index struct has higher priority access evaluation over lower index structs. E.g. MPU_STRUCT15 has higher priority than MPU_STRUCT14 and its access will be evaluated before MPU_STRUCT14. If both target the same memory, then the higher index (MPU_STRUCT15) will be used, and the lower index (MPU_STRUCT14) will be ignored.

Shared Memory Protection

In order to protect a region of memory from all bus masters, an SMPU is used. This protection effectively allows only those with correct bus master access settings to read/write/execute the memory region. This type of protection is used in general memory such as Flash and SRAM. Peripheral registers are best configured using the peripheral protection units instead. SMPU structs have a descending priority, where larger index struct has higher priority access evaluation over lower index structs. E.g. SMPU_STRUCT15 has higher priority than SMPU_STRUCT14 and its access will be evaluated before SMPU_STRUCT14. If both target the same memory, then the higher index (MPU_STRUCT15) will be used, and the lower index (SMPU_STRUCT14) will be ignored.

Peripheral Protection

Peripheral protection is provided by PPUs and allow control of peripheral register accesses by bus masters. Four types of PPUs are available.

  • Fixed Group (GR) PPUs are used to protect an entire peripheral MMIO group from invalid bus master accesses. The MMIO grouping information and which resource belongs to which group is device specific and can be obtained from the device technical reference manual (TRM). Group PPUs have the highest priority in the PPU category. Therefore their access evaluations take precedence over the other types of PPUs.

  • Programmable (PROG) PPUs are used to protect any peripheral memory region in a device from invalid bus master accesses. It is the most versatile type of peripheral protection unit. Programmable PPUs have the second highest priority and take precedence over Region PPUs and Slave PPUs. Similar to SMPUs, higher index PROG PPUs have higher priority than lower indexes PROG PPUs.

  • Fixed Region (RG) PPUs are used to protect an entire peripheral slave instance from invalid bus master accesses. For example, TCPWM0, TCPWM1, SCB0, and SCB1, etc. Region PPUs have the third highest priority and take precedence over Slave PPUs.

  • Fixed Slave (SL) PPUs are used to protect specified regions of peripheral instances. For example, individual DW channel structs, SMPU structs, and IPC structs, etc. Slave PPUs have the lowest priority in the PPU category and therefore are evaluated last.

Protection Context

Protection context (PC) attribute is present in all bus masters and is evaluated when accessing memory protected by an SMPU or a PPU. There are no limitations to how the PC values are allocated to the bus masters and this makes it possible for multiple bus masters to essentially share protection context values. The exception to this rule is the PC value 0.

PC=0

Protection context 0 is a hardware controlled protection context update mechanism that allows only a single entry point for transitioning into PC=0 value. This mechanism is only present for the secure CM0+ core and is a fundamental feature in defining a security solution. While all bus masters are configured to PC=0 at device boot, it is up to the security solution to transition these bus masters to PC!=0 values. Once this is done, those bus masters can no longer revert back to PC=0 and can no longer access resources protected at PC=0.

In order to enter PC=0, the CM0+ core must assign an interrupt vector or an exception handler address to the CPUSS.CM0_PC0_HANDLER register. This allows the hardware to check whether the executing code address matches the value in this register. If they match, the current PC value is saved and the CM0+ bus master automatically transitions to PC=0. It is then up to the executing code to decide if and when it will revert to a PC!=0 value. At that point, the only way to re-transition to PC=0 is through the defined exception/interrupt handler.

note

Devices with CPUSS ver_2 have a hardware-controlled protection context update mechanism that allows only a single-entry point for transitioning into PC=0, 1, 2, and 3. The interrupt vector or the exception handler address can be assigned to the CPUSS.CM0_PC0_HANDLER, CPUSS.CM0_PC1_HANDLER, CPUSS.CM0_PC2_HANDLER or CPUSS.CM0_PC2_HANDLER register. Also, the control register CPUSS.CM0_PC_CTL of the CM0+ protection context must be set: bit 0 - the valid field for CM0_PC0_HANDLER, bit 1 - the valid field for CM0_PC1_HANDLER, bit 2 - the valid field for CM0_PC2_HANDLER, and bit 3 - the valid field for CM0_PC3_HANDLER.

The example of using of the single entry point mechanism is shown below.

/* The code below demonstrates the protection context update 
 * mechanism that allows a single entry point for transitioning 
 * from PC = 1 into PC=0 value.
 */
    
/* Note: "cy_ipc_drv.h", "cy_prot.h" and "cy_sysint.h" should be included. */

#define IPC_INTR_NR 10u

uint32_t pc; /* The active protection context of a master. */
bool isrTriggered = false; /* The ISR flag. */

/* IPC ISR handler.  */
void isrPC0(void)
{
    /* The protection context is 0 here. */
    
    isrTriggered = true; /* Set flag that ISR is triggered. */

    Cy_IPC_Drv_ClearInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(IPC_INTR_NR), 0u, 1u);
}

int main(void)
{
    __enable_irq(); /* Enable global interrupts. */
    #if (CY_CPU_CORTEX_M0P)
        /* Enable CM4. CY_CORTEX_M4_APPL_ADDR must be updated if CM4 memory layout is changed. */
        Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR); 
    #endif

    /* Assign the isrPC0 interrupt vector to the CM0_PC0_HANDLER register. */
    CPUSS->CM0_PC0_HANDLER = (uint32_t)&isrPC0;
    
    /* Configure the IPC interrupt handler. */
    Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(IPC_INTR_NR), 0u, 1u);
    cy_stc_sysint_t intr = {
        #if (CY_CPU_CORTEX_M0P)
            .intrSrc = NvicMux5_IRQn,
            .cm0pSrc = cpuss_interrupts_ipc_10_IRQn,
        #else
            .intrSrc = cpuss_interrupts_ipc_10_IRQn,
        #endif /* (CY_CPU_CORTEX_M0P) */
        .intrPriority = 2u
    };
    Cy_SysInt_Init(&intr, isrPC0);
    NVIC_EnableIRQ(intr.intrSrc);

    /* Configure the bus master to allow setting PC to PC=1 and PC=2 */
    Cy_Prot_ConfigBusMaster(CPUSS_MS_ID_CM0, true, true, CY_PROT_PCMASK1 | CY_PROT_PCMASK2);

    /* Set the CM0+ PC value to 1 */
    if(CY_PROT_SUCCESS != Cy_Prot_SetActivePC(CPUSS_MS_ID_CM0, CY_PROT_PC1))
    {
        /* Insert error handling */
    }

    pc = Cy_Prot_GetActivePC(CPUSS_MS_ID_CM0); /* pc should equal to 1 */

    Cy_IPC_Drv_SetInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(IPC_INTR_NR), 0u, 1u); /* Trigger the ISR */
  
    while(!isrTriggered)
    {
        /* Wait until isrPC0 ISR entered. */
    }
    
    pc = Cy_Prot_GetActivePC(CPUSS_MS_ID_CM0); /* pc should equal to 0 */

    for(;;)
    {

    }
}

Access Evaluation

Each protection unit is capable of evaluating several access types. These can be used to build a system of logical evaluations for different kinds of bus master modes of operations. These access types can be divided into three broad access categories.

  • User/Privileged access: The ARM convention of user mode versus privileged mode is applied in the protection units. For ARM cores, switching between user and privileged modes is handled by updating its Control register or by exception entries. Other bus masters such as Crypto have their own user/privileged settings bit in the bus master control register. This is then controlled by the ARM cores. Bus masters that do not have user/privileged access controls, such as DMA, inherit their attributes from the bus master that configured it. The user/privileged distinction is used mainly in the MPUs for single bus master accesses but they can also be used in all other protection units.

  • Secure/Non-secure access: The secure/non-secure attribute is another identifier to distinguish between two separate modes of operations. Much like the user/privileged access, the secure/non-secure mode flag is present in the bus master control register. The ARM core does not have this attribute in its control register and must use the bus master control register instead. Bus masters that inherit their attributes, such as DMA, inherit the secure/non-secure attribute. The primary use-case for this access evaluation is to define a region to be secure or non-secure using an SMPU or a PPU. A bus master with a secure attribute can access both secure and non-secure regions, whereas a bus master with non-secure attribute can only access non-secure regions.

  • Protection Context access: Protection Context is an attribute that serves two purposes; To enter the hardware controlled secure PC=0 mode of operation from non-secure modes and to provide finer granularity to the bus master access definitions. It is used in SMPU and PPU configuration to control which bus master protection context can access the resources that they protect.

Protection Structure

Each protection unit is comprised of a master struct and a slave struct pair. The exception to this rule is MPU structs, which only have the slave struct equivalent. The protection units apply their access evaluations in a decreasing index order. For example, if SMPU1 and SMPU2 both protect a specific memory region, the the higher index (SMPU2) will be evaluated first. In a secure system, the higher index protection structs would then provide the high level of security and the lower indexes would provide the lower level of security. Refer to the Protection Types section for more information.

Slave Struct

The slave struct is used to configure the protection settings for the resource of interest (memory/registers). Depending on the type of protection unit, the available attributes differ. However all Slave protection units have the following general format.

Slave Struct Address Definition

  • Address: For MPU, SMPU and PROG PPU, the address field is used to define the base memory region to apply the protection. This field has a dependency on the region size, which dictates the alignment of the protection unit. E.g. if the region size is 64KB, the address field is aligned to 64KB. Hence the lowest bits [15:0] are ignored. For instance, if the address is defined at 0x0800FFFF, the protection unit would apply its protection settings from 0x08000000. Thus alignment must be checked before defining the protection address. The address field for other PPUs are not used, as they are bound to their respective peripheral memory locations.

  • Region Size: For MPU, SMPU and PROG PPU, the region size is used to define the memory block size to apply the protection settings, starting from the defined base address. It is also used to define the 8 sub-regions for the chosen memory block. E.g. If the region size is 64KB, each subregion would be 8KB. This information can then be used to disable the protection settings for select subregions, which gives finer granularity to the memory regions. PPUs do not have region size definitions as they are bound to their respective peripheral memory locations.

  • Subregions: The memory block defined by the address and region size fields is divided into 8 (0 to 7) equally spaced subregions. The protection settings of the protection unit can be disabled for these subregions. E.g. for a given 64KB of memory block starting from address 0x08000000, disabling subregion 0 would result in the protection settings not affecting the memory located between 0x08000000 to 0x08001FFF. PPUs do not have subregion definitions as they are bound to their respective peripheral memory locations.

Slave Struct Attribute Definition

  • User Permission: Protection units can control the access restrictions of the read (R), write (W) and execute (X) (subject to their availability depending on the type of protection unit) operations on the memory block when the bus master is operating in user mode. PPU structs do not provide execute attributes.

  • Privileged Permission: Similar to the user permission, protection units can control the access restrictions of the read (R), write (W) and execute (X) (subject to their availability depending on the type of protection unit) operations on the memory block when the bus master is operating in privileged mode. PPU structs do not provide execute attributes.

  • Secure/Non-secure: Applies the secure/non-secure protection settings to the defined memory region. Secure protection allows only bus masters that access the memory with secure attribute. Non-secure protection allows bus masters that have either secure or non-secure attributes.

  • PC match: This attribute allows the protection unit to either apply the 3 access evaluations (user/privileged, secure/non-secure, protection context) or to only provide an address range match. This is useful when multiple protection units protect an overlapping memory region and it’s desirable to only have access evaluations applied from only one of these protection units. For example, SMPU1 protects memory A and SMPU2 protects memory B. There exists a region where A and B intersect and this is accessed by a bus master. Both SMPU1 and SMPU2 are configured to operate in “match” mode. In this scenario, the access evaluation will only be applied by the higher index protection unit (i.e. SMPU2) and the access attributes of SMPU1 will be ignored. If the bus master then tries to access a memory region A (that does not intersect with B), the access evaluation from SMPU1 will be used. Note that the PC match functionality is only available in SMPUs.

  • PC mask: Defines the allowed protection context values that can access the protected memory. The bus master attribute must be operating in one of the protection context values allowed by the protection unit. E.g. If SMPU1 is configured to allow only PC=1 and PC=5, a bus master (such as CM4) must be operating at PC=1 or PC=5 when accessing the protected memory region.

Master Struct

The master struct protects its slave struct in the protection unit. This architecture makes possible for the slave configuration to be protected from reconfiguration by an unauthorized bus master. The configuration attributes and the format are similar to that of the slave structs.

Master Struct Address Definition

  • Address: The address definition for master struct is fixed to the slave struct that it protects.

  • Region Size: The region size is fixed to 256B region.

  • Subregion: This value is fixed to only enable the first 64B subregions, which applies the protection settings to the entire protection unit.

Master Struct Attribute Definition

  • User Permission: Only the write (W) access attribute is allowed for master structs, which controls whether a bus master operating in user mode has the write access.

  • Privileged Permission: Only the write (W) access attribute is allowed for master structs, which controls whether a bus master operating in privileged mode has the write access.

  • Secure/Non-Secure: Same behavior as slave struct.

  • PC match: Same behavior as slave struct.

  • PC mask: Same behavior as slave struct.

Driver Usage

Setting up and using protection units can be summed up in four stages:

  • Configure the bus master attributes. This defines the capabilities of the bus master when trying to access the protected resources.

  • Configure the slave struct of a given protection unit. This defines the protection attributes to be applied to the bus master accessing the protected resource and also defines the size and location of the memory block to protect.

  • Configure the master struct of the protection unit. This defines the attributes to be checked against the bus master that is trying to reconfigure the slave struct.

  • Set the active PC value of the bus master and place it in the correct mode of operation (user/privileged, secure/non-secure). Then access the protected memory.

For example, by configuring the CM0+ bus master configuration to allow only protection contexts 2 and 3, the bus master will be able to set its protection context only to 2 or 3. During runtime, the CM0+ core can set its protection context to 2 by calling Cy_Prot_SetActivePC() and access all regions of protected memory that allow PC=2. A fault will be triggered if a resource is protected with different protection settings.

Note that each protection unit is distinguished by its type (e.g. PROT_MPU_MPU_STRUCT_Type). The list of supported protection units can be obtained from the device definition header file. Choose a protection unit of interest, and call its corresponding Cy_Prot_Config<X>Struct() function with its software protection unit configuration structure populated. Then enable the protection unit by calling the Cy_Prot_Enable<X>Struct() function.

Note that the bus master ID (en_prot_master_t) is defined in the device config header file.

Configuration Considerations

When a resource (memory/register) is accessed, it must pass evaluation of all three protection unit categories in the following order: MPU->SMPU->PPU. The application should ensure that a denial-of-service attack cannot be made on the PPU by the SMPU. For this reason, it is recommended that the application’s security policy limit the ability for the non-secure client from configuring the SMPUs.

Within each category, the priority hierarchy must be carefully considered to ensure that a higher priority protection unit cannot be configured to override the security configuration of a lower index protection unit. Therefore if a lower index protection unit is configured, relevant higher priority indexes should be configured (or protected from unwanted reconfiguration). E.g. If a PPU_SL is configured, PPU_RG and PPU_GR that overlaps with the protected registers should also be configured. SImilar to SMPUs, it is recommended that the configuration of PPU_PROG be limited. Otherwise they can be used to override the protection settings of PPU_RG and PPU_SL structs.

All bus masters are set to PC=0 value at device reset and therefore have full access to all resources. It is up to the security solution to implement what privileges each bus master has. Once transitioned to a PC!=0 value, only the CM0+ core is capable of re-entering the PC=0 via the user-defined exception entry in the CPUSS.CM0_PC0_HANDLER register.

  • SMPU 15 and 14 are configured and enabled to only allow PC=0 accesses at device boot.

  • PROG PPU 15, 14, 13 and 12 are configured to only allow PC=0 accesses at device boot.

  • GR PPU 0 and 2 are configured to only allow PC=0 accesses at device boot.

More Information

Refer to Technical Reference Manual (TRM) and the device datasheet.

Changelog

Version

Changes

Reason for Change

1.60

Modified Cy_Prot_ConfigPpuProgMasterAtt() & Cy_Prot_ConfigPpuFixedMasterAtt() functions to ignore unavailable protection context.

Defect fix.

1.50

Updated implementation of the Cy_Prot_ConfigPpuProgMasterAtt(), Cy_Prot_ConfigPpuProgSlaveAtt(), Cy_Prot_ConfigPpuFixedMasterAtt(), and Cy_Prot_ConfigPpuFixedSlaveAtt() to start registers update from the higher-numbered PCs in order to prevent lockup for the case when registers are configured to read-only.

Defect fix.

Added macros for memory region size setting in cy_en_prot_size_t initialization.

The macros can be useful for the pre-processor checks.

Fixed/Documented MISRA 2012 violations.

MISRA 2012 compliance.

1.40

Added PSoC 64 devices support.

1.30.3

Minor documentation updates.

Documentation enhancement.

1.30.2

Clarified the description of the next API functions: Cy_Prot_ConfigPpuProgMasterAtt,
Cy_Prot_ConfigPpuProgSlaveAtt, Cy_Prot_ConfigPpuFixedMasterAtt, Cy_Prot_ConfigPpuFixedSlaveAtt.

API enhancement based on usability feedback.

1.30.1

Snippet updated.

Old snippet outdated.

1.30

Defect in Cy_Prot_GetPpuProgStruct() function due to faulty defines is fixed.

Defect fixing.

1.20

Flattened the organization of the driver source code into the single source directory and the single include directory.

Driver library directory-structure simplification.

Added functions for CPUSS ver_2:

Added support for CPUSS ver_2.

Added register access layer. Use register access macros instead of direct register access using dereferenced pointers.

Makes register access device-independent, so that the PDL does not need to be recompiled for each supported part number.

1.10

Added input parameter validation to the API functions.
cy_en_prot_pcmask_t, cy_en_prot_subreg_t and cy_en_prot_pc_t types are set to typedef enum

Improved debugging capability

Expanded documentation

1.0

Initial version

API Reference