* 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.
This commit is contained in:
Sebastian Huber
2011-09-24 12:56:51 +00:00
parent 86c847c1da
commit c5ed14844e
26 changed files with 1015 additions and 28 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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

View File

@@ -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"

View File

@@ -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 */

View File

@@ -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