summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/arm
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2011-09-24 12:56:51 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2011-09-24 12:56:51 +0000
commitc5ed14844e379eaefaf6cfe27f54d9f17f8984e1 (patch)
tree1102b1d3f7df560af2b99f3bdc23f25618239290 /cpukit/score/cpu/arm
parent2011-09-24 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff)
downloadrtems-c5ed14844e379eaefaf6cfe27f54d9f17f8984e1.tar.bz2
2011-09-24 Sebastian Huber <sebastian.huber@embedded-brains.de>
* rtems/score/armv7m.h, armv7m-context-initialize.c, armv7m-context-restore.c, armv7m-context-switch.c, armv7m-exception-handler-get.c, armv7m-exception-handler-set.c, armv7m-exception-priority-get.c, armv7m-exception-priority-set.c, armv7m-initialize.c, armv7m-isr-dispatch.c, armv7m-isr-enter-leave.c, armv7m-isr-level-get.c, armv7m-isr-level-set.c, armv7m-isr-vector-install.c, armv7m-multitasking-start-stop.c: New files. * Makefile.am, preinstall.am: Reflect changes above. * rtems/score/arm.h: Define ARM_MULTILIB_ARCH_V4 and ARM_MULTILIB_ARCH_V7M. * rtems/score/cpu.h, cpu_asm.S, cpu.c, arm_exc_abort.S, arm_exc_handler_high.c, arm_exc_handler_low.S, arm_exc_interrupt.S: Define CPU_HAS_HARDWARE_INTERRUPT_STACK to FALSE. Use ARM_MULTILIB_ARCH_V4 and ARM_MULTILIB_ARCH_V7M.
Diffstat (limited to 'cpukit/score/cpu/arm')
-rw-r--r--cpukit/score/cpu/arm/ChangeLog18
-rw-r--r--cpukit/score/cpu/arm/Makefile.am28
-rw-r--r--cpukit/score/cpu/arm/arm_exc_abort.S4
-rw-r--r--cpukit/score/cpu/arm/arm_exc_handler_high.c4
-rw-r--r--cpukit/score/cpu/arm/arm_exc_handler_low.S4
-rw-r--r--cpukit/score/cpu/arm/arm_exc_interrupt.S4
-rw-r--r--cpukit/score/cpu/arm/armv7m-context-initialize.c44
-rw-r--r--cpukit/score/cpu/arm/armv7m-context-restore.c45
-rw-r--r--cpukit/score/cpu/arm/armv7m-context-switch.c49
-rw-r--r--cpukit/score/cpu/arm/armv7m-exception-handler-get.c30
-rw-r--r--cpukit/score/cpu/arm/armv7m-exception-handler-set.c35
-rw-r--r--cpukit/score/cpu/arm/armv7m-exception-priority-get.c36
-rw-r--r--cpukit/score/cpu/arm/armv7m-exception-priority-set.c34
-rw-r--r--cpukit/score/cpu/arm/armv7m-initialize.c46
-rw-r--r--cpukit/score/cpu/arm/armv7m-isr-dispatch.c65
-rw-r--r--cpukit/score/cpu/arm/armv7m-isr-enter-leave.c44
-rw-r--r--cpukit/score/cpu/arm/armv7m-isr-level-get.c30
-rw-r--r--cpukit/score/cpu/arm/armv7m-isr-level-set.c30
-rw-r--r--cpukit/score/cpu/arm/armv7m-isr-vector-install.c41
-rw-r--r--cpukit/score/cpu/arm/armv7m-multitasking-start-stop.c71
-rw-r--r--cpukit/score/cpu/arm/cpu.c19
-rw-r--r--cpukit/score/cpu/arm/cpu_asm.S4
-rw-r--r--cpukit/score/cpu/arm/preinstall.am4
-rw-r--r--cpukit/score/cpu/arm/rtems/score/arm.h18
-rw-r--r--cpukit/score/cpu/arm/rtems/score/armv7m.h236
-rw-r--r--cpukit/score/cpu/arm/rtems/score/cpu.h100
26 files changed, 1015 insertions, 28 deletions
diff --git a/cpukit/score/cpu/arm/ChangeLog b/cpukit/score/cpu/arm/ChangeLog
index 1892efed90..90f8144888 100644
--- a/cpukit/score/cpu/arm/ChangeLog
+++ b/cpukit/score/cpu/arm/ChangeLog
@@ -1,3 +1,21 @@
+2011-09-24 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * rtems/score/armv7m.h, armv7m-context-initialize.c,
+ armv7m-context-restore.c, armv7m-context-switch.c,
+ armv7m-exception-handler-get.c, armv7m-exception-handler-set.c,
+ armv7m-exception-priority-get.c, armv7m-exception-priority-set.c,
+ armv7m-initialize.c, armv7m-isr-dispatch.c, armv7m-isr-enter-leave.c,
+ armv7m-isr-level-get.c, armv7m-isr-level-set.c,
+ armv7m-isr-vector-install.c, armv7m-multitasking-start-stop.c: New
+ files.
+ * Makefile.am, preinstall.am: Reflect changes above.
+ * rtems/score/arm.h: Define ARM_MULTILIB_ARCH_V4 and
+ ARM_MULTILIB_ARCH_V7M.
+ * rtems/score/cpu.h, cpu_asm.S, cpu.c, arm_exc_abort.S,
+ arm_exc_handler_high.c, arm_exc_handler_low.S, arm_exc_interrupt.S:
+ Define CPU_HAS_HARDWARE_INTERRUPT_STACK to FALSE. Use
+ ARM_MULTILIB_ARCH_V4 and ARM_MULTILIB_ARCH_V7M.
+
2011-09-16 Sebastian Huber <sebastian.huber@embedded-brains.de>
* rtems/score/arm.h: More CPU_MODEL_NAME variants.
diff --git a/cpukit/score/cpu/arm/Makefile.am b/cpukit/score/cpu/arm/Makefile.am
index 9da9bec4c8..9043622c51 100644
--- a/cpukit/score/cpu/arm/Makefile.am
+++ b/cpukit/score/cpu/arm/Makefile.am
@@ -9,16 +9,32 @@ include_rtems_scoredir = $(includedir)/rtems/score
include_rtems_score_HEADERS = rtems/score/cpu.h
include_rtems_score_HEADERS += rtems/score/cpu_asm.h
include_rtems_score_HEADERS += rtems/score/arm.h
+include_rtems_score_HEADERS += rtems/score/armv7m.h
include_rtems_score_HEADERS += rtems/score/types.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
-libscorecpu_a_SOURCES = cpu.c \
- cpu_asm.S \
- arm_exc_abort.S \
- arm_exc_interrupt.S \
- arm_exc_handler_low.S \
- arm_exc_handler_high.c
+libscorecpu_a_SOURCES =
+libscorecpu_a_SOURCES += cpu.c
+libscorecpu_a_SOURCES += cpu_asm.S
+libscorecpu_a_SOURCES += arm_exc_abort.S
+libscorecpu_a_SOURCES += arm_exc_interrupt.S
+libscorecpu_a_SOURCES += arm_exc_handler_low.S
+libscorecpu_a_SOURCES += arm_exc_handler_high.c
+libscorecpu_a_SOURCES += armv7m-context-initialize.c
+libscorecpu_a_SOURCES += armv7m-context-restore.c
+libscorecpu_a_SOURCES += armv7m-context-switch.c
+libscorecpu_a_SOURCES += armv7m-exception-handler-get.c
+libscorecpu_a_SOURCES += armv7m-exception-handler-set.c
+libscorecpu_a_SOURCES += armv7m-exception-priority-get.c
+libscorecpu_a_SOURCES += armv7m-exception-priority-set.c
+libscorecpu_a_SOURCES += armv7m-initialize.c
+libscorecpu_a_SOURCES += armv7m-isr-dispatch.c
+libscorecpu_a_SOURCES += armv7m-isr-enter-leave.c
+libscorecpu_a_SOURCES += armv7m-isr-level-get.c
+libscorecpu_a_SOURCES += armv7m-isr-level-set.c
+libscorecpu_a_SOURCES += armv7m-isr-vector-install.c
+libscorecpu_a_SOURCES += armv7m-multitasking-start-stop.c
include $(srcdir)/preinstall.am
include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/arm/arm_exc_abort.S b/cpukit/score/cpu/arm/arm_exc_abort.S
index cd2491fb14..59ab5d2988 100644
--- a/cpukit/score/cpu/arm/arm_exc_abort.S
+++ b/cpukit/score/cpu/arm/arm_exc_abort.S
@@ -26,6 +26,8 @@
#include <rtems/asm.h>
#include <rtems/system.h>
+#ifdef ARM_MULTILIB_ARCH_V4
+
.extern rtems_fatal_error_occurred
.globl arm_exc_data_abort_set_handler
@@ -133,3 +135,5 @@ save_more_context:
call_handler:
bx r2
#endif /* __thumb__ */
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/cpukit/score/cpu/arm/arm_exc_handler_high.c b/cpukit/score/cpu/arm/arm_exc_handler_high.c
index 176c1b4561..3c3ec9f191 100644
--- a/cpukit/score/cpu/arm/arm_exc_handler_high.c
+++ b/cpukit/score/cpu/arm/arm_exc_handler_high.c
@@ -36,6 +36,8 @@
#include <rtems/score/thread.h>
#include <rtems/score/cpu.h>
+#ifdef ARM_MULTILIB_ARCH_V4
+
static void _defaultExcHandler (CPU_Exception_frame *ctx)
{
printk("\n\r");
@@ -119,3 +121,5 @@ void rtems_exception_init_mngt(void)
_CPU_ISR_Enable(level);
}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/cpukit/score/cpu/arm/arm_exc_handler_low.S b/cpukit/score/cpu/arm/arm_exc_handler_low.S
index c43d430e2f..5840c6d0be 100644
--- a/cpukit/score/cpu/arm/arm_exc_handler_low.S
+++ b/cpukit/score/cpu/arm/arm_exc_handler_low.S
@@ -33,6 +33,8 @@
#include <rtems/asm.h>
#include <rtems/score/cpu_asm.h>
+#ifdef ARM_MULTILIB_ARCH_V4
+
.text
/* FIXME: _Exception_Handler_Undef_Swi is untested */
@@ -162,3 +164,5 @@ arm_code:
subs pc, r14, #4
#endif
/* _AFTER_ the aborted one */
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/cpukit/score/cpu/arm/arm_exc_interrupt.S b/cpukit/score/cpu/arm/arm_exc_interrupt.S
index e269e13455..8d7cfbc1c2 100644
--- a/cpukit/score/cpu/arm/arm_exc_interrupt.S
+++ b/cpukit/score/cpu/arm/arm_exc_interrupt.S
@@ -32,6 +32,8 @@
#include <rtems/asm.h>
#include <rtems/score/percpu.h>
+#ifdef ARM_MULTILIB_ARCH_V4
+
#define EXCHANGE_LR r4
#define EXCHANGE_SPSR r5
#define EXCHANGE_CPSR r6
@@ -175,3 +177,5 @@ thread_dispatch_done:
/* Return from interrupt */
subs pc, lr, #4
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/cpukit/score/cpu/arm/armv7m-context-initialize.c b/cpukit/score/cpu/arm/armv7m-context-initialize.c
new file mode 100644
index 0000000000..451c6b5b55
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-context-initialize.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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 <string.h>
+
+#include <rtems/score/thread.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void _CPU_Context_Initialize(
+ Context_Control *context,
+ void *stack_area_begin,
+ size_t stack_area_size,
+ uint32_t new_level,
+ void (*entry_point)( void ),
+ bool is_fp
+)
+{
+ char *stack_area_end = (char *) stack_area_begin + stack_area_size;
+
+ memset(context, 0, sizeof(*context));
+
+ context->register_lr = entry_point;
+ context->register_sp = stack_area_end;
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-context-restore.c b/cpukit/score/cpu/arm/armv7m-context-restore.c
new file mode 100644
index 0000000000..effa3e704e
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-context-restore.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/percpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void __attribute__((naked)) _CPU_Context_restore(
+ Context_Control *heir
+)
+{
+ __asm__ volatile (
+ "movw r2, #:lower16:_Per_CPU_Information\n"
+ "movt r2, #:upper16:_Per_CPU_Information\n"
+ "ldr r3, [r0, %[isrctxoff]]\n"
+ "ldr sp, [r0, %[spctxoff]]\n"
+ "ldm r0, {r4-r11, lr}\n"
+ "str r3, [r2, %[isrpcpuoff]]\n"
+ "bx lr\n"
+ :
+ : [spctxoff] "J" (offsetof(Context_Control, register_sp)),
+ [isrctxoff] "J" (offsetof(Context_Control, isr_nest_level)),
+ [isrpcpuoff] "J" (offsetof(Per_CPU_Control, isr_nest_level))
+ );
+ __builtin_unreachable();
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-context-switch.c b/cpukit/score/cpu/arm/armv7m-context-switch.c
new file mode 100644
index 0000000000..bb73c6671a
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-context-switch.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/percpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void __attribute__((naked)) _CPU_Context_switch(
+ Context_Control *executing,
+ Context_Control *heir
+)
+{
+ __asm__ volatile (
+ "movw r2, #:lower16:_Per_CPU_Information\n"
+ "movt r2, #:upper16:_Per_CPU_Information\n"
+ "ldr r3, [r2, %[isrpcpuoff]]\n"
+ "stm r0, {r4-r11, lr}\n"
+ "str sp, [r0, %[spctxoff]]\n"
+ "str r3, [r0, %[isrctxoff]]\n"
+ "ldr r3, [r1, %[isrctxoff]]\n"
+ "ldr sp, [r1, %[spctxoff]]\n"
+ "ldm r1, {r4-r11, lr}\n"
+ "str r3, [r2, %[isrpcpuoff]]\n"
+ "bx lr\n"
+ :
+ : [spctxoff] "J" (offsetof(Context_Control, register_sp)),
+ [isrctxoff] "J" (offsetof(Context_Control, isr_nest_level)),
+ [isrpcpuoff] "J" (offsetof(Per_CPU_Control, isr_nest_level))
+ );
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-exception-handler-get.c b/cpukit/score/cpu/arm/armv7m-exception-handler-get.c
new file mode 100644
index 0000000000..f6aa663436
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-exception-handler-get.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+ARMV7M_Exception_handler _ARMV7M_Get_exception_handler( int index )
+{
+ return _ARMV7M_SCB->vtor [index];
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-exception-handler-set.c b/cpukit/score/cpu/arm/armv7m-exception-handler-set.c
new file mode 100644
index 0000000000..1f2564faf0
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-exception-handler-set.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void _ARMV7M_Set_exception_handler(
+ int index,
+ ARMV7M_Exception_handler handler
+)
+{
+ if ( _ARMV7M_SCB->vtor [index] != handler ) {
+ _ARMV7M_SCB->vtor [index] = handler;
+ }
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-exception-priority-get.c b/cpukit/score/cpu/arm/armv7m-exception-priority-get.c
new file mode 100644
index 0000000000..f13357d90f
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-exception-priority-get.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+int _ARMV7M_Get_exception_priority( int vector )
+{
+ if (vector >= ARMV7M_VECTOR_IRQ(0)) {
+ return _ARMV7M_NVIC->ipr [vector - ARMV7M_VECTOR_IRQ(0)];
+ } else if (vector >= ARMV7M_VECTOR_MEM_MANAGE) {
+ return _ARMV7M_SCB->shpr [vector - 4];
+ } else {
+ return vector - 4;
+ }
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-exception-priority-set.c b/cpukit/score/cpu/arm/armv7m-exception-priority-set.c
new file mode 100644
index 0000000000..7bd618dee0
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-exception-priority-set.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void _ARMV7M_Set_exception_priority( int vector, int priority )
+{
+ if (vector >= ARMV7M_VECTOR_IRQ(0)) {
+ _ARMV7M_NVIC->ipr [vector - ARMV7M_VECTOR_IRQ(0)] = (uint8_t) priority;
+ } else if (vector >= ARMV7M_VECTOR_MEM_MANAGE) {
+ _ARMV7M_SCB->shpr [vector - 4] = (uint8_t) priority;
+ }
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-initialize.c b/cpukit/score/cpu/arm/armv7m-initialize.c
new file mode 100644
index 0000000000..f8e652d84d
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-initialize.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void _CPU_Initialize( void )
+{
+ /*
+ * The exception handler used to carry out the thead dispatching must have
+ * the lowest priority possible. No other exception handlers must have this
+ * priority if they use services that may lead to a thread dispatch. See
+ * also "ARMv7-M Architecture Reference Manual, Issue D" section B1.5.4
+ * "Exception priorities and preemption".
+ */
+ _ARMV7M_Set_exception_priority( ARMV7M_VECTOR_SVC, 0xff );
+ _ARMV7M_Set_exception_priority( ARMV7M_VECTOR_PENDSV, 0xff );
+ _ARMV7M_Set_exception_handler(
+ ARMV7M_VECTOR_SVC,
+ _ARMV7M_Supervisor_call
+ );
+ _ARMV7M_Set_exception_handler(
+ ARMV7M_VECTOR_PENDSV,
+ _ARMV7M_Pendable_service_call
+ );
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-isr-dispatch.c b/cpukit/score/cpu/arm/armv7m-isr-dispatch.c
new file mode 100644
index 0000000000..42ea404f0f
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-isr-dispatch.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/percpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+static void __attribute__((naked)) _ARMV7M_Thread_dispatch( void )
+{
+ __asm__ volatile (
+ "bl _Thread_Dispatch\n"
+ /* FIXME: SVC, binutils bug */
+ ".short 0xdf00\n"
+ "nop\n"
+ );
+}
+
+void _ARMV7M_Pendable_service_call( void )
+{
+ _ISR_Nest_level = 1;
+ _ARMV7M_SCB->icsr = ARMV7M_SCB_ICSR_PENDSVCLR;
+ ARMV7M_Exception_frame *ef = (ARMV7M_Exception_frame *) _ARMV7M_Get_PSP();
+ --ef;
+ _ARMV7M_Set_PSP((uint32_t) ef);
+
+ /*
+ * According to "ARMv7-M Architecture Reference Manual" section B1.5.6
+ * "Exception entry behavior" the return address is half-word aligned.
+ */
+ ef->register_pc = (void *)
+ ((uintptr_t) _ARMV7M_Thread_dispatch & ~((uintptr_t) 1));
+
+ ef->register_xpsr = 0x01000000U;
+}
+
+void _ARMV7M_Supervisor_call( void )
+{
+ ARMV7M_Exception_frame *ef = (ARMV7M_Exception_frame *) _ARMV7M_Get_PSP();
+ ++ef;
+ _ARMV7M_Set_PSP((uint32_t) ef);
+ _ISR_Nest_level = 0;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ if ( _Thread_Dispatch_necessary ) {
+ _ARMV7M_Pendable_service_call();
+ }
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-isr-enter-leave.c b/cpukit/score/cpu/arm/armv7m-isr-enter-leave.c
new file mode 100644
index 0000000000..cd5844b255
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-isr-enter-leave.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/thread.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void _ARMV7M_Interrupt_service_enter( void )
+{
+ ++_Thread_Dispatch_disable_level;
+ ++_ISR_Nest_level;
+}
+
+void _ARMV7M_Interrupt_service_leave( void )
+{
+ --_ISR_Nest_level;
+ --_Thread_Dispatch_disable_level;
+ if (
+ _ISR_Nest_level == 0
+ && _Thread_Dispatch_disable_level == 0
+ && _Thread_Dispatch_necessary
+ ) {
+ _ARMV7M_SCB->icsr = ARMV7M_SCB_ICSR_PENDSVSET;
+ }
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-isr-level-get.c b/cpukit/score/cpu/arm/armv7m-isr-level-get.c
new file mode 100644
index 0000000000..79a03ee0d2
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-isr-level-get.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+uint32_t _CPU_ISR_Get_level( void )
+{
+ return 0;
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-isr-level-set.c b/cpukit/score/cpu/arm/armv7m-isr-level-set.c
new file mode 100644
index 0000000000..981ac063f4
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-isr-level-set.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void _CPU_ISR_Set_level( uint32_t level )
+{
+ _ARMV7M_Set_basepri( 0 );
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-isr-vector-install.c b/cpukit/score/cpu/arm/armv7m-isr-vector-install.c
new file mode 100644
index 0000000000..c2f52943cb
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-isr-vector-install.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/isr.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ uint32_t level;
+
+ _ISR_Disable( level );
+ if ( old_handler != NULL ) {
+ *old_handler = _ARMV7M_Get_exception_handler( (int) vector );
+ }
+ _ARMV7M_Set_exception_handler( (int) vector, new_handler );
+ _ISR_Enable( level );
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/armv7m-multitasking-start-stop.c b/cpukit/score/cpu/arm/armv7m-multitasking-start-stop.c
new file mode 100644
index 0000000000..1827f97dfa
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv7m-multitasking-start-stop.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+#include <rtems/score/armv7m.h>
+
+void __attribute__((naked)) _ARMV7M_Start_multitasking(
+ Context_Control *bsp,
+ Context_Control *heir
+)
+{
+ __asm__ volatile (
+ /* Store BSP context */
+ "stm r0, {r4-r11, lr}\n"
+ "str sp, [r0, %[spctxoff]]\n"
+ /* Restore heir context */
+ "ldr r2, [r1, %[spctxoff]]\n"
+ "msr psp, r2\n"
+ "ldm r1, {r4-r11, lr}\n"
+ /* Enable process stack pointer (PSP) */
+ "mrs r2, control\n"
+ "orr r2, #0x2\n"
+ "msr control, r2\n"
+ /* Return to heir */
+ "bx lr\n"
+ :
+ : [spctxoff] "J" (offsetof(Context_Control, register_sp))
+ );
+}
+
+void __attribute__((naked)) _ARMV7M_Stop_multitasking( Context_Control *bsp )
+{
+ __asm__ volatile (
+ /* Disable interrupts */
+ "mov r2, #0x80\n"
+ "msr basepri_max, r2\n"
+ /* Restore BSP context */
+ "ldr r2, [r0, %[spctxoff]]\n"
+ "msr msp, r2\n"
+ "ldm r0, {r4-r11, lr}\n"
+ /* Disable process stack pointer (PSP) */
+ "mrs r2, control\n"
+ "bic r2, #0x2\n"
+ "msr control, r2\n"
+ /* Return to BSP */
+ "bx lr\n"
+ :
+ : [spctxoff] "J" (offsetof(Context_Control, register_sp))
+ );
+ __builtin_unreachable();
+}
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/cpu.c b/cpukit/score/cpu/arm/cpu.c
index 00ff4aabcd..89f5ce2d7a 100644
--- a/cpukit/score/cpu/arm/cpu.c
+++ b/cpukit/score/cpu/arm/cpu.c
@@ -15,7 +15,7 @@
*
* Copyright (c) 2007 Ray xu <rayx.cn@gmail.com>
*
- * Copyright (c) 2009 embedded brains GmbH
+ * Copyright (c) 2009-2011 embedded brains GmbH
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -36,6 +36,8 @@
#include <rtems/score/thread.h>
#include <rtems/score/cpu.h>
+#ifdef ARM_MULTILIB_ARCH_V4
+
/*
* This variable can be used to change the running mode of the execution
* contexts.
@@ -44,14 +46,14 @@ uint32_t arm_cpu_mode = 0x13;
void _CPU_Context_Initialize(
Context_Control *the_context,
- uint32_t *stack_base,
- uint32_t size,
+ void *stack_area_begin,
+ size_t stack_area_size,
uint32_t new_level,
- void *entry_point,
+ void (*entry_point)( void ),
bool is_fp
)
{
- the_context->register_sp = (uint32_t) stack_base + size ;
+ the_context->register_sp = (uint32_t) stack_area_begin + stack_area_size;
the_context->register_lr = (uint32_t) entry_point;
the_context->register_cpsr = new_level | arm_cpu_mode;
}
@@ -114,12 +116,9 @@ void _CPU_ISR_install_vector(
}
}
-void _CPU_Install_interrupt_stack( void )
-{
- /* This function is empty since the BSP must set up the interrupt stacks */
-}
-
void _CPU_Initialize( void )
{
/* Do nothing */
}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S
index 9eebabae38..340ebd5dbd 100644
--- a/cpukit/score/cpu/arm/cpu_asm.S
+++ b/cpukit/score/cpu/arm/cpu_asm.S
@@ -34,6 +34,8 @@
#include <rtems/asm.h>
#include <rtems/score/cpu_asm.h>
+#ifdef ARM_MULTILIB_ARCH_V4
+
.text
/*
@@ -78,3 +80,5 @@ _restore:
DEFINE_FUNCTION_ARM(_CPU_Context_restore)
mov r1, r0
b _restore
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/cpukit/score/cpu/arm/preinstall.am b/cpukit/score/cpu/arm/preinstall.am
index 90ac37443e..92ba4687fc 100644
--- a/cpukit/score/cpu/arm/preinstall.am
+++ b/cpukit/score/cpu/arm/preinstall.am
@@ -39,6 +39,10 @@ $(PROJECT_INCLUDE)/rtems/score/arm.h: rtems/score/arm.h $(PROJECT_INCLUDE)/rtems
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/arm.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/arm.h
+$(PROJECT_INCLUDE)/rtems/score/armv7m.h: rtems/score/armv7m.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/armv7m.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/armv7m.h
+
$(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
diff --git a/cpukit/score/cpu/arm/rtems/score/arm.h b/cpukit/score/cpu/arm/rtems/score/arm.h
index 5c47e4c617..c0a7c8bb54 100644
--- a/cpukit/score/cpu/arm/rtems/score/arm.h
+++ b/cpukit/score/cpu/arm/rtems/score/arm.h
@@ -44,40 +44,52 @@ extern "C" {
*/
#if defined(__ARM_ARCH_4__)
# define CPU_MODEL_NAME "ARMv4"
+# define ARM_MULTILIB_ARCH_V4
#elif defined(__ARM_ARCH_4T__)
# define CPU_MODEL_NAME "ARMv4T"
+# define ARM_MULTILIB_ARCH_V4
#elif defined(__ARM_ARCH_5__)
# define CPU_MODEL_NAME "ARMv5"
+# define ARM_MULTILIB_ARCH_V4
#elif defined(__ARM_ARCH_5T__)
# define CPU_MODEL_NAME "ARMv5T"
+# define ARM_MULTILIB_ARCH_V4
#elif defined(__ARM_ARCH_5E__)
# define CPU_MODEL_NAME "ARMv5E"
+# define ARM_MULTILIB_ARCH_V4
#elif defined(__ARM_ARCH_5TE__)
# define CPU_MODEL_NAME "ARMv5TE"
+# define ARM_MULTILIB_ARCH_V4
#elif defined(__ARM_ARCH_5TEJ__)
# define CPU_MODEL_NAME "ARMv5TEJ"
+# define ARM_MULTILIB_ARCH_V4
#elif defined(__ARM_ARCH_6J__)
# define CPU_MODEL_NAME "ARMv6J"
#elif defined(__ARM_ARCH_6M__)
# define CPU_MODEL_NAME "ARMv6M"
+# define ARM_MULTILIB_ARCH_V7M
#elif defined(__ARM_ARCH_7__)
# define CPU_MODEL_NAME "ARMv7"
-#elif defined(__ARM_ARCH_7M__)
-# define CPU_MODEL_NAME "ARMv7M"
-
#elif defined(__ARM_ARCH_7A__)
# define CPU_MODEL_NAME "ARMv7A"
+#elif defined(__ARM_ARCH_7R__)
+# define CPU_MODEL_NAME "ARMv7R"
+
+#elif defined(__ARM_ARCH_7M__)
+# define CPU_MODEL_NAME "ARMv7M"
+# define ARM_MULTILIB_ARCH_V7M
+
#else
# error "Unsupported CPU Model"
diff --git a/cpukit/score/cpu/arm/rtems/score/armv7m.h b/cpukit/score/cpu/arm/rtems/score/armv7m.h
new file mode 100644
index 0000000000..1005b23ae3
--- /dev/null
+++ b/cpukit/score/cpu/arm/rtems/score/armv7m.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2011 Sebastian Huber. 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$
+ */
+
+#ifndef RTEMS_SCORE_ARMV7M_H
+#define RTEMS_SCORE_ARMV7M_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct {
+ uint32_t reserved_0;
+ uint32_t ictr;
+ uint32_t actlr;
+ uint32_t reserved_1;
+} ARMV7M_Interrupt_type;
+
+typedef void (*ARMV7M_Exception_handler)(void);
+
+typedef struct {
+ uint32_t register_r0;
+ uint32_t register_r1;
+ uint32_t register_r2;
+ uint32_t register_r3;
+ uint32_t register_r12;
+ void *register_lr;
+ void *register_pc;
+ uint32_t register_xpsr;
+} ARMV7M_Exception_frame;
+
+typedef struct {
+ uint32_t cpuid;
+
+#define ARMV7M_SCB_ICSR_NMIPENDSET (1U << 31)
+#define ARMV7M_SCB_ICSR_PENDSVSET (1U << 28)
+#define ARMV7M_SCB_ICSR_PENDSVCLR (1U << 27)
+#define ARMV7M_SCB_ICSR_PENDSTSET (1U << 26)
+#define ARMV7M_SCB_ICSR_PENDSTCLR (1U << 25)
+#define ARMV7M_SCB_ICSR_ISRPREEMPT (1U << 23)
+#define ARMV7M_SCB_ICSR_ISRPENDING (1U << 22)
+#define ARMV7M_SCB_ICSR_VECTPENDING(reg) (((reg) >> 12) & 0x1ffU)
+#define ARMV7M_SCB_ICSR_RETTOBASE (1U << 11)
+#define ARMV7M_SCB_ICSR_VECTACTIVE(reg) ((reg) & 0x1ffU)
+ uint32_t icsr;
+
+ ARMV7M_Exception_handler *vtor;
+ uint32_t aircr;
+ uint32_t scr;
+ uint32_t ccr;
+ uint8_t shpr [12];
+ uint32_t shcsr;
+ uint32_t cfsr;
+ uint32_t hfsr;
+ uint32_t dfsr;
+ uint32_t mmfar;
+ uint32_t bfar;
+ uint32_t afsr;
+} ARMV7M_SCB;
+
+typedef struct {
+#define ARMV7M_SYSTICK_CSR_COUNTFLAG (1U << 16)
+#define ARMV7M_SYSTICK_CSR_CLKSOURCE (1U << 2)
+#define ARMV7M_SYSTICK_CSR_TICKINT (1U << 1)
+#define ARMV7M_SYSTICK_CSR_ENABLE (1U << 0)
+ uint32_t csr;
+
+ uint32_t rvr;
+ uint32_t cvr;
+
+#define ARMV7M_SYSTICK_CALIB_NOREF (1U << 31)
+#define ARMV7M_SYSTICK_CALIB_SKEW (1U << 30)
+#define ARMV7M_SYSTICK_CALIB_TENMS(reg) ((reg) & 0xffffffU)
+ uint32_t calib;
+} ARMV7M_Systick;
+
+typedef struct {
+ uint32_t iser [8];
+ uint32_t reserved_0 [24];
+ uint32_t icer [8];
+ uint32_t reserved_1 [24];
+ uint32_t ispr [8];
+ uint32_t reserved_2 [24];
+ uint32_t icpr [8];
+ uint32_t reserved_3 [24];
+ uint32_t iabr [8];
+ uint32_t reserved_4 [56];
+ uint8_t ipr [240];
+ uint32_t reserved_5 [644];
+ uint32_t stir;
+} ARMV7M_NVIC;
+
+#define ARMV7M_SCS_BASE 0xe000e000
+#define ARMV7M_SYSTICK_BASE (ARMV7M_SCS_BASE + 0x10)
+#define ARMV7M_NVIC_BASE (ARMV7M_SCS_BASE + 0x100)
+#define ARMV7M_SCB_BASE (ARMV7M_SCS_BASE + 0xd00)
+
+#define _ARMV7M_Interrupt_type \
+ ((volatile ARMV7M_Interrupt_type *) ARMV7M_SCS_BASE)
+#define _ARMV7M_SCB \
+ ((volatile ARMV7M_SCB *) ARMV7M_SCB_BASE)
+#define _ARMV7M_Systick \
+ ((volatile ARMV7M_Systick *) ARMV7M_SYSTICK_BASE)
+#define _ARMV7M_NVIC \
+ ((volatile ARMV7M_NVIC *) ARMV7M_NVIC_BASE)
+
+#define ARMV7M_VECTOR_MSP 0
+#define ARMV7M_VECTOR_RESET 1
+#define ARMV7M_VECTOR_NMI 2
+#define ARMV7M_VECTOR_HARD_FAULT 3
+#define ARMV7M_VECTOR_MEM_MANAGE 4
+#define ARMV7M_VECTOR_BUS_FAULT 5
+#define ARMV7M_VECTOR_USAGE_FAULT 6
+#define ARMV7M_VECTOR_SVC 11
+#define ARMV7M_VECTOR_DEBUG_MONITOR 12
+#define ARMV7M_VECTOR_PENDSV 14
+#define ARMV7M_VECTOR_SYSTICK 15
+#define ARMV7M_VECTOR_IRQ(n) (16 + (n))
+
+static inline uint32_t _ARMV7M_Get_basepri(void)
+{
+ uint32_t val;
+ __asm__ volatile ("mrs %[val], basepri\n" : [val] "=&r" (val));
+ return val;
+}
+
+static inline void _ARMV7M_Set_basepri(uint32_t val)
+{
+ __asm__ volatile ("msr basepri, %[val]\n" : : [val] "r" (val));
+}
+
+static inline uint32_t _ARMV7M_Get_primask(void)
+{
+ uint32_t val;
+ __asm__ volatile ("mrs %[val], primask\n" : [val] "=&r" (val));
+ return val;
+}
+
+static inline void _ARMV7M_Set_primask(uint32_t val)
+{
+ __asm__ volatile ("msr primask, %[val]\n" : : [val] "r" (val));
+}
+
+static inline uint32_t _ARMV7M_Get_faultmask(void)
+{
+ uint32_t val;
+ __asm__ volatile ("mrs %[val], faultmask\n" : [val] "=&r" (val));
+ return val;
+}
+
+static inline void _ARMV7M_Set_faultmask(uint32_t val)
+{
+ __asm__ volatile ("msr faultmask, %[val]\n" : : [val] "r" (val));
+}
+
+static inline uint32_t _ARMV7M_Get_control(void)
+{
+ uint32_t val;
+ __asm__ volatile ("mrs %[val], control\n" : [val] "=&r" (val));
+ return val;
+}
+
+static inline void _ARMV7M_Set_control(uint32_t val)
+{
+ __asm__ volatile ("msr control, %[val]\n" : : [val] "r" (val));
+}
+
+static inline uint32_t _ARMV7M_Get_MSP(void)
+{
+ uint32_t val;
+ __asm__ volatile ("mrs %[val], msp\n" : [val] "=&r" (val));
+ return val;
+}
+
+static inline void _ARMV7M_Set_MSP(uint32_t val)
+{
+ __asm__ volatile ("msr msp, %[val]\n" : : [val] "r" (val));
+}
+
+static inline uint32_t _ARMV7M_Get_PSP(void)
+{
+ uint32_t val;
+ __asm__ volatile ("mrs %[val], psp\n" : [val] "=&r" (val));
+ return val;
+}
+
+static inline void _ARMV7M_Set_PSP(uint32_t val)
+{
+ __asm__ volatile ("msr psp, %[val]\n" : : [val] "r" (val));
+}
+
+static inline uint32_t _ARMV7M_Get_XPSR(void)
+{
+ uint32_t val;
+ __asm__ volatile ("mrs %[val], xpsr\n" : [val] "=&r" (val));
+ return val;
+}
+
+int _ARMV7M_Get_exception_priority( int vector );
+
+void _ARMV7M_Set_exception_priority( int vector, int priority );
+
+ARMV7M_Exception_handler _ARMV7M_Get_exception_handler( int index );
+
+void _ARMV7M_Set_exception_handler(
+ int index,
+ ARMV7M_Exception_handler handler
+);
+
+void _ARMV7M_Interrupt_service_enter( void );
+
+void _ARMV7M_Interrupt_service_leave( void );
+
+void _ARMV7M_Pendable_service_call( void );
+
+void _ARMV7M_Supervisor_call( void );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SCORE_ARMV7M_H */
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
index f873e7d9b1..a95c2b5881 100644
--- a/cpukit/score/cpu/arm/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/rtems/score/cpu.h
@@ -12,7 +12,7 @@
* This include file contains information pertaining to the ARM
* processor.
*
- * Copyright (c) 2009-2010 embedded brains GmbH.
+ * Copyright (c) 2009-2011 embedded brains GmbH.
*
* Copyright (c) 2007 Ray Xu <Rayx.cn@gmail.com>
*
@@ -36,6 +36,8 @@
#include <rtems/score/types.h>
#include <rtems/score/arm.h>
+#if defined(ARM_MULTILIB_ARCH_V4)
+
/**
* @defgroup ScoreCPUARM ARM Specific Support
*
@@ -93,6 +95,8 @@
/** @} */
+#endif /* defined(ARM_MULTILIB_ARCH_V4) */
+
/**
* @addtogroup ScoreCPU
*
@@ -120,7 +124,7 @@
#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
-#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
@@ -216,6 +220,7 @@ extern "C" {
*/
typedef struct {
+#if defined(ARM_MULTILIB_ARCH_V4)
uint32_t register_cpsr;
uint32_t register_r4;
uint32_t register_r5;
@@ -228,6 +233,19 @@ typedef struct {
uint32_t register_sp;
uint32_t register_lr;
uint32_t register_pc;
+#elif defined(ARM_MULTILIB_ARCH_V7M)
+ uint32_t register_r4;
+ uint32_t register_r5;
+ uint32_t register_r6;
+ uint32_t register_r7;
+ uint32_t register_r8;
+ uint32_t register_r9;
+ uint32_t register_r10;
+ uint32_t register_r11;
+ void *register_lr;
+ void *register_sp;
+ uint32_t isr_nest_level;
+#endif
} Context_Control;
typedef struct {
@@ -240,6 +258,7 @@ extern uint32_t arm_cpu_mode;
static inline uint32_t arm_interrupt_disable( void )
{
+#if defined(ARM_MULTILIB_ARCH_V4)
uint32_t arm_switch_reg;
uint32_t level;
@@ -253,10 +272,24 @@ static inline uint32_t arm_interrupt_disable( void )
);
return level;
+#elif defined(ARM_MULTILIB_ARCH_V7M)
+ uint32_t level;
+ uint32_t basepri = 0x80;
+
+ __asm__ volatile (
+ "mrs %[level], basepri\n"
+ "msr basepri_max, %[basepri]\n"
+ : [level] "=&r" (level)
+ : [basepri] "r" (basepri)
+ );
+
+ return level;
+#endif
}
static inline void arm_interrupt_enable( uint32_t level )
{
+#if defined(ARM_MULTILIB_ARCH_V4)
ARM_SWITCH_REGISTERS;
__asm__ volatile (
@@ -266,10 +299,18 @@ static inline void arm_interrupt_enable( uint32_t level )
: ARM_SWITCH_OUTPUT
: [level] "r" (level)
);
+#elif defined(ARM_MULTILIB_ARCH_V7M)
+ __asm__ volatile (
+ "msr basepri, %[level]\n"
+ :
+ : [level] "r" (level)
+ );
+#endif
}
static inline void arm_interrupt_flash( uint32_t level )
{
+#if defined(ARM_MULTILIB_ARCH_V4)
uint32_t arm_switch_reg;
__asm__ volatile (
@@ -281,6 +322,17 @@ static inline void arm_interrupt_flash( uint32_t level )
: [arm_switch_reg] "=&r" (arm_switch_reg)
: [level] "r" (level)
);
+#elif defined(ARM_MULTILIB_ARCH_V7M)
+ uint32_t basepri;
+
+ __asm__ volatile (
+ "mrs %[basepri], basepri\n"
+ "msr basepri, %[level]\n"
+ "msr basepri, %[basepri]\n"
+ : [basepri] "=&r" (basepri)
+ : [level] "r" (level)
+ );
+#endif
}
#define _CPU_ISR_Disable( _isr_cookie ) \
@@ -300,10 +352,10 @@ uint32_t _CPU_ISR_Get_level( void );
void _CPU_Context_Initialize(
Context_Control *the_context,
- uint32_t *stack_base,
- uint32_t size,
+ void *stack_area_begin,
+ size_t stack_area_size,
uint32_t new_level,
- void *entry_point,
+ void (*entry_point)( void ),
bool is_fp
);
@@ -343,12 +395,18 @@ void _CPU_ISR_install_vector(
proc_ptr *old_handler
);
-void _CPU_Install_interrupt_stack( void );
-
void _CPU_Context_switch( Context_Control *run, Context_Control *heir );
void _CPU_Context_restore( Context_Control *new_context )
- RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
+ RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
+
+#if defined(ARM_MULTILIB_ARCH_V7M)
+ void _ARMV7M_Start_multitasking( Context_Control *bsp, Context_Control *heir );
+ void _ARMV7M_Stop_multitasking( Context_Control *bsp )
+ RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
+ #define _CPU_Start_multitasking _ARMV7M_Start_multitasking
+ #define _CPU_Stop_multitasking _ARMV7M_Stop_multitasking
+#endif
void _CPU_Context_save_fp( Context_Control_fp **fp_context_ptr );
@@ -356,7 +414,14 @@ void _CPU_Context_restore_fp( Context_Control_fp **fp_context_ptr );
static inline uint32_t CPU_swap_u32( uint32_t value )
{
-#if defined(__thumb__)
+#if defined(__thumb2__)
+ __asm__ volatile (
+ "rev %0, %0"
+ : "=r" (value)
+ : "0" (value)
+ );
+ return value;
+#elif defined(__thumb__)
uint32_t byte1, byte2, byte3, byte4, swapped;
byte4 = (value >> 24) & 0xff;
@@ -380,11 +445,22 @@ static inline uint32_t CPU_swap_u32( uint32_t value )
static inline uint16_t CPU_swap_u16( uint16_t value )
{
+#if defined(__thumb2__)
+ __asm__ volatile (
+ "rev16 %0, %0"
+ : "=r" (value)
+ : "0" (value)
+ );
+ return value;
+#else
return (uint16_t) (((value & 0xffU) << 8) | ((value >> 8) & 0xffU));
+#endif
}
/** @} */
+#if defined(ARM_MULTILIB_ARCH_V4)
+
/**
* @addtogroup ScoreCPUARM
*
@@ -487,6 +563,12 @@ typedef struct {
typedef CPU_Exception_frame CPU_Interrupt_frame;
+#elif defined(ARM_MULTILIB_ARCH_V7M)
+
+typedef void CPU_Interrupt_frame;
+
+#endif /* defined(ARM_MULTILIB_ARCH_V7M) */
+
#ifdef __cplusplus
}
#endif