2024-07-13 09:37 AM
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?
2024-09-04 10:33 AM
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