This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 292b22f9d82 arm/stm32: Preserve ICACHE state when reading UID
292b22f9d82 is described below

commit 292b22f9d82d37381e6c7e56a8a994b7e42f38ae
Author: jsanchez-2g <[email protected]>
AuthorDate: Wed Aug 26 09:35:00 2026 -0500

    arm/stm32: Preserve ICACHE state when reading UID
    
    The unique ID on STM32 Cortex-M33 parts is stored in flash information
    memory, which cannot be accessed while the instruction cache is enabled.
    
    Add an ICACHE state helper, temporarily disable the instruction cache
    while reading the UID using 32-bit accesses, and restore it only when it
    was originally enabled. This preserves the caller's cache state and
    prevents a bus fault during UID access.
    
    Assisted-by: Codex:gpt-5
    
    Signed-off-by: jsanchez-2g <[email protected]>
---
 arch/arm/src/common/stm32/stm32_uid.c | 24 ++++++++++++++++++++++++
 arch/arm/src/stm32h5/stm32_icache.c   | 11 +++++++++++
 arch/arm/src/stm32h5/stm32_icache.h   | 16 ++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/arch/arm/src/common/stm32/stm32_uid.c 
b/arch/arm/src/common/stm32/stm32_uid.c
index e710dabcf64..016b447d368 100644
--- a/arch/arm/src/common/stm32/stm32_uid.c
+++ b/arch/arm/src/common/stm32/stm32_uid.c
@@ -46,6 +46,10 @@
 #include "chip.h"
 #include "stm32_uid.h"
 
+#ifdef CONFIG_STM32_ICACHE
+#  include "stm32_icache.h"
+#endif
+
 #ifdef STM32_SYSMEM_UID /* Not defined for some STM32 parts */
 
 /****************************************************************************
@@ -56,6 +60,19 @@ void stm32_get_uniqueid(uint8_t uniqueid[12])
 {
   uint32_t uid[3];
   int i;
+#ifdef CONFIG_STM32_ICACHE
+  bool icache_enabled;
+
+  /* The UID on STM32 Cortex-M33 parts cannot be read while the instruction
+   * cache is enabled.  Preserve the cache state across the UID access.
+   */
+
+  icache_enabled = stm32_icache_enabled();
+  if (icache_enabled)
+    {
+      stm32_disable_icache();
+    }
+#endif
 
   /* Read the UID with 32-bit accesses. Some parts (STM32H5) store the UID
    * in flash memory that does not support 8-bit reads.
@@ -66,6 +83,13 @@ void stm32_get_uniqueid(uint8_t uniqueid[12])
       uid[i] = getreg32(STM32_SYSMEM_UID + 4 * i);
     }
 
+#ifdef CONFIG_STM32_ICACHE
+  if (icache_enabled)
+    {
+      stm32_enable_icache();
+    }
+#endif
+
   memcpy(uniqueid, uid, 12);
 }
 
diff --git a/arch/arm/src/stm32h5/stm32_icache.c 
b/arch/arm/src/stm32h5/stm32_icache.c
index 2aa578d6723..0d8272d22af 100644
--- a/arch/arm/src/stm32h5/stm32_icache.c
+++ b/arch/arm/src/stm32h5/stm32_icache.c
@@ -180,6 +180,7 @@ static inline void stm32_icache_set_ier(uint32_t ier)
 static inline void stm32_icache_reset_hmon(void)
 {
   uint32_t regval;
+
   regval = getreg32(STM32_ICACHE_CR);
   regval |= ICACHE_CR_HITMRST;
   putreg32(regval, STM32_ICACHE_CR);
@@ -190,6 +191,7 @@ static inline void stm32_icache_reset_hmon(void)
 static inline void stm32_icache_reset_mmon(void)
 {
   uint32_t regval;
+
   regval = getreg32(STM32_ICACHE_CR);
   regval |= ICACHE_CR_MISSMRST;
   putreg32(regval, STM32_ICACHE_CR);
@@ -200,6 +202,7 @@ static inline void stm32_icache_reset_mmon(void)
 static inline void stm32_icache_enable_monitors(void)
 {
   uint32_t regval;
+
   regval = getreg32(STM32_ICACHE_CR);
   regval |= (ICACHE_CR_MISSMEN | ICACHE_CR_HITMEN);
   putreg32(regval, STM32_ICACHE_CR);
@@ -208,6 +211,7 @@ static inline void stm32_icache_enable_monitors(void)
 static inline void stm32_icache_disable_monitors(void)
 {
   uint32_t regval;
+
   regval = getreg32(STM32_ICACHE_CR);
   regval &= ~(ICACHE_CR_MISSMEN | ICACHE_CR_HITMEN);
   putreg32(regval, STM32_ICACHE_CR);
@@ -298,6 +302,7 @@ void stm32_icache_initialize(void)
 void stm32_icache_reset_monitors(void)
 {
   uint32_t regval;
+
   regval = getreg32(STM32_ICACHE_CR);
   regval |= (ICACHE_CR_MISSMRST | ICACHE_CR_HITMRST);
   putreg32(regval, STM32_ICACHE_CR);
@@ -318,11 +323,17 @@ size_t stm32_get_icache_size(void)
 void stm32_disable_icache(void)
 {
   uint32_t regval;
+
   regval = getreg32(STM32_ICACHE_CR);
   regval &= ~(ICACHE_CR_EN);
   putreg32(regval, STM32_ICACHE_CR);
 }
 
+bool stm32_icache_enabled(void)
+{
+  return (getreg32(STM32_ICACHE_CR) & ICACHE_CR_EN) != 0;
+}
+
 void stm32_enable_icache(void)
 {
   uint32_t regval;
diff --git a/arch/arm/src/stm32h5/stm32_icache.h 
b/arch/arm/src/stm32h5/stm32_icache.h
index 13684c4f262..07b85969889 100644
--- a/arch/arm/src/stm32h5/stm32_icache.h
+++ b/arch/arm/src/stm32h5/stm32_icache.h
@@ -117,6 +117,22 @@ void stm32_enable_icache(void);
 
 void stm32_disable_icache(void);
 
+/****************************************************************************
+ * Name: stm32_icache_enabled
+ *
+ * Description:
+ *   Returns whether the STM32H5 ICACHE is enabled.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   true if the ICACHE is enabled; false otherwise.
+ *
+ ****************************************************************************/
+
+bool stm32_icache_enabled(void);
+
 /****************************************************************************
  * Name: stm32_reset_monitors
  *

Reply via email to