cancel
Showing results for 
Search instead for 
Did you mean: 

OSPI_NOR usage with SBSFU (B-U585I-IOT02A)

soutys
Associate

Hi, I've decided to create a new post based on the similar one (https://community.st.com/t5/stm32-mcus-security/solved-stm32u5-tfm-example-b-u585i-iot02a-memory-mapped-psram/td-p/108722) which has been solved but doesn't work for me.

The problem is as follows:
- I want to run my application on the B-U585I-IOT02A board that uses the BSP_OSPI_NOR (OSPI2) with the external flash memory with the following parameters:

 

 

BSP_OSPI_NOR_Init_t init_params = {
      .InterfaceMode = BSP_OSPI_NOR_OPI_MODE,
      .TransferRate = BSP_OSPI_NOR_STR_TRANSFER
};
BSP_OSPI_NOR_Init(0, &init_params);

 

 

- When using the standard application (TZEN=0, no SBSFU), everything works correctly - the BSP_OSPI_NOR_Init returns 0 and writes/reads works correctly

- When using the SBSFU application (https://github.com/STMicroelectronics/STM32CubeU5/tree/v1.0.2/Projects/B-U585I-IOT02A/Applications/SBSFU version 1.0.2) I can't initialize the OSPI in the NonSecure application. I always get the "-5" return value (BSP_ERROR_COMPONENT_FAILURE) and read/writes don't work (but no HardFault happens)

- My changes to the "Projects/B-U585I-IOT02A/SBSFU_Boot/Src/low_level_security.c" file (inspired by the mentioned post) are listed below:

 

 

const struct mpu_armv8m_region_cfg_t region_cfg_init_ns[] = {
           /* forbid execution on non secure FLASH /RAM in case of jump in non secure */
           /* Non Secure MPU  background all access in priviligied */
           /* reduced execution to all flash during control */
           {
               0,
               FLASH_BASE_NS + NS_IMAGE_PRIMARY_PARTITION_OFFSET,
               FLASH_BASE_NS + NS_IMAGE_PRIMARY_PARTITION_OFFSET + FLASH_NS_PARTITION_SIZE - 1,
               MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX,
               MPU_ARMV8M_XN_EXEC_NEVER,
               MPU_ARMV8M_AP_RW_PRIV_ONLY,
               MPU_ARMV8M_SH_NONE,
#ifdef FLOW_CONTROL
               FLOW_STEP_MPU_NS_I_EN_R0,
               FLOW_CTRL_MPU_NS_I_EN_R0,
               FLOW_STEP_MPU_NS_I_CH_R0,
               FLOW_CTRL_MPU_NS_I_CH_R0,
#endif /* FLOW_CONTROL */
           },
// CHANGE START ////////////////////////////////////////////////////////
          {
            1,
            OCTOSPI2_BASE,
            OCTOSPI2_BASE + (32 * 1024 * 1024) - 1,
            MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX,
            MPU_ARMV8M_XN_EXEC_OK,
            MPU_ARMV8M_AP_RW_PRIV_UNPRIV,
            MPU_ARMV8M_SH_NONE,
#ifdef FLOW_CONTROL
            FLOW_STEP_MPU_NS_I_EN_R1,
            FLOW_CTRL_MPU_NS_I_EN_R1,
            FLOW_STEP_MPU_NS_I_CH_R1,
            FLOW_CTRL_MPU_NS_I_CH_R1,
#endif /* FLOW_CONTROL */
// CHANGE END ////////////////////////////////////////////////////////
           },
           /* Forbid execution on full SRAM area */
           {
               2,
#ifdef TFM_ERROR_HANDLER_NON_SECURE
               SRAM1_BASE_NS + (~MPU_RBAR_BASE_Msk) + 1,
#else
               SRAM1_BASE_NS,
#endif /*   TFM_ERROR_HANDLER_NON_SECURE */
               SRAM4_BASE_NS + _SRAM4_SIZE_MAX - 1,
               MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
               MPU_ARMV8M_XN_EXEC_NEVER,
               MPU_ARMV8M_AP_RW_PRIV_ONLY,
               MPU_ARMV8M_SH_NONE,
#ifdef FLOW_CONTROL
               FLOW_STEP_MPU_NS_I_EN_R2,
               FLOW_CTRL_MPU_NS_I_EN_R2,
               FLOW_STEP_MPU_NS_I_CH_R2,
               FLOW_CTRL_MPU_NS_I_CH_R2,
#endif /* FLOW_CONTROL */
           },
           /* forbid secure peripheral execution */
           {
               3,
               PERIPH_BASE_NS,
               PERIPH_BASE_NS + 0xFFFFFFF,
               MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX,
               MPU_ARMV8M_XN_EXEC_NEVER,
               MPU_ARMV8M_AP_RW_PRIV_ONLY,
               MPU_ARMV8M_SH_NONE,
#ifdef FLOW_CONTROL
               FLOW_STEP_MPU_NS_I_EN_R3,
               FLOW_CTRL_MPU_NS_I_EN_R3,
               FLOW_STEP_MPU_NS_I_CH_R3,
               FLOW_CTRL_MPU_NS_I_CH_R3,
#endif /* FLOW_CONTROL */
           }
};

...

static void sau_and_idau_cfg(void)
{
  uint32_t i;
  uint32_t rnr;
  uint32_t rbar;
  uint32_t rlar;
  uint32_t rnr_reg;
  uint32_t rbar_reg;
  uint32_t rlar_reg;
  uint32_t ctrl_reg;

  /* configuration stage */
  if (uFlowStage == FLOW_STAGE_CFG)
  {
    /* Disable SAU */
    TZ_SAU_Disable();

    for (i = 0; i < ARRAY_SIZE(sau_init_cfg); i++)
    {
      SAU->RNR = sau_init_cfg[i].RNR;
      SAU->RBAR = sau_init_cfg[i].RBAR & SAU_RBAR_BADDR_Msk;
      SAU->RLAR = (sau_init_cfg[i].RLAR & SAU_RLAR_LADDR_Msk) |
                  (sau_init_cfg[i].nsc ? SAU_RLAR_NSC_Msk : 0U) |
                  SAU_RLAR_ENABLE_Msk;

      /* Execution stopped if flow control failed */
      FLOW_CONTROL_STEP(uFlowProtectValue, sau_init_cfg[i].flow_step_enable,
                                           sau_init_cfg[i].flow_ctrl_enable);
    }
// CHANGE START ////////////////////////////////////////////////////////
    SAU->RNR  = (6 & SAU_RNR_REGION_Msk);
    SAU->RBAR = (OCTOSPI1_BASE & SAU_RBAR_BADDR_Msk);
    SAU->RLAR = (  ((OCTOSPI1_BASE + (8 * 1024 * 1024) - 1) & SAU_RLAR_LADDR_Msk)
                 | ((0 << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk)
                 | 1U);
 
    SAU->RNR  = (7 & SAU_RNR_REGION_Msk);
    SAU->RBAR = (OCTOSPI2_BASE & SAU_RBAR_BADDR_Msk);
    SAU->RLAR = (  ((OCTOSPI2_BASE + (32 * 1024 * 1024) - 1) & SAU_RLAR_LADDR_Msk)
                 | ((0 << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk)
                 | 1U);
 
    MPCWM_ConfigTypeDef MPCWM_Desc =
    {
        .AreaId = GTZC_TZSC_MPCWM_ID1,
		.AreaStatus = 1,
		.Offset = 0,
		.Attribute = GTZC_TZSC_MPCWM_REGION_NSEC | GTZC_TZSC_MPCWM_REGION_NPRIV,
		.Length = (8 * 1024 * 1024),
		.Lock = GTZC_TZSC_MPCWM_LOCK_ON,
    };
 
    HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes(OCTOSPI1_BASE, &MPCWM_Desc);
 
    MPCWM_Desc.Offset = 0;
    MPCWM_Desc.Length = (32 * 1024 * 1024);
    HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes(OCTOSPI2_BASE, &MPCWM_Desc);
// CHANGE END ////////////////////////////////////////////////////////

    /* Force memory writes before continuing */
    __DSB();
    /* Flush and refill pipeline with updated permissions */
    ...
}

 

 

- But I still can't get my BSP_OPSI to work. Probably some additional configuration needs to be performed, but I don't know where to look for them.

Are there any tips you can give me to make my OSPI_NOR working?

1 REPLY 1
Jocelyn RICARD
ST Employee

Hello @soutys ,

Sorry for late answer.

First I would suggest using STM32CubeMX to create a TZ project generating secure and non secure applications.

The tool will generate the code necessary to make OSPI accessible in non secure: basically set GPIOs as non secure I guess, but may need other setup.

In general, you will need to setup the secure configuration in the secure application : split peripherals between secure and non secure.

Once your project works without SBSFU then you can integrate it as secure + non secure application launched by SBSFU.

Best regards

Jocelyn