Skip to main content
Associate
July 13, 2024
Question

OSPI_NOR usage with SBSFU (B-U585I-IOT02A)

  • July 13, 2024
  • 1 reply
  • 863 views

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

Jocelyn RICARD
ST Employee
September 4, 2024

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