summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-03-30 14:59:18 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-03-30 15:03:26 +0200
commit40b8f63a10b8106da5a7beb38124896a22c4d661 (patch)
treec74f15e92b87a7de9b694f1059eb6bbfb1c0673a /cpukit
parentNIOS2: Fix outermost interrupt check (diff)
downloadrtems-40b8f63a10b8106da5a7beb38124896a22c4d661.tar.bz2
NIOS2: Add MPU support functions
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/score/cpu/nios2/Makefile.am1
-rw-r--r--cpukit/score/cpu/nios2/nios2-mpu-add-region.c106
-rw-r--r--cpukit/score/cpu/nios2/nios2-mpu-descriptor.c15
-rw-r--r--cpukit/score/cpu/nios2/rtems/score/nios2-utility.h64
4 files changed, 165 insertions, 21 deletions
diff --git a/cpukit/score/cpu/nios2/Makefile.am b/cpukit/score/cpu/nios2/Makefile.am
index 11bf3bdcb0..606a512400 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 0000000000..d23769c48b
--- /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@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 2b3cc41564..1aee1c40ea 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 83909c3305..7327e8c7e8 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();
}