You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/10/23 08:58:37 UTC

[incubator-nuttx] 01/04: armv7-m, armv7-r, armv8-m:MPU Add mpu_reset and ARM_MPU_EARLY_RESET

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

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

commit 9d8f7126f6cee0b7af3c13c2f14a5d8593b69c5f
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Wed Sep 22 10:28:35 2021 -0700

    armv7-m,armv7-r,armv8-m:MPU Add mpu_reset and ARM_MPU_EARLY_RESET
    
       When NuttX is booted from a foreign (non NuttX)
       bootloader. There as a possibility that the
       bootloader configured the MPU, in an
       incompatible way for the NuttX memory usage.
    
       The option to reset the MPU before it is initialized
       may not succeed if the bss and data initialization
       code violated the previous MPU configurations.
    
       Added herein are ARM_MPU_RESET and
       ARM_MPU_EARLY_RESET. The former can be used
       If the system is capable of booting and running
       NuttX MPU configuration code without an MPU
       violation. The latter is used if the system can
       not run the bss and data initialization code.
    
       These are options so that a NuttX may be configured to
       not clobber a bootloader MPU configuration in a system
       that is architected to share the MPU configuration task.
---
 arch/arm/Kconfig               | 28 +++++++++++++++++++++
 arch/arm/src/armv7-m/arm_mpu.c | 57 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/src/armv7-m/mpu.h     | 30 ++++++++++++++++++++++
 arch/arm/src/armv7-r/arm_mpu.c | 57 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/src/armv7-r/mpu.h     | 30 ++++++++++++++++++++++
 arch/arm/src/armv8-m/arm_mpu.c | 57 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/src/armv8-m/mpu.h     | 30 ++++++++++++++++++++++
 7 files changed, 289 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a768a79..56b9a4f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -879,6 +879,34 @@ config ARM_MPU_NREGIONS
 	---help---
 		This is the number of protection regions supported by the MPU.
 
+config ARM_MPU_RESET
+	bool "MPU Reset before MPU initialization"
+	default n
+	depends on ARM_MPU
+	---help---
+		Configures the MPU initialization sequence to disable the MPU
+		before configuring it.
+
+		This may be needed in a system with a bootloader that has
+		configured the MPU prior to running NuttX. This may be all that is
+		needed to allow booting if the previous MPU configuration allow
+		the system to execute the MPU initialization code. If not use
+		ARM_MPU_EARLY_RESET.
+
+config ARM_MPU_EARLY_RESET
+	bool "MPU Early Reset"
+	default n
+	depends on ARCH_HAVE_MPU
+	---help---
+		Configures the early system initialization sequence to disable the MPU.
+
+		This may be needed in a system with a bootloader that has
+		configured the MPU prior to running NuttX. This is useful if the system
+		faults during bbs, or data initialization or before the
+		stm32_mpuinitialize can be called.
+
+		Note: This can be used without MPU Support enabled.
+
 config ARCH_HAVE_LOWVECTORS
 	bool
 
diff --git a/arch/arm/src/armv7-m/arm_mpu.c b/arch/arm/src/armv7-m/arm_mpu.c
index b241661..7a35108 100644
--- a/arch/arm/src/armv7-m/arm_mpu.c
+++ b/arch/arm/src/armv7-m/arm_mpu.c
@@ -178,6 +178,33 @@ static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
 }
 
 /****************************************************************************
+ * Name: mpu_reset_internal
+ *
+ * Description:
+ *   Resets the MPU to disabled.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
+static void mpu_reset_internal()
+{
+  int region;
+  int regions;
+  regions = (getreg32(MPU_TYPE) & MPU_TYPE_DREGION_MASK)
+                                  >> MPU_TYPE_DREGION_SHIFT;
+
+  for (region = 0; region < regions; region++)
+    {
+      putreg32(region, MPU_RNR);
+      putreg32(0, MPU_RASR);
+      putreg32(0, MPU_RBAR);
+    }
+
+  putreg32(0, MPU_CTRL);
+}
+#endif
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -387,3 +414,33 @@ void mpu_configure_region(uintptr_t base, size_t size,
            flags;
   putreg32(regval, MPU_RASR);
 }
+
+/****************************************************************************
+ * Name: mpu_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled during
+ *   MPU initialization.
+ *
+ ****************************************************************************/
+#if defined(CONFIG_MPU_RESET)
+void mpu_reset()
+{
+  mpu_reset_internal();
+}
+#endif
+
+/****************************************************************************
+ * Name: mpu_early_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled immediately
+ *   after reset.
+ *
+ ****************************************************************************/
+#if defined(CONFIG_ARM_MPU_EARLY_RESET)
+void mpu_early_reset()
+{
+  mpu_reset_internal();
+}
+#endif
diff --git a/arch/arm/src/armv7-m/mpu.h b/arch/arm/src/armv7-m/mpu.h
index 2d8fb88..870fea6 100644
--- a/arch/arm/src/armv7-m/mpu.h
+++ b/arch/arm/src/armv7-m/mpu.h
@@ -132,6 +132,36 @@
 #    define MPU_RASR_AP_RORO    (6 << MPU_RASR_AP_SHIFT)  /* P:RO   U:RO   */
 #  define MPU_RASR_XN           (1 << 28)                 /* Bit 28: Instruction access disable */
 
+/****************************************************************************
+ * Name: mpu_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled during
+ *   MPU initialization.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_MPU_RESET)
+void mpu_reset(void);
+#else
+#  define mpu_reset() do { } while (0)
+#endif
+
+/****************************************************************************
+ * Name: mpu_early_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled immediately
+ *   after reset.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_ARM_MPU_EARLY_RESET)
+void mpu_early_reset(void);
+#else
+#  define mpu_early_reset() do { } while (0)
+#endif
+
 #ifdef CONFIG_ARM_MPU
 
 /****************************************************************************
diff --git a/arch/arm/src/armv7-r/arm_mpu.c b/arch/arm/src/armv7-r/arm_mpu.c
index 5fd3723..2023909 100644
--- a/arch/arm/src/armv7-r/arm_mpu.c
+++ b/arch/arm/src/armv7-r/arm_mpu.c
@@ -178,6 +178,33 @@ static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
 }
 
 /****************************************************************************
+ * Name: mpu_reset_internal
+ *
+ * Description:
+ *   Resets the MPU to disabled.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
+static void mpu_reset_internal()
+{
+  int region;
+  int regions;
+  regions = (getreg32(MPU_TYPE) & MPU_TYPE_DREGION_MASK)
+                                  >> MPU_TYPE_DREGION_SHIFT;
+
+  for (region = 0; region < regions; region++)
+    {
+      putreg32(region, MPU_RNR);
+      putreg32(0, MPU_RASR);
+      putreg32(0, MPU_RBAR);
+    }
+
+  putreg32(0, MPU_CTRL);
+}
+#endif
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -300,3 +327,33 @@ uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size)
   ret |= mpu_subregion_ls(offset, l2size);
   return ret;
 }
+
+/****************************************************************************
+ * Name: mpu_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled during
+ *   MPU initialization.
+ *
+ ****************************************************************************/
+#if defined(CONFIG_MPU_RESET)
+void mpu_reset()
+{
+  mpu_reset_internal();
+}
+#endif
+
+/****************************************************************************
+ * Name: mpu_early_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled immediately
+ *   after reset.
+ *
+ ****************************************************************************/
+#if defined(CONFIG_ARM_MPU_EARLY_RESET)
+void mpu_early_reset()
+{
+  mpu_reset_internal();
+}
+#endif
diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h
index e4ccc98..5824353 100644
--- a/arch/arm/src/armv7-r/mpu.h
+++ b/arch/arm/src/armv7-r/mpu.h
@@ -121,6 +121,36 @@ extern "C"
 #endif
 
 /****************************************************************************
+ * Name: mpu_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled during
+ *   MPU initialization.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_MPU_RESET)
+void mpu_reset(void);
+#else
+#  define mpu_reset() do { } while (0)
+#endif
+
+/****************************************************************************
+ * Name: mpu_early_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled immediately
+ *   after reset.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_ARM_MPU_EARLY_RESET)
+void mpu_early_reset(void);
+#else
+#  define mpu_early_reset() do { } while (0)
+#endif
+
+/****************************************************************************
  * Name: mpu_allocregion
  *
  * Description:
diff --git a/arch/arm/src/armv8-m/arm_mpu.c b/arch/arm/src/armv8-m/arm_mpu.c
index 29bb63d..50ae4ff 100644
--- a/arch/arm/src/armv8-m/arm_mpu.c
+++ b/arch/arm/src/armv8-m/arm_mpu.c
@@ -72,6 +72,33 @@ unsigned int mpu_allocregion(void)
 }
 
 /****************************************************************************
+ * Name: mpu_reset_internal
+ *
+ * Description:
+ *   Resets the MPU to disabled.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
+static void mpu_reset_internal()
+{
+  int region;
+  int regions;
+  regions = (getreg32(MPU_TYPE) & MPU_TYPE_DREGION_MASK)
+                                  >> MPU_TYPE_DREGION_SHIFT;
+
+  for (region = 0; region < regions; region++)
+    {
+      putreg32(region, MPU_RNR);
+      putreg32(0, MPU_RASR);
+      putreg32(0, MPU_RBAR);
+    }
+
+  putreg32(0, MPU_CTRL);
+}
+#endif
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -148,3 +175,33 @@ void mpu_configure_region(uintptr_t base, size_t size,
   putreg32(base | flags1, MPU_RBAR);
   putreg32(limit | flags2 | MPU_RLAR_ENABLE, MPU_RLAR);
 }
+
+/****************************************************************************
+ * Name: mpu_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled during
+ *   MPU initialization.
+ *
+ ****************************************************************************/
+#if defined(CONFIG_MPU_RESET)
+void mpu_reset()
+{
+  mpu_reset_internal();
+}
+#endif
+
+/****************************************************************************
+ * Name: mpu_early_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled immediately
+ *   after reset.
+ *
+ ****************************************************************************/
+#if defined(CONFIG_ARM_MPU_EARLY_RESET)
+void mpu_early_reset()
+{
+  mpu_reset_internal();
+}
+#endif
diff --git a/arch/arm/src/armv8-m/mpu.h b/arch/arm/src/armv8-m/mpu.h
index 4e793de..428a06a 100644
--- a/arch/arm/src/armv8-m/mpu.h
+++ b/arch/arm/src/armv8-m/mpu.h
@@ -171,6 +171,36 @@
                                  MPU_MAIR_INNER_NT | MPU_MAIR_INNER_WB | \
                                  MPU_MAIR_INNER_RA | MPU_MAIR_INNER_WA)
 
+/****************************************************************************
+ * Name: mpu_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled during
+ *   MPU initialization.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_MPU_RESET)
+void mpu_reset(void);
+#else
+#  define mpu_reset() do { } while (0)
+#endif
+
+/****************************************************************************
+ * Name: mpu_early_reset
+ *
+ * Description:
+ *   Conditional public interface that resets the MPU to disabled immediately
+ *   after reset.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_ARM_MPU_EARLY_RESET)
+void mpu_early_reset(void);
+#else
+#  define mpu_early_reset() do { } while (0)
+#endif
+
 #ifdef CONFIG_ARM_MPU
 
 /****************************************************************************