Skip to content

Commit a68b811

Browse files
ahmadstmadeaarm
authored andcommitted
STM : low_level_flash drivers doesn't disable icache
when erasing or writing flash memory. 1- Erasing or writing flash memory while ICACHE is enabled, causes ERRF bit to be set in ICACHE status register. So, should disables ICACHE before erase/write operations and re-enables it afterwards, and that's what this patch support. 2- Enable Icache on H5 platform. Signed-off-by: Ahmad EL JOUAID <[email protected]> Change-Id: Id60631bff10c1c92361b3f8f9969a7650f5e3063
1 parent 0d5b976 commit a68b811

File tree

8 files changed

+139
-3
lines changed

8 files changed

+139
-3
lines changed

platform/ext/target/stm/common/hal/CMSIS_Driver/low_level_flash.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,20 @@
2222
#include "stm32hal.h"
2323
#include <stdio.h>
2424
#include "board.h"
25+
#include "boot_hal_cfg.h"
2526

2627
#ifndef ARG_UNUSED
2728
#define ARG_UNUSED(arg) ((void)arg)
2829
#endif /* ARG_UNUSED */
2930

31+
/* Private typedef -----------------------------------------------------------*/
32+
/* Private constants ---------------------------------------------------------*/
33+
/** @addtogroup ICACHE_Private_Constants ICACHE Private Constants
34+
* @{
35+
*/
36+
#define ICACHE_INVALIDATE_TIMEOUT_VALUE 1U /* 1ms */
37+
#define ICACHE_DISABLE_TIMEOUT_VALUE 1U /* 1ms */
38+
3039
/* config for flash driver */
3140
/*
3241
#define DEBUG_FLASH_ACCESS
@@ -414,6 +423,81 @@ static int32_t Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
414423
}
415424
}
416425

426+
#ifdef TFM_ICACHE_ENABLE
427+
#define HAL_ICACHE_MODULE_ENABLED
428+
static int stm32_icache_disable(void)
429+
{
430+
int status = 0;
431+
uint32_t tickstart;
432+
433+
/* Clear BSYENDF flag first and then disable the instruction cache
434+
* that starts a cache invalidation procedure
435+
*/
436+
CLEAR_BIT(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
437+
438+
HAL_ICACHE_Disable();
439+
440+
/* Get tick */
441+
tickstart = HAL_GetTick();
442+
443+
/* Wait for instruction cache to get disabled */
444+
while (HAL_ICACHE_IsEnabled()) {
445+
if ((HAL_GetTick() - tickstart) >
446+
ICACHE_DISABLE_TIMEOUT_VALUE) {
447+
/* New check to avoid false timeout detection in case
448+
* of preemption.
449+
*/
450+
if (HAL_ICACHE_IsEnabled()) {
451+
status = ARM_DRIVER_ERROR_TIMEOUT;
452+
break;
453+
}
454+
}
455+
}
456+
457+
return status;
458+
}
459+
460+
static void stm32_icache_enable(void)
461+
{
462+
HAL_ICACHE_Enable();
463+
}
464+
465+
static int icache_wait_for_invalidate_complete(void)
466+
{
467+
int status = ARM_DRIVER_ERROR;
468+
uint32_t tickstart;
469+
470+
/* Check if ongoing invalidation operation */
471+
if (__HAL_ICACHE_GET_FLAG(ICACHE_FLAG_BUSY)) {
472+
/* Get tick */
473+
tickstart = HAL_GetTick();
474+
475+
/* Wait for end of cache invalidation */
476+
while (!__HAL_ICACHE_GET_FLAG(ICACHE_FLAG_BUSYEND)) {
477+
if ((HAL_GetTick() - tickstart) >
478+
ICACHE_INVALIDATE_TIMEOUT_VALUE) {
479+
break;
480+
}
481+
}
482+
}
483+
484+
/* Clear any pending flags */
485+
if (__HAL_ICACHE_GET_FLAG(ICACHE_FLAG_BUSYEND)) {
486+
__HAL_ICACHE_CLEAR_FLAG(ICACHE_FLAG_BUSYEND);
487+
status = 0;
488+
} else {
489+
status = ARM_DRIVER_ERROR_TIMEOUT;
490+
}
491+
492+
if (__HAL_ICACHE_GET_FLAG(ICACHE_FLAG_ERROR)) {
493+
__HAL_ICACHE_CLEAR_FLAG(ICACHE_FLAG_ERROR);
494+
status = ARM_DRIVER_ERROR;
495+
}
496+
497+
return status;
498+
}
499+
#endif // TFM_ICACHE_ENABLE
500+
417501
static int32_t Flash_ProgramData(uint32_t addr,
418502
const void *data, uint32_t cnt)
419503
{
@@ -476,6 +560,15 @@ static int32_t Flash_ProgramData(uint32_t addr,
476560
return ARM_DRIVER_ERROR_PARAMETER;
477561
}
478562

563+
#ifdef TFM_ICACHE_ENABLE
564+
/* Disable icache, this will start the invalidation procedure.
565+
* All changes(erase/write) to flash memory should happen when
566+
* i-cache is disabled. A write to flash performed without
567+
* disabling i-cache will set ERRF error flag in SR register.
568+
*/
569+
stm32_icache_disable();
570+
#endif /* TFM_ICACHE_ENABLE */
571+
479572
HAL_FLASH_Unlock();
480573
ARM_FLASH0_STATUS.busy = DRIVER_STATUS_BUSY;
481574
do
@@ -505,6 +598,16 @@ static int32_t Flash_ProgramData(uint32_t addr,
505598

506599
ARM_FLASH0_STATUS.busy = DRIVER_STATUS_IDLE;
507600
HAL_FLASH_Lock();
601+
602+
#ifdef TFM_ICACHE_ENABLE
603+
icache_wait_for_invalidate_complete();
604+
605+
/* I-cache should be enabled only after the
606+
* invalidation is complete.
607+
*/
608+
stm32_icache_enable();
609+
#endif /* TFM_ICACHE_ENABLE */
610+
508611
/* compare data written */
509612
#ifdef CHECK_WRITE
510613
if ((err == HAL_OK) && memcmp(dest, data, cnt))
@@ -587,12 +690,32 @@ static int32_t Flash_EraseSector(uint32_t addr)
587690
#else
588691
EraseInit.Page = page_number(&ARM_FLASH0_DEV, addr);
589692
#endif
693+
694+
#ifdef TFM_ICACHE_ENABLE
695+
/* Disable icache, this will start the invalidation procedure.
696+
* All changes(erase/write) to flash memory should happen when
697+
* i-cache is disabled. A write to flash performed without
698+
* disabling i-cache will set ERRF error flag in SR register.
699+
*/
700+
stm32_icache_disable();
701+
#endif /* TFM_ICACHE_ENABLE */
702+
590703
ARM_FLASH0_STATUS.error = DRIVER_STATUS_NO_ERROR;
591704
HAL_FLASH_Unlock();
592705
ARM_FLASH0_STATUS.busy = DRIVER_STATUS_BUSY;
593706
err = HAL_FLASHEx_Erase(&EraseInit, &pageError);
594707
ARM_FLASH0_STATUS.busy = DRIVER_STATUS_IDLE;
595708
HAL_FLASH_Lock();
709+
710+
#ifdef TFM_ICACHE_ENABLE
711+
icache_wait_for_invalidate_complete();
712+
713+
/* I-cache should be enabled only after the
714+
* invalidation is complete.
715+
*/
716+
stm32_icache_enable();
717+
#endif /* TFM_ICACHE_ENABLE */
718+
596719
#ifdef DEBUG_FLASH_ACCESS
597720
if (err != HAL_OK)
598721
{

platform/ext/target/stm/common/stm32h5xx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ target_sources(platform_s
8484
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32h5xx_hal_pka.c
8585
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32h5xx_hal_cryp.c
8686
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32h5xx_hal_cryp_ex.c
87+
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32h5xx_hal_icache.c
8788
${STM_COMMON_DIR}/hal/Native_Driver/low_level_rng.c
8889
)
8990

platform/ext/target/stm/common/stm32u5xx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ target_sources(platform_s
9090
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32u5xx_hal_cryp_ex.c
9191
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32u5xx_hal_i2c.c
9292
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32u5xx_hal_i2c_ex.c
93+
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32u5xx_hal_icache.c
9394
${STM_COMMON_DIR}/hal/Native_Driver/low_level_rng.c
9495
${STM_COMMON_DIR}/hal/Native_Driver/nv_counters.c
9596
)

platform/ext/target/stm/common/stm32u5xx/hal/Inc/stm32u5xx_hal_icache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ typedef struct
227227
/* Peripheral Control functions **********************************************/
228228
HAL_StatusTypeDef HAL_ICACHE_Enable(void);
229229
HAL_StatusTypeDef HAL_ICACHE_Disable(void);
230+
uint32_t HAL_ICACHE_IsEnabled(void);
230231
HAL_StatusTypeDef HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode);
231232
HAL_StatusTypeDef HAL_ICACHE_DeInit(void);
232233

platform/ext/target/stm/common/stm32u5xx/hal/Src/stm32u5xx_hal_icache.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,15 @@ HAL_StatusTypeDef HAL_ICACHE_Disable(void)
260260
return status;
261261
}
262262

263+
/**
264+
* @brief Check whether the Instruction Cache is enabled or not.
265+
* @retval Status (0: disabled, 1: enabled)
266+
*/
267+
uint32_t HAL_ICACHE_IsEnabled(void)
268+
{
269+
return ((READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) ? 1UL : 0UL);
270+
}
271+
263272
/**
264273
* @brief Invalidate the Instruction Cache.
265274
* @note This function waits for the end of cache invalidation procedure

platform/ext/target/stm/common/stm32wbaxx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ target_sources(platform_s
9191
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32wbaxx_hal_cryp_ex.c
9292
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32wbaxx_hal_i2c.c
9393
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32wbaxx_hal_i2c_ex.c
94+
${CMAKE_CURRENT_SOURCE_DIR}/hal/Src/stm32wbaxx_hal_icache.c
9495
${STM_COMMON_DIR}/hal/Native_Driver/low_level_rng.c
9596
)
9697

platform/ext/target/stm/stm32h573i_dk/include/boot_hal_cfg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
#define TFM_DEV_MODE
4141
/* ICache */
42-
/*#define TFM_ICACHE_ENABLE*/ /*!< Instruction cache enable */
42+
#define TFM_ICACHE_ENABLE /*!< Instruction cache enable */
4343

4444
/* Static protections */
4545
#define TFM_WRP_PROTECT_ENABLE /*!< Write Protection */

platform/ext/target/stm/stm32wba65i_dk/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,14 @@ add_custom_target(tfm_s_fmw ALL SOURCES ${tfm_s_split_out})
8989
if(CMAKE_C_COMPILER STREQUAL "iccarm")
9090
add_custom_command(
9191
OUTPUT ${tfm_s_split_out}
92-
DEPENDS tfm_s_binaries
92+
# DEPENDS tfm_s_binaries
9393
COMMAND ielftool --silent --exclude=.BL2_OTP --bin $<TARGET_FILE:tfm_s> ${tfm_s_bin_dir}/tfm_s_fmw.bin
9494
COMMAND ielftool --silent --only=.BL2_OTP --bin $<TARGET_FILE:tfm_s> ${tfm_s_bin_dir}/tfm_s_otp.bin
9595
)
9696
else()
9797
add_custom_command(
9898
OUTPUT ${tfm_s_split_out}
99-
DEPENDS tfm_s_binaries
99+
# DEPENDS tfm_s_binaries
100100
COMMAND ${CMAKE_OBJCOPY} --remove-section .BL2_OTP -O binary $<TARGET_FILE:tfm_s> ${tfm_s_bin_dir}/tfm_s_fmw.bin
101101
COMMAND ${CMAKE_OBJCOPY} --only-section .BL2_OTP -O binary $<TARGET_FILE:tfm_s> ${tfm_s_bin_dir}/tfm_s_otp.bin
102102
)

0 commit comments

Comments
 (0)