summaryrefslogtreecommitdiff
path: root/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2011-10-21 08:44:23 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2011-10-21 08:44:23 +0000
commitd4a95940391a1ee8c1e36a8b10b8800ee526c0e6 (patch)
treedc2dd05a6e7cc7b8d3bcbf53b10d3a4bfa425f7a /cpukit/score/cpu/nios2/nios2-mpu-descriptor.c
parent488dc6be310095362984d1f665db270b5acd847d (diff)
2011-10-21 Sebastian Huber <sebastian.huber@embedded-brains.de>
* nios2-mpu-configuration.c, nios2-mpu-descriptor.c, nios2-mpu-disable-protected.c, nios2-mpu-reset.c: New files. * Makefile.am: Reflect changes above. * rtems/score/nios2-utility.h, nios2-context-initialize.c: Added support for the memory protection unit (MPU).
Diffstat (limited to 'cpukit/score/cpu/nios2/nios2-mpu-descriptor.c')
-rw-r--r--cpukit/score/cpu/nios2/nios2-mpu-descriptor.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c b/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c
new file mode 100644
index 0000000000..2b3cc41564
--- /dev/null
+++ b/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/score/nios2-utility.h>
+
+static bool _Nios2_Is_power_of_two( uint32_t size )
+{
+ bool ok = false;
+ int i = 0;
+
+ for ( i = 0; !ok && i < 32; ++i ) {
+ ok = size == (1U << i);
+ }
+
+ return ok;
+}
+
+static bool _Nios2_Is_valid_base_and_end(
+ const Nios2_MPU_Configuration *config,
+ bool data,
+ uint32_t base,
+ uint32_t end,
+ uint32_t *mask_or_limit
+)
+{
+ uint32_t size = end - base;
+ uint32_t end_limit = data ?
+ (1U << config->data_address_width)
+ : (1U << config->instruction_address_width);
+ uint32_t mask = data ?
+ ((1U << config->data_region_size_log2)) - 1
+ : ((1U << config->instruction_region_size_log2)) - 1;
+ bool ok = base < end && end <= end_limit
+ && (base & mask) == 0 && (end & mask) == 0;
+
+ if ( config->region_uses_limit ) {
+ *mask_or_limit = end;
+ } else {
+ ok = ok && _Nios2_Is_power_of_two( size );
+ *mask_or_limit = (~(size - 1)) & NIOS2_MPUACC_MASK_MASK;
+ }
+
+ 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
+)
+{
+ int max = data ? 6 : 2;
+
+ return 0 <= perm && perm <= max && (!data || (data && perm != 3));
+}
+
+bool _Nios2_MPU_Setup_region_registers(
+ const Nios2_MPU_Configuration *config,
+ const Nios2_MPU_Region_descriptor *desc,
+ uint32_t *mpubase,
+ uint32_t *mpuacc
+)
+{
+ uint32_t base = (uint32_t) desc->base;
+ uint32_t end = (uint32_t) desc->end;
+ uint32_t mask_or_limit = 0;
+ bool is_valid_base_and_end = _Nios2_Is_valid_base_and_end(
+ config,
+ desc->data,
+ base,
+ end,
+ &mask_or_limit
+ );
+ bool ok = is_valid_base_and_end
+ && _Nios2_Is_valid_index( config, desc->data, desc->index )
+ && _Nios2_Is_valid_permission( desc->data, desc->perm )
+ && !(!desc->data && desc->cacheable)
+ && !(desc->read && desc->write);
+
+ if ( ok ) {
+ *mpubase = (base & NIOS2_MPUBASE_BASE_MASK)
+ | ((desc->index << NIOS2_MPUBASE_INDEX_OFFSET) & NIOS2_MPUBASE_INDEX_MASK)
+ | (desc->data ? NIOS2_MPUBASE_D : 0);
+ *mpuacc = mask_or_limit
+ | (desc->cacheable ? NIOS2_MPUACC_C : 0)
+ | ((desc->perm << NIOS2_MPUACC_PERM_OFFSET) & NIOS2_MPUACC_PERM_MASK)
+ | (desc->read ? NIOS2_MPUACC_RD : 0)
+ | (desc->write ? NIOS2_MPUACC_WR : 0);
+ }
+
+ return ok;
+}