From c5ed14844e379eaefaf6cfe27f54d9f17f8984e1 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Sat, 24 Sep 2011 12:56:51 +0000 Subject: 2011-09-24 Sebastian Huber * 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. --- cpukit/score/cpu/arm/ChangeLog | 18 ++ cpukit/score/cpu/arm/Makefile.am | 28 ++- cpukit/score/cpu/arm/arm_exc_abort.S | 4 + cpukit/score/cpu/arm/arm_exc_handler_high.c | 4 + cpukit/score/cpu/arm/arm_exc_handler_low.S | 4 + cpukit/score/cpu/arm/arm_exc_interrupt.S | 4 + cpukit/score/cpu/arm/armv7m-context-initialize.c | 44 ++++ cpukit/score/cpu/arm/armv7m-context-restore.c | 45 ++++ cpukit/score/cpu/arm/armv7m-context-switch.c | 49 +++++ .../score/cpu/arm/armv7m-exception-handler-get.c | 30 +++ .../score/cpu/arm/armv7m-exception-handler-set.c | 35 +++ .../score/cpu/arm/armv7m-exception-priority-get.c | 36 ++++ .../score/cpu/arm/armv7m-exception-priority-set.c | 34 +++ cpukit/score/cpu/arm/armv7m-initialize.c | 46 ++++ cpukit/score/cpu/arm/armv7m-isr-dispatch.c | 65 ++++++ cpukit/score/cpu/arm/armv7m-isr-enter-leave.c | 44 ++++ cpukit/score/cpu/arm/armv7m-isr-level-get.c | 30 +++ cpukit/score/cpu/arm/armv7m-isr-level-set.c | 30 +++ cpukit/score/cpu/arm/armv7m-isr-vector-install.c | 41 ++++ .../score/cpu/arm/armv7m-multitasking-start-stop.c | 71 +++++++ cpukit/score/cpu/arm/cpu.c | 19 +- cpukit/score/cpu/arm/cpu_asm.S | 4 + cpukit/score/cpu/arm/preinstall.am | 4 + cpukit/score/cpu/arm/rtems/score/arm.h | 18 +- cpukit/score/cpu/arm/rtems/score/armv7m.h | 236 +++++++++++++++++++++ cpukit/score/cpu/arm/rtems/score/cpu.h | 100 ++++++++- 26 files changed, 1015 insertions(+), 28 deletions(-) create mode 100644 cpukit/score/cpu/arm/armv7m-context-initialize.c create mode 100644 cpukit/score/cpu/arm/armv7m-context-restore.c create mode 100644 cpukit/score/cpu/arm/armv7m-context-switch.c create mode 100644 cpukit/score/cpu/arm/armv7m-exception-handler-get.c create mode 100644 cpukit/score/cpu/arm/armv7m-exception-handler-set.c create mode 100644 cpukit/score/cpu/arm/armv7m-exception-priority-get.c create mode 100644 cpukit/score/cpu/arm/armv7m-exception-priority-set.c create mode 100644 cpukit/score/cpu/arm/armv7m-initialize.c create mode 100644 cpukit/score/cpu/arm/armv7m-isr-dispatch.c create mode 100644 cpukit/score/cpu/arm/armv7m-isr-enter-leave.c create mode 100644 cpukit/score/cpu/arm/armv7m-isr-level-get.c create mode 100644 cpukit/score/cpu/arm/armv7m-isr-level-set.c create mode 100644 cpukit/score/cpu/arm/armv7m-isr-vector-install.c create mode 100644 cpukit/score/cpu/arm/armv7m-multitasking-start-stop.c create mode 100644 cpukit/score/cpu/arm/rtems/score/armv7m.h (limited to 'cpukit/score/cpu/arm') 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 + + * 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 * 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 #include +#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 #include +#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 #include +#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 #include +#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 + * + * + * 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 + +#include + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 + * + * + * 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 + +#ifdef ARM_MULTILIB_ARCH_V7M + +#include + +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 * - * 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 #include +#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 #include +#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 + * + * + * 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 + +#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 * @@ -36,6 +36,8 @@ #include #include +#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 -- cgit v1.2.3