diff --git a/nuttx-patches/00010-BACKPORT-stm32-flash-F4-dcache-corruption-fix-no-HSI-on.patch b/nuttx-patches/00010-BACKPORT-stm32-flash-F4-dcache-corruption-fix-no-HSI-on.patch new file mode 100644 index 0000000000..e904850fe9 --- /dev/null +++ b/nuttx-patches/00010-BACKPORT-stm32-flash-F4-dcache-corruption-fix-no-HSI-on.patch @@ -0,0 +1,216 @@ +diff --git NuttX/nuttx/arch/arm/src/stm32/Kconfig NuttX/nuttx/arch/arm/src/stm32/Kconfig +index b6c0458..8ebf8df 100644 +--- NuttX/nuttx/arch/arm/src/stm32/Kconfig ++++ NuttX/nuttx/arch/arm/src/stm32/Kconfig +@@ -2514,6 +2514,14 @@ config STM32_FLASH_PREFETCH + on F1 parts). Some early revisions of F4 parts do not support FLASH pre-fetch + properly and enabling this option may interfere with ADC accuracy. + ++config STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW ++ bool "Workaround for FLASH data cache corruption" ++ default n ++ ---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 ++ errata to check if your STM32 is affected by this problem. ++ + choice + prompt "JTAG Configuration" + default STM32_JTAG_DISABLE +diff --git NuttX/nuttx/arch/arm/src/stm32/chip/stm32_flash.h NuttX/nuttx/arch/arm/src/stm32/chip/stm32_flash.h +index 70e6d62..82d8f09 100644 +--- NuttX/nuttx/arch/arm/src/stm32/chip/stm32_flash.h ++++ NuttX/nuttx/arch/arm/src/stm32/chip/stm32_flash.h +@@ -322,10 +322,11 @@ + # define FLASH_CR_SER (1 << 1) /* Bit 1: Sector Erase */ + # define FLASH_CR_MER (1 << 2) /* Bit 2: Mass Erase sectors 0..11 */ + # define FLASH_CR_SNB_SHIFT (3) /* Bits 3-6: Sector number */ +-# define FLASH_CR_SNB_MASK (15 << FLASH_CR_SNB_SHIFT) + #if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) ++# define FLASH_CR_SNB_MASK (31 << FLASH_CR_SNB_SHIFT) + # define FLASH_CR_SNB(n) (((n % 12) << FLASH_CR_SNB_SHIFT) | ((n / 12) << 7)) /* Sector n, n=0..23 */ + #else ++# define FLASH_CR_SNB_MASK (15 << FLASH_CR_SNB_SHIFT) + # define FLASH_CR_SNB(n) ((n) << FLASH_CR_SNB_SHIFT) /* Sector n, n=0..11 */ + #endif + # define FLASH_CR_PSIZE_SHIFT (8) /* Bits 8-9: Program size */ +diff --git NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c +index 73f1419..3b4ebd8 100644 +--- NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c ++++ NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c +@@ -47,6 +47,10 @@ + + #include + #include ++ ++#include ++#include ++#include + #include + + #include "stm32_flash.h" +@@ -81,13 +85,29 @@ + #endif + + /************************************************************************************ +- * Private Functions ++ * Private Data + ************************************************************************************/ + ++static sem_t g_sem = SEM_INITIALIZER(1); ++ + /************************************************************************************ +- * Public Functions ++ * Private Functions + ************************************************************************************/ +-void stm32_flash_unlock(void) ++ ++static void sem_lock(void) ++{ ++ while (sem_wait(&g_sem) < 0) ++ { ++ DEBUGASSERT(errno == EINTR); ++ } ++} ++ ++static inline void sem_unlock(void) ++{ ++ sem_post(&g_sem); ++} ++ ++static void flash_unlock(void) + { + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) + { +@@ -103,14 +123,48 @@ void stm32_flash_unlock(void) + } + } + +-void stm32_flash_lock(void) ++static void flash_lock(void) + { + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_LOCK); + } + ++#if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) ++static void data_cache_disable(void) ++{ ++ modifyreg32(STM32_FLASH_ACR, FLASH_ACR_DCEN, 0); ++} + +-#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) ++static void data_cache_enable(void) ++{ ++ /* Reset data cache */ + ++ modifyreg32(STM32_FLASH_ACR, 0, FLASH_ACR_DCRST); ++ ++ /* Enable data cache */ ++ ++ modifyreg32(STM32_FLASH_ACR, 0, FLASH_ACR_DCEN); ++} ++#endif ++ ++/************************************************************************************ ++ * Public Functions ++ ************************************************************************************/ ++ ++void stm32_flash_unlock(void) ++{ ++ sem_lock(); ++ flash_unlock(); ++ sem_unlock(); ++} ++ ++void stm32_flash_lock(void) ++{ ++ sem_lock(); ++ flash_lock(); ++ sem_unlock(); ++} ++ ++#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) + size_t up_progmem_pagesize(size_t page) + { + return STM32_FLASH_PAGESIZE; +@@ -231,14 +285,18 @@ ssize_t up_progmem_erasepage(size_t page) + return -EFAULT; + } + +- /* Get flash ready and begin erasing single page */ ++ sem_lock(); + ++#if !defined(CONFIG_STM32_STM32F40XX) + if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION)) + { + return -EPERM; + } ++#endif ++ ++ /* Get flash ready and begin erasing single page */ + +- stm32_flash_unlock(); ++ flash_unlock(); + + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PAGE_ERASE); + +@@ -257,6 +315,7 @@ ssize_t up_progmem_erasepage(size_t page) + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste(); + + modifyreg32(STM32_FLASH_CR, FLASH_CR_PAGE_ERASE, 0); ++ sem_unlock(); + + /* Verify */ + if (up_progmem_ispageerased(page) == 0) +@@ -318,14 +377,23 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) + return -EFAULT; + } + +- /* Get flash ready and begin flashing */ ++ sem_lock(); + ++#if !defined(CONFIG_STM32_STM32F40XX) + if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION)) + { ++ sem_unlock(); + return -EPERM; + } ++#endif ++ ++ /* Get flash ready and begin flashing */ ++ ++ flash_unlock(); + +- stm32_flash_unlock(); ++#if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) ++ data_cache_disable(); ++#endif + + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PG); + +@@ -347,17 +415,25 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) + if (getreg32(STM32_FLASH_SR) & FLASH_SR_WRITE_PROTECTION_ERROR) + { + modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); ++ sem_unlock(); + return -EROFS; + } + + if (getreg16(addr) != *hword) + { + modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); ++ sem_unlock(); + return -EIO; + } + } + + modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); ++ ++#if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) ++ data_cache_enable(); ++#endif ++ ++ sem_unlock(); + return written; + } + diff --git a/nuttx-patches/00010-PENDING-workarround-for-flash-data-cache-corruption.patch b/nuttx-patches/00010-PENDING-workarround-for-flash-data-cache-corruption.patch deleted file mode 100644 index 13d1860248..0000000000 --- a/nuttx-patches/00010-PENDING-workarround-for-flash-data-cache-corruption.patch +++ /dev/null @@ -1,81 +0,0 @@ -diff --git NuttX/nuttx/arch/arm/src/stm32/Kconfig NuttX/nuttx/arch/arm/src/stm32/Kconfig -index b6c0458649..d9fb0aeaa2 100644 ---- NuttX/nuttx/arch/arm/src/stm32/Kconfig -+++ NuttX/nuttx/arch/arm/src/stm32/Kconfig -@@ -2514,6 +2514,12 @@ config STM32_FLASH_PREFETCH - on F1 parts). Some early revisions of F4 parts do not support FLASH pre-fetch - properly and enabling this option may interfere with ADC accuracy. - -+config STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW -+ bool "Enable the workaround to fix flash data cache corruption when reading from one flash bank while writing on other flash bank" -+ default n -+ ---help--- -+ See your STM32 errata to check if your STM32 is affected by this problem. -+ - choice - prompt "JTAG Configuration" - default STM32_JTAG_DISABLE -diff --git NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c -index 73f1419506..fd0b05d624 100644 ---- NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c -+++ NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c -@@ -294,6 +294,37 @@ ssize_t up_progmem_ispageerased(size_t page) - return bwritten; - } - -+#if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) -+static void data_cache_disable(void) -+{ -+ uint32_t value = getreg32(STM32_FLASH_ACR); -+ -+ if (value & FLASH_ACR_DCEN) -+ { -+ value &= ~FLASH_ACR_DCEN; -+ putreg32(value, STM32_FLASH_ACR); -+ } -+} -+ -+static void data_cache_enable(void) -+{ -+ uint32_t value = getreg32(STM32_FLASH_ACR); -+ if (value & FLASH_ACR_DCEN) -+ { -+ return; -+ } -+ -+ /* reset data cache */ -+ value |= FLASH_ACR_DCRST; -+ putreg32(value, STM32_FLASH_ACR); -+ -+ /* enable data cache */ -+ value = getreg32(STM32_FLASH_ACR); -+ value |= FLASH_ACR_DCEN; -+ putreg32(value, STM32_FLASH_ACR); -+} -+#endif -+ - ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) - { - uint16_t *hword = (uint16_t *)buf; -@@ -327,6 +358,10 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) - - stm32_flash_unlock(); - -+#if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) -+ data_cache_disable(); -+#endif -+ - modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PG); - - #if defined(CONFIG_STM32_STM32F40XX) -@@ -358,6 +393,10 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) - } - - modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); -+ -+#if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) -+ data_cache_enable(); -+#endif - return written; - } - diff --git a/nuttx-patches/00015-BACKPORT-stm32-flash-no-HSI-needed-f4.patch b/nuttx-patches/00015-BACKPORT-stm32-flash-no-HSI-needed-f4.patch deleted file mode 100644 index c8ff66e59b..0000000000 --- a/nuttx-patches/00015-BACKPORT-stm32-flash-no-HSI-needed-f4.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff --git NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c -index 73f1419..9ac38a1 100644 ---- NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c -+++ NuttX/nuttx/arch/arm/src/stm32/stm32_flash.c -@@ -231,12 +231,14 @@ ssize_t up_progmem_erasepage(size_t page) - return -EFAULT; - } - -- /* Get flash ready and begin erasing single page */ -- -+#if !defined(CONFIG_STM32_STM32F40XX) - if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION)) - { - return -EPERM; - } -+#endif -+ -+ /* Get flash ready and begin erasing single page */ - - stm32_flash_unlock(); - -@@ -318,12 +320,14 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) - return -EFAULT; - } - -- /* Get flash ready and begin flashing */ -- -+#if !defined(CONFIG_STM32_STM32F40XX) - if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION)) - { - return -EPERM; - } -+#endif -+ -+ /* Get flash ready and begin flashing */ - - stm32_flash_unlock(); -