cancel
Showing results for 
Search instead for 
Did you mean: 

[SOLVED] STM32U5 TFM example (B-U585I-IOT02A) memory mapped PSRAM not accessible

BKara.3
Associate II

We managed to successfully run TFM_SBSFU example for the IOT02A board. We are using latest STM32Cube_FW_U5_V1.2.0.

The problem is that we do not have access to PSRAM from NonSecure application when in memory mapped mode.

We implemented PSRAM init by importing drivers from BSP package into TFM Example, and initializing PSRAM imidiately in main, adter COM_Init(). For the test, we tried without changing GTZC_TZSC_MPCWM and SAU registers from secure app.

As expected, we are getting Secure Failed handler, with the information that we tried to access protected memory. All as expected.

Than we implemented memory area unprotection in TFM_Appli_Secure, by adding next line of codes in function:

fih_int sau_and_idau_cfg(void)
{
.
.
.
.   
    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);
    }
 
// ADDED LINES TO UNLOCK OCTOSPI1_BASE and OCTOSPI2_BASE
 
    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);
 
//ADDITION DONE
.
.
.
.
}

By our understanding, this should be enough to have OCTOSPI1_BASE, and OCTOSPI2_BASE unlocked for access from TFM_Appli_NonSecure.

We did not changed anything else.

We are able to write to and read from PSRAM in command mode from TFM_Appli_NonSecure.

We are able to see PSRAM content in memory mapped mode from debugger in Memory View from TFM_Appli_NonSecure.

But we are not able to following code to access PSRAM. Exact the same code is working correctly in standalone nonsecure TZEN=0 application.

uint8_t aTxBuffer_ospi[] =
		" ****Memory-mapped OSPI communication****  "
		"****Memory-mapped OSPI communication****  "
		"****Memory-mapped OSPI communication****  "
		"****Memory-mapped OSPI communication****  "
		"****Memory-mapped OSPI communication****  "
		"****Memory-mapped OSPI communication****     ";
 
uint8_t *mem_addr;
uint8_t temp;
.
.
.
.
  ret = BSP_OSPI_RAM_Init(0);
  if(ret != BSP_ERROR_NONE)
  {
	  DEBUG_ERROR("Deinitialization failed Failed\n");
	  return ret;
  }
 
  ret = BSP_OSPI_RAM_EnableMemoryMappedMode(0);
  if(ret != BSP_ERROR_NONE)
  {
	  DEBUG_ERROR("Enable Memory Mapped Mode: FAILED.\n");
	  DEBUG_ERROR("Test Aborted.\n");
	  error_code++;
  }
 
  if(error_code == 0)
  {
    /* Writing Sequence ----------------------------------------------- */
    mem_addr = (uint8_t *)(OCTOSPI1_BASE);
    for (uint16_t index = 0; index < 0x100; index++)
    {
		*mem_addr = aTxBuffer_ospi[index]; // <--POINT OF HardFault!!!
		mem_addr++;
    }
 
    /* In memory-mapped mode, not possible to check if the memory is ready
    after the programming. So a delay corresponding to max page programming
    time is added */
    HAL_Delay(100);
 
    /* Reading Sequence ----------------------------------------------- */
    mem_addr = (uint8_t *)(OCTOSPI1_BASE);
    for (index = 0; index < 0x100; index++)
    {
      temp = *mem_addr; //<--POINT OF HardFault IF WRITING SEQUENCE COMMENTED OUT!!!
      if (temp != aTxBuffer_ospi[index])
      {
    	  DEBUG_ERROR("Memory mapped read failed.\n");
      }
      mem_addr++;
    }
    DEBUG_INFO("OSPI RAM Memory Mapped: Successful\n");
  }
.
.
.

Failure is HardFault, but not able to get anything from stack, it looks like corrupted. HardFault handler is enabled in TFM_Appli_Secure. We tried by increasing stack, and heap for all application, but no luck.

It looks like we are missing important step in enabling NonSecure access to memory area.

Any help?

1 ACCEPTED SOLUTION

Accepted Solutions
Frantz LEFRERE
ST Employee

Dear @BKara.3​ 

as stated on the support channel the issue is that by the default mpu of the non secure is disable so you need to define a region for external memory.

You can add a region in region_cfg_init_ns :

{

1,

0x90000000,

0x90800000-1,

MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX,

MPU_ARMV8M_XN_EXEC_OK,

MPU_ARMV8M_AP_RW_PRIV_ONLY,

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 */

},

Best regards.

View solution in original post

6 REPLIES 6
BKara.3
Associate II

As an effort from our side, we have also run SBSFU example for the same board (B-U585I-IOT02A). With the same setup (SBSFU + imported OSPI driver from BSP example, and ospi_ram.c for tests), we again are not able to access OSPI ram in memory mapped mode from NonSecure app despite the fact everything set up as in ref manual.

Anyone from ST willing to help, or give a comment?

Is this known issue, or there is missing bits and pieces on our side.

Thanks for help.

Frantz LEFRERE
ST Employee

Hello @BKara.3​ 

I've sent your a file transfer request by mail ( thanks Secure File transfer tool) to get you SBSU code.

As soon as I can reproduce, I could investigate on my side.

Response and files sent.

​Thanks for help.

Frantz LEFRERE
ST Employee

Dear @BKara.3​ 

as stated on the support channel the issue is that by the default mpu of the non secure is disable so you need to define a region for external memory.

You can add a region in region_cfg_init_ns :

{

1,

0x90000000,

0x90800000-1,

MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX,

MPU_ARMV8M_XN_EXEC_OK,

MPU_ARMV8M_AP_RW_PRIV_ONLY,

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 */

},

Best regards.

Dear @Frantz LEFRERE​ this was it.

I successfully prove your suggestion fix the issues with OCTOSPI access in memory mapped mode.

Thanks for your help.

Hi, @Frantz LEFRERE 
I've encoutered a simmilar problem with the B-U585I-IOT02A board. My 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, 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) 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)
- I've tried both your solution and @BKara.3 solution, both don't work for me. My changes for region_cfg_init_ns struct are listed below:

 

 

 

const struct mpu_armv8m_region_cfg_t region_cfg_init_ns[] = {
          ...
          {
            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 */
           },
           ...
static void sau_and_idau_cfg(void)
{
    ...
    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);
    ....

 

 


- But I still can't get my BSP_OPSI to work.

Can you please help me with my problem? Probably some additional configuration needs to be performed, but I don't know where to look for them.