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 3ff85acb4b63e34830859a3f4feaa0af846f4b5b
Author: Ricardo Maurizio Paul <[email protected]>
AuthorDate: Mon Oct 5 14:43:32 2026 +0200

    arch/arm/stm32h5: map OTP, RO and EDATA flash non-cacheable.
    
    The OTP, read-only (UID, flash size, package) and high-cycle data (EDATA)
    flash areas only accept 16/32-bit accesses and return a bus error
    otherwise (RM0481 Table 77).  The manual requires the MPU to disable local
    cacheability for them (RM0481 7.3.2); with the ICACHE enabled and no such
    region, reading them raises a precise bus error.
    
    Until now this was worked around piecemeal: the driver disabled the
    ICACHE around stm32_get_uniqueid() and the OTP and EDATA word reads, and
    nucleo-h563zi mapped the 4 KB OTP/RO area non-cacheable in its board
    code.  Other reads, for example stm32_otp_read() or an application
    reading the OTP on another board, still raised a precise bus error when
    the ICACHE was enabled.
    
    Map 0x08fff000-0x09017fff, which covers the three contiguous areas, as
    Normal non-cacheable and execute-never with a single MPU region before
    the ICACHE is enabled.  STM32_ICACHE now selects ARM_MPU so that
    stm32_mpuinitialize() has reset and enabled the MPU by then.
    
    Remove the nucleo-h563zi OTP region in the same commit: the Armv8-M MPU
    faults on an address that matches more than one region, so keeping both
    would make OTP and UID reads fault on that board.
    
    Assisted-by: Claude:claude-sonnet-5-5
    Assisted-by: Claude:claude-opus-5-5
    Signed-off-by: Ricardo Maurizio Paul <[email protected]>
---
 arch/arm/src/common/stm32/Kconfig.periph           |  6 ++++
 arch/arm/src/stm32h5/stm32_icache.c                | 28 +++++++++++++++
 .../arm/stm32h5/nucleo-h563zi/src/CMakeLists.txt   |  4 ---
 boards/arm/stm32h5/nucleo-h563zi/src/Make.defs     |  4 ---
 .../arm/stm32h5/nucleo-h563zi/src/nucleo-h563zi.h  | 12 -------
 boards/arm/stm32h5/nucleo-h563zi/src/stm32_boot.c  |  6 ----
 boards/arm/stm32h5/nucleo-h563zi/src/stm32_mpu.c   | 41 ----------------------
 7 files changed, 34 insertions(+), 67 deletions(-)

diff --git a/arch/arm/src/common/stm32/Kconfig.periph 
b/arch/arm/src/common/stm32/Kconfig.periph
index 2b292bbb70b..514f07c9858 100644
--- a/arch/arm/src/common/stm32/Kconfig.periph
+++ b/arch/arm/src/common/stm32/Kconfig.periph
@@ -324,6 +324,12 @@ config STM32_ICACHE
        bool "ICACHE"
        default n
        depends on STM32_HAVE_ICACHE
+       select ARM_MPU
+       ---help---
+               Enable the instruction cache (ICACHE) on the C-AHB bus.  The 
OTP,
+               read-only and high-cycle data flash areas cannot be cached
+               (RM0481 7.3.2), so this option selects ARM_MPU and maps them
+               non-cacheable.
 
 config STM32_DCACHE1
        depends on STM32_HAVE_DCACHE1
diff --git a/arch/arm/src/stm32h5/stm32_icache.c 
b/arch/arm/src/stm32h5/stm32_icache.c
index 3c73d8c9770..c6837213bbc 100644
--- a/arch/arm/src/stm32h5/stm32_icache.c
+++ b/arch/arm/src/stm32h5/stm32_icache.c
@@ -34,6 +34,7 @@
 #include <stdint.h>
 
 #include "arm_internal.h"
+#include "mpu.h"
 #include "stm32.h"
 
 /****************************************************************************
@@ -43,6 +44,15 @@
 #define STM32_ICACHE_INTERRUPT  (defined(CONFIG_STM32_ICACHE_INV_INT) ||\
                                    defined(CONFIG_STM32_ICACHE_ERR_INT))
 
+/* The OTP (0x08fff000), read-only (0x08fff800, UID) and EDATA
+ * (0x09000000-0x09017fff) flash areas only accept 16/32-bit accesses
+ * (RM0481 Table 77) and must be mapped non-cacheable (RM0481 7.3.2).  They
+ * are contiguous, so one MPU region covers them.
+ */
+
+#define STM32_ICACHE_NC_BASE      0x08fff000
+#define STM32_ICACHE_NC_END       0x09018000
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -238,12 +248,30 @@ static void stm32_icache_setup_region(struct 
stm32_icache_region region)
 }
 #endif
 
+static void stm32_icache_mpu_setup(void)
+{
+  /* Non-cacheable, execute-never.  stm32_mpuinitialize() enabled the MPU. */
+
+  DEBUGASSERT((getreg32(MPU_CTRL) & MPU_CTRL_ENABLE) != 0);
+
+  mpu_configure_region(STM32_ICACHE_NC_BASE,
+                       STM32_ICACHE_NC_END - STM32_ICACHE_NC_BASE,
+                       MPU_RBAR_XN | MPU_RBAR_AP_RWRW | MPU_RBAR_SH_NO,
+                       MPU_RLAR_NONCACHEABLE);
+}
+
 void stm32_icache_initialize(void)
 {
 #ifdef CONFIG_STM32_ICACHE_DIRECT
   uint32_t regval;
 #endif
 
+  /* The flash areas that cannot be cached must be excluded before the
+   * ICACHE is enabled.
+   */
+
+  stm32_icache_mpu_setup();
+
   /* Set associativity */
 
 #ifdef CONFIG_STM32_ICACHE_DIRECT
diff --git a/boards/arm/stm32h5/nucleo-h563zi/src/CMakeLists.txt 
b/boards/arm/stm32h5/nucleo-h563zi/src/CMakeLists.txt
index e6816c82f32..75c0d6d997b 100644
--- a/boards/arm/stm32h5/nucleo-h563zi/src/CMakeLists.txt
+++ b/boards/arm/stm32h5/nucleo-h563zi/src/CMakeLists.txt
@@ -52,10 +52,6 @@ if(CONFIG_STM32_USBFS_HOST)
   list(APPEND SRCS stm32_usb.c)
 endif()
 
-if(CONFIG_ARM_MPU)
-  list(APPEND SRCS stm32_mpu.c)
-endif()
-
 target_sources(board PRIVATE ${SRCS})
 
 set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/flash.ld")
diff --git a/boards/arm/stm32h5/nucleo-h563zi/src/Make.defs 
b/boards/arm/stm32h5/nucleo-h563zi/src/Make.defs
index e51b1e73344..828ce6c96c1 100644
--- a/boards/arm/stm32h5/nucleo-h563zi/src/Make.defs
+++ b/boards/arm/stm32h5/nucleo-h563zi/src/Make.defs
@@ -58,10 +58,6 @@ ifeq ($(CONFIG_STM32_USBFS_HOST),y)
 CSRCS += stm32_usb.c
 endif
 
-ifeq ($(CONFIG_ARM_MPU),y)
-CSRCS += stm32_mpu.c
-endif
-
 DEPPATH += --dep-path board
 VPATH += :board
 CFLAGS += 
${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board
diff --git a/boards/arm/stm32h5/nucleo-h563zi/src/nucleo-h563zi.h 
b/boards/arm/stm32h5/nucleo-h563zi/src/nucleo-h563zi.h
index a19be1144ae..7bbc2507f82 100644
--- a/boards/arm/stm32h5/nucleo-h563zi/src/nucleo-h563zi.h
+++ b/boards/arm/stm32h5/nucleo-h563zi/src/nucleo-h563zi.h
@@ -115,18 +115,6 @@
 
 int stm32_bringup(void);
 
-/****************************************************************************
- * Name: stm32_mpu_configure_otp
- *
- * Description:
- *   Initialize MPU and configure the OTP flash region.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_ARM_MPU) && defined(CONFIG_STM32_ICACHE)
-void stm32_mpu_configure_otp(void);
-#endif
-
 #ifdef CONFIG_STM32_SPI
 /****************************************************************************
  * Name: stm32_spiregister
diff --git a/boards/arm/stm32h5/nucleo-h563zi/src/stm32_boot.c 
b/boards/arm/stm32h5/nucleo-h563zi/src/stm32_boot.c
index 9d33312fb59..a0674b61329 100644
--- a/boards/arm/stm32h5/nucleo-h563zi/src/stm32_boot.c
+++ b/boards/arm/stm32h5/nucleo-h563zi/src/stm32_boot.c
@@ -53,12 +53,6 @@
 
 void stm32_board_initialize(void)
 {
-#if defined(CONFIG_ARM_MPU) && defined(CONFIG_STM32_ICACHE)
-  /* Configure OTP MPU region. */
-
-  stm32_mpu_configure_otp();
-#endif
-
 #ifdef CONFIG_ARCH_LEDS
   /* Configure on-board LEDs if LED support has been selected. */
 
diff --git a/boards/arm/stm32h5/nucleo-h563zi/src/stm32_mpu.c 
b/boards/arm/stm32h5/nucleo-h563zi/src/stm32_mpu.c
deleted file mode 100644
index 3ac2d4f0e3e..00000000000
--- a/boards/arm/stm32h5/nucleo-h563zi/src/stm32_mpu.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/****************************************************************************
- * boards/arm/stm32h5/nucleo-h563zi/src/stm32_mpu.c
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <debug.h>
-#include <errno.h>
-
-#include <nuttx/arch.h>
-
-#include "hardware/stm32_memorymap.h"
-#include "mpu.h"
-#include "stm32_mpuinit.h"
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: stm32_mpu_configure_otp
- *
- * Description:
- *   Configure the OTP flash region as non-cacheable, non-executable, non-
- *   shareable, and read-only.
- *
- ****************************************************************************/
-
-void stm32_mpu_configure_otp(void)
-{
-  mpu_configure_region(STM32_OTP_BASE, 4096,
-      MPU_RBAR_XN | MPU_RBAR_SH_NO | MPU_RBAR_AP_RORO,
-      MPU_RLAR_NONCACHEABLE);
-}

Reply via email to