change log for rtems (2011-10-21)

rtems-vc at rtems.org rtems-vc at rtems.org
Fri Oct 21 09:11:52 UTC 2011


 *sh*:
2011-10-21	Sebastian Huber <sebastian.huber at 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).

M   1.45  cpukit/score/cpu/nios2/ChangeLog
M    1.8  cpukit/score/cpu/nios2/Makefile.am
M    1.3  cpukit/score/cpu/nios2/nios2-context-initialize.c
A    1.1  cpukit/score/cpu/nios2/nios2-mpu-configuration.c
A    1.1  cpukit/score/cpu/nios2/nios2-mpu-descriptor.c
A    1.1  cpukit/score/cpu/nios2/nios2-mpu-disable-protected.c
A    1.1  cpukit/score/cpu/nios2/nios2-mpu-reset.c
M    1.6  cpukit/score/cpu/nios2/rtems/score/nios2-utility.h

diff -u rtems/cpukit/score/cpu/nios2/ChangeLog:1.44 rtems/cpukit/score/cpu/nios2/ChangeLog:1.45
--- rtems/cpukit/score/cpu/nios2/ChangeLog:1.44	Fri Sep 30 03:02:56 2011
+++ rtems/cpukit/score/cpu/nios2/ChangeLog	Fri Oct 21 03:44:22 2011
@@ -1,3 +1,11 @@
+2011-10-21	Sebastian Huber <sebastian.huber at 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).
+
 2011-09-30	Sebastian Huber <sebastian.huber at embedded-brains.de>
 
 	* nios2-context-switch.S: Use small-data area access for

diff -u rtems/cpukit/score/cpu/nios2/Makefile.am:1.7 rtems/cpukit/score/cpu/nios2/Makefile.am:1.8
--- rtems/cpukit/score/cpu/nios2/Makefile.am:1.7	Fri Sep 16 05:25:22 2011
+++ rtems/cpukit/score/cpu/nios2/Makefile.am	Fri Oct 21 03:44:22 2011
@@ -37,6 +37,10 @@
 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-configuration.c
+libscorecpu_a_SOURCES += nios2-mpu-descriptor.c
+libscorecpu_a_SOURCES += nios2-mpu-disable-protected.c
+libscorecpu_a_SOURCES += nios2-mpu-reset.c
 libscorecpu_a_SOURCES += nios2-thread-dispatch-disabled.c
 
 libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)

diff -u rtems/cpukit/score/cpu/nios2/nios2-context-initialize.c:1.2 rtems/cpukit/score/cpu/nios2/nios2-context-initialize.c:1.3
--- rtems/cpukit/score/cpu/nios2/nios2-context-initialize.c:1.2	Fri Sep  2 02:52:30 2011
+++ rtems/cpukit/score/cpu/nios2/nios2-context-initialize.c	Fri Oct 21 03:44:22 2011
@@ -21,6 +21,7 @@
 
 #include <rtems/score/cpu.h>
 #include <rtems/score/nios2-utility.h>
+#include <rtems/score/interr.h>
 
 void _CPU_Context_Initialize(
   Context_Control *context,
@@ -31,6 +32,7 @@
   bool is_fp
 )
 {
+  const Nios2_MPU_Configuration *mpu_config = _Nios2_MPU_Get_configuration();
   uint32_t stack = (uint32_t) stack_area_begin + stack_area_size - 4;
 
   memset(context, 0, sizeof(*context));
@@ -39,4 +41,29 @@
   context->status = _Nios2_ISR_Set_level( new_level, NIOS2_STATUS_PIE );
   context->sp = stack;
   context->ra = (uint32_t) entry_point;
+
+  if ( mpu_config != NULL ) {
+    Nios2_MPU_Region_descriptor desc = {
+      .index = mpu_config->data_index_for_stack_protection,
+      /* FIXME: Brocken stack allocator */
+      .base = (void *) ((int) stack_area_begin & ~((1 << mpu_config->data_region_size_log2) - 1)),
+      .end = (char *) stack_area_begin + stack_area_size,
+      .perm = NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE,
+      .data = true,
+      .cacheable = mpu_config->enable_data_cache_for_stack,
+      .read = false,
+      .write = true
+    };
+    bool ok = _Nios2_MPU_Setup_region_registers(
+      mpu_config,
+      &desc,
+      &context->stack_mpubase,
+      &context->stack_mpuacc
+    );
+
+    if ( !ok ) {
+      /* The task stack allocator must ensure that the stack area is valid */
+      _Internal_error_Occurred( INTERNAL_ERROR_CORE, false, 0xdeadbeef );
+    }
+  }
 }

diff -u /dev/null rtems/cpukit/score/cpu/nios2/nios2-mpu-configuration.c:1.1
--- /dev/null	Fri Oct 21 04:11:52 2011
+++ rtems/cpukit/score/cpu/nios2/nios2-mpu-configuration.c	Fri Oct 21 03:44:22 2011
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/score/nios2-utility.h>
+
+static const Nios2_MPU_Configuration *_Nios2_MPU_Configuration;
+
+void _Nios2_MPU_Set_configuration( const Nios2_MPU_Configuration *config )
+{
+  _Nios2_MPU_Configuration = config;
+}
+
+const Nios2_MPU_Configuration *_Nios2_MPU_Get_configuration( void )
+{
+  return _Nios2_MPU_Configuration;
+}

diff -u /dev/null rtems/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c:1.1
--- /dev/null	Fri Oct 21 04:11:52 2011
+++ rtems/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c	Fri Oct 21 03:44:22 2011
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ *
+ * $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;
+}

diff -u /dev/null rtems/cpukit/score/cpu/nios2/nios2-mpu-disable-protected.c:1.1
--- /dev/null	Fri Oct 21 04:11:52 2011
+++ rtems/cpukit/score/cpu/nios2/nios2-mpu-disable-protected.c	Fri Oct 21 03:44:22 2011
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/score/isr.h>
+#include <rtems/score/nios2-utility.h>
+
+uint32_t _Nios2_MPU_Disable_protected( void )
+{
+  ISR_Level level;
+  uint32_t config;
+
+  _ISR_Disable( level );
+  config = _Nios2_MPU_Disable();
+  _ISR_Enable( level );
+
+  return config;
+}

diff -u /dev/null rtems/cpukit/score/cpu/nios2/nios2-mpu-reset.c:1.1
--- /dev/null	Fri Oct 21 04:11:52 2011
+++ rtems/cpukit/score/cpu/nios2/nios2-mpu-reset.c	Fri Oct 21 03:44:23 2011
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/score/nios2-utility.h>
+
+void _Nios2_MPU_Reset( const Nios2_MPU_Configuration *config )
+{
+  uint32_t data_mpubase = (1U << config->data_region_size_log2)
+    | NIOS2_MPUBASE_D;
+  uint32_t inst_mpubase = 1U << config->instruction_region_size_log2;
+  uint32_t mpuacc = NIOS2_MPUACC_WR;
+  int data_count = config->data_region_count;
+  int inst_count = config->instruction_region_count;
+  int i = 0;
+
+  _Nios2_MPU_Disable();
+
+  for ( i = 0; i < data_count; ++i ) {
+    uint32_t index = ((uint32_t) i) << NIOS2_MPUBASE_INDEX_OFFSET;
+
+    _Nios2_Set_ctlreg_mpubase( data_mpubase | index );
+    _Nios2_Set_ctlreg_mpuacc( mpuacc );
+  }
+
+  for ( i = 0; i < inst_count; ++i ) {
+    uint32_t index = ((uint32_t) i) << NIOS2_MPUBASE_INDEX_OFFSET;
+
+    _Nios2_Set_ctlreg_mpubase( inst_mpubase | index );
+    _Nios2_Set_ctlreg_mpuacc( mpuacc );
+  }
+}

diff -u rtems/cpukit/score/cpu/nios2/rtems/score/nios2-utility.h:1.5 rtems/cpukit/score/cpu/nios2/rtems/score/nios2-utility.h:1.6
--- rtems/cpukit/score/cpu/nios2/rtems/score/nios2-utility.h:1.5	Fri Sep 16 05:25:22 2011
+++ rtems/cpukit/score/cpu/nios2/rtems/score/nios2-utility.h	Fri Oct 21 03:44:23 2011
@@ -102,7 +102,7 @@
 #define NIOS2_CONFIG_ANI (1 << 1)
 #define NIOS2_CONFIG_PE (1 << 0)
 
-#define NIOS2_MPUBASE_BASE_OFFSET 5
+#define NIOS2_MPUBASE_BASE_OFFSET 6
 #define NIOS2_MPUBASE_BASE_MASK (0x1ffffff << NIOS2_MPUBASE_BASE_OFFSET)
 #define NIOS2_MPUBASE_INDEX_OFFSET 1
 
@@ -132,6 +132,7 @@
 
 #ifndef ASM
 
+#include <stddef.h>
 #include <stdint.h>
 #include <stdbool.h>
 
@@ -168,6 +169,14 @@
  */
 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 uint32_t _Nios2_Get_ctlreg_status( void )
 {
   return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_STATUS );
@@ -305,10 +314,133 @@
 
 uint32_t _Nios2_ISR_Set_level( uint32_t new_level, uint32_t status );
 
+typedef struct {
+  int data_address_width;
+  int instruction_address_width;
+  int data_region_size_log2;
+  int instruction_region_size_log2;
+  int data_region_count;
+  int instruction_region_count;
+  int data_index_for_stack_protection;
+  bool region_uses_limit;
+  bool enable_data_cache_for_stack;
+} Nios2_MPU_Configuration;
+
+void _Nios2_MPU_Set_configuration( const Nios2_MPU_Configuration *config );
+
+const Nios2_MPU_Configuration *_Nios2_MPU_Get_configuration( void );
+
+typedef enum {
+  NIOS2_MPU_INST_PERM_SVR_NONE_USER_NONE = 0,
+  NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_NONE,
+  NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_EXECUTE,
+  NIOS2_MPU_DATA_PERM_SVR_NONE_USER_NONE = 0,
+  NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_NONE,
+  NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_READONLY,
+  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE = 4,
+  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_READONLY,
+  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_READWRITE
+} Nios2_MPU_Region_permissions;
+
+typedef struct {
+  int index;
+  const void *base;
+  const void *end;
+  Nios2_MPU_Region_permissions perm;
+  bool data;
+  bool cacheable;
+  bool read;
+  bool write;
+} Nios2_MPU_Region_descriptor;
+
+#define NIOS2_MPU_REGION_DESC_INST( index, base, end ) \
+  { \
+    (index), (base), (end), NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_NONE, \
+    false, false, false, true \
+  }
+
+#define NIOS2_MPU_REGION_DESC_DATA_RO( index, base, end ) \
+  { \
+    (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_NONE, \
+    true, true, false, true \
+  }
+
+#define NIOS2_MPU_REGION_DESC_DATA_RW( index, base, end ) \
+  { \
+    (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE, \
+    true, true, false, true \
+  }
+
+#define NIOS2_MPU_REGION_DESC_DATA_IO( index, base, end ) \
+  { \
+    (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE, \
+    true, false, false, true \
+  }
+
+bool _Nios2_MPU_Setup_region_registers(
+  const Nios2_MPU_Configuration *config,
+  const Nios2_MPU_Region_descriptor *desc,
+  uint32_t *mpubase,
+  uint32_t *mpuacc
+);
+
+static inline void _Nios2_MPU_Get_region_registers(
+  int index,
+  bool data,
+  uint32_t *mpubase,
+  uint32_t *mpuacc
+)
+{
+  uint32_t base = (uint32_t)
+    (((index << NIOS2_MPUBASE_INDEX_OFFSET) & NIOS2_MPUBASE_INDEX_MASK)
+      | (data ? NIOS2_MPUBASE_D : 0));
+
+  _Nios2_Set_ctlreg_mpubase( base );
+  _Nios2_Set_ctlreg_mpuacc( NIOS2_MPUACC_RD );
+  *mpubase = _Nios2_Get_ctlreg_mpubase() | base;
+  *mpuacc = _Nios2_Get_ctlreg_mpuacc();
+}
+
+static inline void _Nios2_MPU_Enable( void )
+{
+  uint32_t config = _Nios2_Get_ctlreg_config();
+
+  _Nios2_Set_ctlreg_config( config | NIOS2_CONFIG_PE );
+}
+
+static inline uint32_t _Nios2_MPU_Disable( void )
+{
+  uint32_t config = _Nios2_Get_ctlreg_config();
+  uint32_t config_pe = NIOS2_CONFIG_PE;
+
+  _Nios2_Set_ctlreg_config( config & ~config_pe );
+
+  return config;
+}
+
+static inline void _Nios2_MPU_Restore( uint32_t config )
+{
+  _Nios2_Set_ctlreg_config( config );
+}
+
+uint32_t _Nios2_MPU_Disable_protected( void );
+
+void _Nios2_MPU_Reset( const Nios2_MPU_Configuration *config );
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* !ASM */
+#else /* ASM */
+
+	.macro	NIOS2_ASM_DISABLE_INTERRUPTS new_status, current_status
+	movhi	\new_status, %hiadj(_Nios2_ISR_Status_mask)
+	addi	\new_status, \new_status, %lo(_Nios2_ISR_Status_mask)
+	and	\new_status, \current_status, \new_status
+	ori	\new_status, \new_status, %lo(_Nios2_ISR_Status_bits)
+	wrctl	status, \new_status
+	.endm
+
+#endif /* ASM */
 
 #endif /* _RTEMS_SCORE_NIOS2_UTILITY_H */



--

Generated by Deluxe Loginfo [http://www.codewiz.org/projects/index.html#loginfo] 2.122 by Bernardo Innocenti <bernie at develer.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/vc/attachments/20111021/ecb32f4f/attachment.html>


More information about the vc mailing list