This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit c954b6b3f57e721d986b18550fec1f902b4867da Author: Daniel P. Carvalho <[email protected]> AuthorDate: Sat Oct 24 10:58:13 2026 -0300 arch/arm/src/common/stm32: enable the data cache RWW workaround on the G4 ES0430 erratum 2.2.2: in dual bank mode, reading one bank (data access or code execution) while writing the other with the data cache enabled corrupts the data cache. In an MCUboot swap on an STM32G474 this made up_progmem_write() fail intermittently with a bus fault. The driver already has the workaround, but STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW could not be selected on the G4 (nor on the L4 since it started depending on STM32_FLASH_DCACHE). Make the option available on the G4 and default it to y there. In the driver, also disable the data cache before the page erase and release DCRST after setting it, as the erratum asks; the cache was left in reset after the first write. Tested on an STM32G474 running the MCUboot loader from bank 1: 8 swaps and 8 reverts in a row with the defaults. Assisted-by: Claude Code:claude-sonnet-5-5 Signed-off-by: Daniel P. Carvalho <[email protected]> --- arch/arm/src/common/stm32/Kconfig.flash | 3 ++- arch/arm/src/common/stm32/stm32_flash_m3m4_g4.c | 22 ++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/arch/arm/src/common/stm32/Kconfig.flash b/arch/arm/src/common/stm32/Kconfig.flash index 0a04da242e1..835ef14fc49 100644 --- a/arch/arm/src/common/stm32/Kconfig.flash +++ b/arch/arm/src/common/stm32/Kconfig.flash @@ -132,7 +132,8 @@ config STM32_FLASH_PREFETCH config STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW bool "Workaround for FLASH data cache corruption" - depends on STM32_FLASH_DCACHE && (STM32_STM32F20XX || STM32_STM32F4XXX || (ARCH_CHIP_STM32L4 && (STM32_STM32L4X5 || STM32_STM32L4X6 || STM32_STM32L4XR))) + depends on STM32_FLASH_DCACHE && (STM32_STM32F20XX || STM32_STM32F4XXX || ARCH_CHIP_STM32G4 || (ARCH_CHIP_STM32L4 && (STM32_STM32L4X5 || STM32_STM32L4X6 || STM32_STM32L4XR))) + default y if ARCH_CHIP_STM32G4 ---help--- Enable the workaround to fix flash data cache corruption when reading from one flash bank while writing on other flash bank. See your STM32 diff --git a/arch/arm/src/common/stm32/stm32_flash_m3m4_g4.c b/arch/arm/src/common/stm32/stm32_flash_m3m4_g4.c index f2d722e4799..adce4a09a18 100644 --- a/arch/arm/src/common/stm32/stm32_flash_m3m4_g4.c +++ b/arch/arm/src/common/stm32/stm32_flash_m3m4_g4.c @@ -224,6 +224,12 @@ static inline void flash_erase(size_t page) } #if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) + +/* ES0430 erratum 2.2.2: in dual bank mode, reading one bank (data access or + * code execution) while writing to the other with the data cache enabled + * corrupts the data cache. Keep the cache off while the flash is written. + */ + static void data_cache_disable(void) { modifyreg32(STM32_FLASH_ACR, FLASH_ACR_DCEN, 0); @@ -231,12 +237,12 @@ static void data_cache_disable(void) static void data_cache_enable(void) { - /* Reset data cache */ + /* Reset the data cache (it can only be written while DCEN = 0), release + * the reset and enable the cache again. + */ modifyreg32(STM32_FLASH_ACR, 0, FLASH_ACR_DCRST); - - /* Enable data cache */ - + modifyreg32(STM32_FLASH_ACR, FLASH_ACR_DCRST, 0); modifyreg32(STM32_FLASH_ACR, 0, FLASH_ACR_DCEN); } #endif /* defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) */ @@ -531,14 +537,14 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t buflen) * write back existing data read from page without erase. */ - flash_erase(page); - - /* Write the page. Must be with double-words. */ - #if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) data_cache_disable(); #endif + flash_erase(page); + + /* Write the page. Must be with double-words. */ + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PG); set_pg_bit = true;
