diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2011-10-21 08:44:23 +0000 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2011-10-21 08:44:23 +0000 |
commit | d4a95940391a1ee8c1e36a8b10b8800ee526c0e6 (patch) | |
tree | dc2dd05a6e7cc7b8d3bcbf53b10d3a4bfa425f7a /cpukit/score/cpu/nios2/nios2-mpu-descriptor.c | |
parent | 488dc6be310095362984d1f665db270b5acd847d (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.c | 121 |
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; +} |