cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7RS | H7S3L8 Core Freeze XSPI + DCACHE in Bootloader

Fatih_Yildirim
Associate II

Hi,

I am experiencing a core freeze issue on STM32H7S3L8 MCU, as described below.

UPDATE 1: Most probably Data Cache is the main culprit, closing Data Cache in bootloader solves the problem. Application code Enables Data Cache and we have never observed any freeze errors in application code. Relocating the HASH code changes the behaviour but same error observed for both HW and SW Hash functions so Hash is probably irrelevant! (see the comment section.)

In the bootloader, I compute a HASH over the application image stored in external XSPI flash (memory-mapped XIP). After this process, "we believe", the core occasionally freezes and becomes inaccessible through the debug probe.

In the first scenario bootloader firmware remains unchanged; only the application binary varies. The freeze depends on the application binary. Some application images consistently trigger the issue on every power cycle, while others run without problems.

In the second scenario when using an application image that triggers the freeze and modifying the bootloader, disabling Data Cache or either by relocating the HASH processing block (see. “HASH HW START” and “HASH HW END”) or by commenting out a single line such as // HAL_HASH_DeInit(&hash); or // __HAL_RCC_HASH_CLK_DISABLE(); prevents the freeze and allows a normal jump to the application.


My observations:
1. Error doesn't happen when Data Cache is disabled.

2. Relocating the HASH HW code changes the behaviour

3. Changing the input clock source has no effect on the behaviour (HSE <-> HSI), core freezes with the exact same app binary.

4. I could not trigger the problem using a software HASH implementation.

Given the nondeterministic behavior, I was unable to reach a solution.
I welcome any advice or questions. Thanks in advance.


Pseudo-code which exhibits the exact flow of my bootloader. (I can't share the bootloader itself, unfortunately)

Systick_Init();
// Region 0: Start Addr: 0,         SIZE_4GB,  NO_ACCESS,   SubRegDisable: 0x87
// Region 1: Start Addr: 0x9000000, SIZE_32MB, FULL_ACCESS, SubRegDisable: 0x00, NOT_SHAREABLE, INSTRUCTION_ACCESS_ENABLE
MPU_Init();
SCB_EnableICache();
SCB_EnableDCache();

NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
Clock_Init();	// Error occurs working with HSE and also with HSI mode.

CRC_Init();

LL_PWR_ConfigSupply(LL_PWR_DIRECT_SMPS_SUPPLY);

OptionBytes_Program();	// XSPI works in HSLV Mode

// XSPI1 and XSPI2 uses corresponding MCEs
XSPI1_Init();	// Uses ST EXTMEM Library for External FLash
MCE1_Init();

XSPI2_Init();	// Used for external PSRAM
MCE2_Init();

// HASH HW Start
// Core freezes somewhere after this point, beware that XSPI1 is in memory mapped mode // and we pass external flash address directly to the HAL_HASH_Start();
HASH_Init();	// Poll mode, SHA256 algo, HASH_BYTE_SWAP
// XSPI_APP_FLASH_BASE = 0x90000512, XSPI_APP_FLASH_SIZE = 512kB-512byte
uint8_t digest[32];
HAL_HASH_Start(&hash, XSPI_APP_FLASH_BASE, XSPI_APP_FLASH_SIZE, digest, 2000);
HAL_HASH_DeInit(&hash);
__HAL_RCC_HASH_CLK_DISABLE();
// HASH HW END

signature_success = uECC_verify(public_key, digest, signature);

 

1 ACCEPTED SOLUTION

Accepted Solutions
lobna
ST Employee

Hello @Fatih_Yildirim 

Could you try please to add the following description to your MPU

    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER_X ; //SM: Please use the correct region number in your application.
    MPU_InitStruct.BaseAddress = 0x25000000;    
    MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    HAL_MPU_ConfigRegion(&MPU_InitStruct);

 

BR

Lobna

 

View solution in original post

8 REPLIES 8
Fatih_Yildirim
Associate II

Update 1:

  1. The same error occured on DISCOVERY_H7S7 board with the same bootloader. (Our bootloader supports NUCLEO_H7S3, DISCOVERY_H7S7 and our custom board.)
  2. We have observed the problem with software hash implementation as well. So one can deduce that HASH was not relevant for this problem.
  3. We think main culprit is the D-Cache. STM32H7S3L8 core is r1p2 and I couldn't find data cache errata related to our problem but we have had similar issues with STM32F765 in the past and disabled the data cache according to the errata.
@KDJEM.1, I’ve read your replies on XSPI in the forum, so I’m mentioning you in case you can provide any insights on this issue. Thanks for your help.
AME MCU SM
ST Employee

Hello @Fatih_Yildirim , 

 

Are you able to send me the project that replicates it on the DK board and tell me how to trigger it? 

 

Some additional questions for you:

 

1) What toolchain are you using and have you updated it to latest revision?

2) What is the CubeFW HAL version you are working with? Please make sure you have updated to the latest version. 

3) Are you doing cache maintenance (clean/invalidate) before/after reads/writes?  Or perhaps you can setup MPU to make regions accessed by your DMA non-cacheable? You can also give your external memory device memory attribute as shown in Table 91. TEX, C, B, and S encoding (see PM: STM32F7 Series and STM32H7 Series Cortex®-M7 processor programming manual). 

4) Can you do a register dump using the STM32CubeProgammer, using hot-plug mode after the lock up?

 

 

Thanks,

MCU Support

lobna
ST Employee

Hello @Fatih_Yildirim 

Could you try please to add the following description to your MPU

    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER_X ; //SM: Please use the correct region number in your application.
    MPU_InitStruct.BaseAddress = 0x25000000;    
    MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    HAL_MPU_ConfigRegion(&MPU_InitStruct);

 

BR

Lobna

 

I will provide you a detailed solution as soon as possible. I will also do my best to trigger the problem on Nucleo or Discovery kits.
Best regards.

Hi @lobna and @mƎALLEm ,

I have added suggested MPU settings and the problem didn't occur. To pin-point the problematic access, I have narrowed down the access range by changing MPU base address and size using your MPU configuration. It seems that an access to an address between [0x25A76DE0 - 0x25A76DF0] (32Byte, minimum MPU region size) is the problem. I have kept the base address and size the same as your suggestion and changed the MPU attributes, no problem observed even tough region is set as follows, accessible, T=1, C=1, B=1, XN=0, S=1. Is this behaviour normal and expected? Just setting the MPU for this address range with any configuration solves (maybe hides!) the problem.

Why did you suggest the MPU setting for address 0x25000000 with 16MB size? There are other undefined regions in memory map, do I also need to cover them with MPU?

Thanks for your cooperation.
    - Fatih

Hi @Fatih_Yildirim 

Thank you for the feedback, and glad that the solution resolves your problem

The root cause appears to be speculative cache line fill accesses to the GFXMMU address ranges (from 0x25000000 to 0x25FFFFFF).

The issue is resolved by configuring the memory attributes as I mentioned before

This behavior will be documented as an erratum soon.

Yes, a typo regarding the memory address ranges in the Reference Manual has been identified and is corrected in the revision 9 (available here.)

see table 6 and figure 3.

For Cortex-M7, speculative accesses are allowed, so the best practice is to prevent any access to unused regions.

BR

Lobna

Thanks for your detailed explanations and insights. I have disabled access to whole memory-mapped region with subregion_disable = 0x87 and enabled necessary areas with increasing mpu region numbers. I will check whether this background protection leaves any undefined areas.
I believe it is safe to use D-Cache in the H7S3L8 MCU. Are there any other deadlock-related errata you know about that have not been published yet?
This information will directly affect the release firmware of our projects.
Best regards,
– Fatih

lobna
ST Employee

Dear @Fatih_Yildirim 

To my knowledge, currently there is only the erratum I mentioned to you that will be added to the STM32H7RS products.

And indeed, you can use the D-cache for performance but simply protect all unused memory areas with the MPU.

BR

Lobna