[rtems commit] NIOS2: Add MPU support functions

Sebastian Huber sebh at rtems.org
Fri Mar 30 13:03:10 UTC 2012


Module:    rtems
Branch:    master
Commit:    40b8f63a10b8106da5a7beb38124896a22c4d661
Changeset: http://git.rtems.org/rtems/commit/?id=40b8f63a10b8106da5a7beb38124896a22c4d661

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Mar 30 14:59:18 2012 +0200

NIOS2: Add MPU support functions

---

 cpukit/score/cpu/nios2/Makefile.am                 |    1 +
 cpukit/score/cpu/nios2/nios2-mpu-add-region.c      |  106 ++++++++++++++++++++
 cpukit/score/cpu/nios2/nios2-mpu-descriptor.c      |   15 +---
 cpukit/score/cpu/nios2/rtems/score/nios2-utility.h |   64 +++++++++++--
 4 files changed, 165 insertions(+), 21 deletions(-)

diff --git a/cpukit/score/cpu/nios2/Makefile.am b/cpukit/score/cpu/nios2/Makefile.am
index 11bf3bd..606a512 100644
--- a/cpukit/score/cpu/nios2/Makefile.am
+++ b/cpukit/score/cpu/nios2/Makefile.am
@@ -37,6 +37,7 @@ libscorecpu_a_SOURCES += nios2-isr-install-raw-handler.c
 libscorecpu_a_SOURCES += nios2-isr-install-vector.c
 libscorecpu_a_SOURCES += nios2-isr-is-in-progress.c
 libscorecpu_a_SOURCES += nios2-isr-set-level.c
+libscorecpu_a_SOURCES += nios2-mpu-add-region.c
 libscorecpu_a_SOURCES += nios2-mpu-configuration.c
 libscorecpu_a_SOURCES += nios2-mpu-descriptor.c
 libscorecpu_a_SOURCES += nios2-mpu-disable-protected.c
diff --git a/cpukit/score/cpu/nios2/nios2-mpu-add-region.c b/cpukit/score/cpu/nios2/nios2-mpu-add-region.c
new file mode 100644
index 0000000..d23769c
--- /dev/null
+++ b/cpukit/score/cpu/nios2/nios2-mpu-add-region.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/score/nios2-utility.h>
+
+static bool _Nios2_MPU_Is_region_disabled(
+  const Nios2_MPU_Configuration *config,
+  uint32_t mpubase,
+  uint32_t mpuacc
+)
+{
+  bool disabled = false;
+
+  if ( config->region_uses_limit ) {
+    disabled = (mpubase & NIOS2_MPUBASE_BASE_MASK)
+      > (mpuacc & NIOS2_MPUACC_LIMIT_MASK);
+  } else {
+    disabled = (mpuacc & NIOS2_MPUACC_MASK_MASK) == 0;
+  }
+
+  return disabled;
+}
+
+int _Nios2_MPU_Get_disabled_region_index(
+  const Nios2_MPU_Configuration *config,
+  bool data,
+  int begin,
+  int end
+)
+{
+  int index = -1;
+  int count = _Nios2_MPU_Get_region_count( config, data );
+
+  if ( end < 0 || count < end ) {
+    end = count;
+  }
+
+  if ( begin >= 0 ) {
+    int i = 0;
+
+    for ( i = begin; i < end && index < 0; ++i ) {
+      uint32_t mpubase = 0;
+      uint32_t mpuacc = 0;
+
+      _Nios2_MPU_Get_region_registers( i, data, &mpubase, &mpuacc );
+
+      if ( _Nios2_MPU_Is_region_disabled( config, mpubase, mpuacc ) ) {
+        index = i;
+      }
+    }
+  }
+
+  return index;
+}
+
+bool _Nios2_MPU_Add_region(
+  const Nios2_MPU_Configuration *config,
+  const Nios2_MPU_Region_descriptor *desc,
+  bool force
+)
+{
+  bool ok = true;
+  int index = desc->index;
+  bool data = desc->data;
+  uint32_t mpubase = 0;
+  uint32_t mpuacc = 0;
+
+  if ( _Nios2_MPU_Is_valid_index( config, data, index ) ) {
+    if ( !force ) {
+      _Nios2_MPU_Get_region_registers( index, data, &mpubase, &mpuacc );
+      ok = _Nios2_MPU_Is_region_disabled( config, mpubase, mpuacc );
+    }
+
+    if ( ok ) {
+      ok = _Nios2_MPU_Setup_region_registers(
+        config,
+        desc,
+        &mpubase,
+        &mpuacc
+      );
+      if ( ok ) {
+        _Nios2_Set_ctlreg_mpubase(mpubase);
+        _Nios2_Set_ctlreg_mpuacc(mpuacc);
+      }
+    }
+  } else {
+    ok = false;
+  }
+
+  return ok;
+}
diff --git a/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c b/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c
index 2b3cc41..1aee1c4 100644
--- a/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c
+++ b/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c
@@ -60,19 +60,6 @@ static bool _Nios2_Is_valid_base_and_end(
   return ok;
 }
 
-static bool _Nios2_Is_valid_index(
-  const Nios2_MPU_Configuration *config,
-  bool data,
-  int index
-)
-{
-  int count = data ?
-    config->data_region_count
-      : config->instruction_region_count;
-
-  return 0 <= index && index < count;
-}
-
 static bool _Nios2_Is_valid_permission(
   bool data,
   int perm
@@ -101,7 +88,7 @@ bool _Nios2_MPU_Setup_region_registers(
     &mask_or_limit
   );
   bool ok = is_valid_base_and_end
-    && _Nios2_Is_valid_index( config, desc->data, desc->index )
+    && _Nios2_MPU_Is_valid_index( config, desc->data, desc->index )
     && _Nios2_Is_valid_permission( desc->data, desc->perm )
     && !(!desc->data && desc->cacheable)
     && !(desc->read && desc->write);
diff --git a/cpukit/score/cpu/nios2/rtems/score/nios2-utility.h b/cpukit/score/cpu/nios2/rtems/score/nios2-utility.h
index 83909c3..7327e8c 100644
--- a/cpukit/score/cpu/nios2/rtems/score/nios2-utility.h
+++ b/cpukit/score/cpu/nios2/rtems/score/nios2-utility.h
@@ -169,13 +169,10 @@ extern char _Nios2_ISR_Status_mask [];
  */
 extern char _Nios2_ISR_Status_bits [];
 
-/**
- * @brief This global variable indicates that the Nios2 MPU is active
- *
- * This global variable is set to 1 when the board support package
- * initializes the MPU during startup.
- */
-extern uint32_t _Nios2_Mpu_active;
+static inline void _Nios2_Flush_pipeline( void )
+{
+  __asm__ volatile ("flushp");
+}
 
 static inline uint32_t _Nios2_Get_ctlreg_status( void )
 {
@@ -377,6 +374,26 @@ typedef struct {
     true, false, false, true \
   }
 
+static inline int _Nios2_MPU_Get_region_count(
+  const Nios2_MPU_Configuration *config,
+  bool data
+)
+{
+  return data ?
+    config->data_region_count
+      : config->instruction_region_count;
+}
+
+static inline bool _Nios2_MPU_Is_valid_index(
+  const Nios2_MPU_Configuration *config,
+  bool data,
+  int index
+)
+{
+  return 0 <= index
+    && index < _Nios2_MPU_Get_region_count( config, data );
+}
+
 bool _Nios2_MPU_Setup_region_registers(
   const Nios2_MPU_Configuration *config,
   const Nios2_MPU_Region_descriptor *desc,
@@ -384,6 +401,38 @@ bool _Nios2_MPU_Setup_region_registers(
   uint32_t *mpuacc
 );
 
+/**
+ * @brief Seaches the region table part for a disabled region.
+ *
+ * The table will be searched between indices @a begin and @a end.  The @a end
+ * index is not part of the search range.  If @a end is negative, then the
+ * region count will be used.  Thus a @a begin of 0 and a @a end of -1 will
+ * specifiy the complete table.
+ *
+ * @retval -1 No disabled region is available.
+ * @retval other Index of disabled region.
+ */
+int _Nios2_MPU_Get_disabled_region_index(
+  const Nios2_MPU_Configuration *config,
+  bool data,
+  int begin,
+  int end
+);
+
+/**
+ * @brief Adds a region according to region descriptor @a desc.
+ *
+ * If @a force is true, then an enabled region will be overwritten.
+ *
+ * @retval true Successful operation.
+ * @retval false Invalid region descriptor or region already in use.
+ */
+bool _Nios2_MPU_Add_region(
+  const Nios2_MPU_Configuration *config,
+  const Nios2_MPU_Region_descriptor *desc,
+  bool force
+);
+
 static inline void _Nios2_MPU_Get_region_registers(
   int index,
   bool data,
@@ -397,6 +446,7 @@ static inline void _Nios2_MPU_Get_region_registers(
 
   _Nios2_Set_ctlreg_mpubase( base );
   _Nios2_Set_ctlreg_mpuacc( NIOS2_MPUACC_RD );
+  _Nios2_Flush_pipeline();
   *mpubase = _Nios2_Get_ctlreg_mpubase() | base;
   *mpuacc = _Nios2_Get_ctlreg_mpuacc();
 }




More information about the vc mailing list