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;
 

Reply via email to