forked from Imagelibrary/rtems
@@ -43,7 +43,7 @@
|
|||||||
#define EXCHANGE_SIZE 16
|
#define EXCHANGE_SIZE 16
|
||||||
|
|
||||||
#define SELF_CPU_CONTROL r7
|
#define SELF_CPU_CONTROL r7
|
||||||
#define SP_OF_INTERRUPTED_CONTEXT r9
|
#define NON_VOLATILE_SCRATCH r9
|
||||||
|
|
||||||
#define CONTEXT_LIST {r0, r1, r2, r3, EXCHANGE_LR, EXCHANGE_SPSR, SELF_CPU_CONTROL, r12}
|
#define CONTEXT_LIST {r0, r1, r2, r3, EXCHANGE_LR, EXCHANGE_SPSR, SELF_CPU_CONTROL, r12}
|
||||||
#define CONTEXT_SIZE 32
|
#define CONTEXT_SIZE 32
|
||||||
@@ -73,7 +73,7 @@ _ARMV4_Exception_interrupt:
|
|||||||
* interrupted context.
|
* interrupted context.
|
||||||
*/
|
*/
|
||||||
stmdb sp!, CONTEXT_LIST
|
stmdb sp!, CONTEXT_LIST
|
||||||
stmdb sp!, {SP_OF_INTERRUPTED_CONTEXT, lr}
|
stmdb sp!, {NON_VOLATILE_SCRATCH, lr}
|
||||||
|
|
||||||
#ifdef ARM_MULTILIB_VFP
|
#ifdef ARM_MULTILIB_VFP
|
||||||
/* Save VFP context */
|
/* Save VFP context */
|
||||||
@@ -98,7 +98,7 @@ _ARMV4_Exception_interrupt:
|
|||||||
ldr r2, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
|
ldr r2, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
|
||||||
|
|
||||||
/* Switch stack if necessary and save original stack pointer */
|
/* Switch stack if necessary and save original stack pointer */
|
||||||
mov SP_OF_INTERRUPTED_CONTEXT, sp
|
mov NON_VOLATILE_SCRATCH, sp
|
||||||
cmp r2, #0
|
cmp r2, #0
|
||||||
moveq sp, r1
|
moveq sp, r1
|
||||||
|
|
||||||
@@ -130,33 +130,68 @@ _ARMV4_Exception_interrupt:
|
|||||||
bl bsp_interrupt_dispatch
|
bl bsp_interrupt_dispatch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Decrement interrupt nest and thread dispatch disable level */
|
/* Load some per-CPU variables */
|
||||||
ldr r2, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
|
ldr r0, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
|
||||||
ldr r3, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
|
ldrb r1, [SELF_CPU_CONTROL, #PER_CPU_DISPATCH_NEEDED]
|
||||||
sub r2, #1
|
ldr r2, [SELF_CPU_CONTROL, #PER_CPU_ISR_DISPATCH_DISABLE]
|
||||||
sub r3, #1
|
ldr r3, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
|
||||||
str r2, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
|
|
||||||
str r3, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
|
|
||||||
|
|
||||||
/* Restore stack pointer */
|
/* Restore stack pointer */
|
||||||
mov sp, SP_OF_INTERRUPTED_CONTEXT
|
mov sp, NON_VOLATILE_SCRATCH
|
||||||
|
|
||||||
/* Check thread dispatch disable level */
|
/* Save CPSR in non-volatile register */
|
||||||
cmp r3, #0
|
mrs NON_VOLATILE_SCRATCH, CPSR
|
||||||
|
|
||||||
|
/* Decrement levels and determine thread dispatch state */
|
||||||
|
eor r1, r0
|
||||||
|
sub r0, #1
|
||||||
|
orr r1, r0
|
||||||
|
orr r1, r2
|
||||||
|
sub r3, #1
|
||||||
|
|
||||||
|
/* Store thread dispatch disable and ISR nest levels */
|
||||||
|
str r0, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
|
||||||
|
str r3, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check thread dispatch necessary, ISR dispatch disable and thread
|
||||||
|
* dispatch disable level.
|
||||||
|
*/
|
||||||
|
cmp r0, #0
|
||||||
bne .Lthread_dispatch_done
|
bne .Lthread_dispatch_done
|
||||||
|
|
||||||
/* Check context switch necessary */
|
|
||||||
ldrb r1, [SELF_CPU_CONTROL, #PER_CPU_DISPATCH_NEEDED]
|
|
||||||
cmp r1, #0
|
|
||||||
beq .Lthread_dispatch_done
|
|
||||||
|
|
||||||
/* This aligns .Lthread_dispatch_done on a 4 byte boundary */
|
|
||||||
#ifdef __thumb__
|
|
||||||
nop
|
|
||||||
#endif /* __thumb__ */
|
|
||||||
|
|
||||||
/* Thread dispatch */
|
/* Thread dispatch */
|
||||||
bl _Thread_Dispatch
|
mrs NON_VOLATILE_SCRATCH, CPSR
|
||||||
|
|
||||||
|
.Ldo_thread_dispatch:
|
||||||
|
|
||||||
|
/* Set ISR dispatch disable and thread dispatch disable level to one */
|
||||||
|
mov r0, #1
|
||||||
|
str r0, [SELF_CPU_CONTROL, #PER_CPU_ISR_DISPATCH_DISABLE]
|
||||||
|
str r0, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
|
||||||
|
|
||||||
|
/* Call _Thread_Do_dispatch(), this function will enable interrupts */
|
||||||
|
mov r0, SELF_CPU_CONTROL
|
||||||
|
mov r1, NON_VOLATILE_SCRATCH
|
||||||
|
mov r2, #0x80
|
||||||
|
bic r1, r2
|
||||||
|
bl _Thread_Do_dispatch
|
||||||
|
|
||||||
|
/* Disable interrupts */
|
||||||
|
msr CPSR, NON_VOLATILE_SCRATCH
|
||||||
|
|
||||||
|
#ifdef RTEMS_SMP
|
||||||
|
GET_SELF_CPU_CONTROL SELF_CPU_CONTROL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check if we have to do the thread dispatch again */
|
||||||
|
ldrb r0, [SELF_CPU_CONTROL, #PER_CPU_DISPATCH_NEEDED]
|
||||||
|
cmp r0, #0
|
||||||
|
bne .Ldo_thread_dispatch
|
||||||
|
|
||||||
|
/* We are done with thread dispatching */
|
||||||
|
mov r0, #0
|
||||||
|
str r0, [SELF_CPU_CONTROL, #PER_CPU_ISR_DISPATCH_DISABLE]
|
||||||
|
|
||||||
.Lthread_dispatch_done:
|
.Lthread_dispatch_done:
|
||||||
|
|
||||||
@@ -173,8 +208,8 @@ _ARMV4_Exception_interrupt:
|
|||||||
vmsr FPSCR, r0
|
vmsr FPSCR, r0
|
||||||
#endif /* ARM_MULTILIB_VFP */
|
#endif /* ARM_MULTILIB_VFP */
|
||||||
|
|
||||||
/* Restore SP_OF_INTERRUPTED_CONTEXT register and link register */
|
/* Restore NON_VOLATILE_SCRATCH register and link register */
|
||||||
ldmia sp!, {SP_OF_INTERRUPTED_CONTEXT, lr}
|
ldmia sp!, {NON_VOLATILE_SCRATCH, lr}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: Remember and restore stack pointer. The data on the stack is
|
* XXX: Remember and restore stack pointer. The data on the stack is
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2007 Ray xu <rayx.cn@gmail.com>
|
* Copyright (c) 2007 Ray xu <rayx.cn@gmail.com>
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009-2011 embedded brains GmbH
|
* Copyright (c) 2009, 2016 embedded brains GmbH
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
@@ -50,6 +50,14 @@
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARM_MULTILIB_ARCH_V4
|
||||||
|
RTEMS_STATIC_ASSERT(
|
||||||
|
offsetof( Context_Control, isr_dispatch_disable )
|
||||||
|
== ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE,
|
||||||
|
ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RTEMS_SMP
|
#ifdef RTEMS_SMP
|
||||||
RTEMS_STATIC_ASSERT(
|
RTEMS_STATIC_ASSERT(
|
||||||
offsetof( Context_Control, is_executing )
|
offsetof( Context_Control, is_executing )
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2015 embedded brains GmbH
|
* Copyright (c) 2013, 2016 embedded brains GmbH
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
@@ -58,6 +58,9 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)
|
|||||||
mrs r2, CPSR
|
mrs r2, CPSR
|
||||||
stmia r0, {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
|
stmia r0, {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
|
||||||
|
|
||||||
|
GET_SELF_CPU_CONTROL r2
|
||||||
|
ldr r4, [r2, #PER_CPU_ISR_DISPATCH_DISABLE]
|
||||||
|
|
||||||
#ifdef ARM_MULTILIB_VFP
|
#ifdef ARM_MULTILIB_VFP
|
||||||
add r3, r0, #ARM_CONTEXT_CONTROL_D8_OFFSET
|
add r3, r0, #ARM_CONTEXT_CONTROL_D8_OFFSET
|
||||||
vstm r3, {d8-d15}
|
vstm r3, {d8-d15}
|
||||||
@@ -68,6 +71,8 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)
|
|||||||
str r3, [r0, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
|
str r3, [r0, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
str r4, [r0, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]
|
||||||
|
|
||||||
#ifdef RTEMS_SMP
|
#ifdef RTEMS_SMP
|
||||||
/*
|
/*
|
||||||
* The executing thread no longer executes on this processor. Switch
|
* The executing thread no longer executes on this processor. Switch
|
||||||
@@ -75,7 +80,6 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)
|
|||||||
* the context of the executing thread as not executing.
|
* the context of the executing thread as not executing.
|
||||||
*/
|
*/
|
||||||
dmb
|
dmb
|
||||||
GET_SELF_CPU_CONTROL r2
|
|
||||||
add sp, r2, #(PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE)
|
add sp, r2, #(PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE)
|
||||||
mov r3, #0
|
mov r3, #0
|
||||||
strb r3, [r0, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
|
strb r3, [r0, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
|
||||||
@@ -102,6 +106,8 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)
|
|||||||
clrex
|
clrex
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ldr r4, [r1, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]
|
||||||
|
|
||||||
#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
|
#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
|
||||||
ldr r3, [r1, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
|
ldr r3, [r1, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
|
||||||
mcr p15, 0, r3, c13, c0, 3
|
mcr p15, 0, r3, c13, c0, 3
|
||||||
@@ -112,6 +118,8 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)
|
|||||||
vldm r3, {d8-d15}
|
vldm r3, {d8-d15}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
str r4, [r2, #PER_CPU_ISR_DISPATCH_DISABLE]
|
||||||
|
|
||||||
ldmia r1, {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
|
ldmia r1, {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
|
||||||
msr CPSR_fsxc, r2
|
msr CPSR_fsxc, r2
|
||||||
#ifdef __thumb__
|
#ifdef __thumb__
|
||||||
@@ -129,6 +137,7 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)
|
|||||||
*/
|
*/
|
||||||
DEFINE_FUNCTION_ARM(_CPU_Context_restore)
|
DEFINE_FUNCTION_ARM(_CPU_Context_restore)
|
||||||
mov r1, r0
|
mov r1, r0
|
||||||
|
GET_SELF_CPU_CONTROL r2
|
||||||
b .L_restore
|
b .L_restore
|
||||||
|
|
||||||
#ifdef RTEMS_SMP
|
#ifdef RTEMS_SMP
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* This include file contains information pertaining to the ARM
|
* This include file contains information pertaining to the ARM
|
||||||
* processor.
|
* processor.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009-2015 embedded brains GmbH.
|
* Copyright (c) 2009, 2016 embedded brains GmbH
|
||||||
*
|
*
|
||||||
* Copyright (c) 2007 Ray Xu <Rayx.cn@gmail.com>
|
* Copyright (c) 2007 Ray Xu <Rayx.cn@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -209,11 +209,19 @@
|
|||||||
#define ARM_CONTEXT_CONTROL_D8_OFFSET 48
|
#define ARM_CONTEXT_CONTROL_D8_OFFSET 48
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARM_MULTILIB_ARCH_V4
|
||||||
|
#ifdef ARM_MULTILIB_VFP
|
||||||
|
#define ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE 112
|
||||||
|
#else
|
||||||
|
#define ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE 48
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RTEMS_SMP
|
#ifdef RTEMS_SMP
|
||||||
#ifdef ARM_MULTILIB_VFP
|
#ifdef ARM_MULTILIB_VFP
|
||||||
#define ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 112
|
#define ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 116
|
||||||
#else
|
#else
|
||||||
#define ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 48
|
#define ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 52
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -277,6 +285,9 @@ typedef struct {
|
|||||||
uint64_t register_d14;
|
uint64_t register_d14;
|
||||||
uint64_t register_d15;
|
uint64_t register_d15;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ARM_MULTILIB_ARCH_V4
|
||||||
|
uint32_t isr_dispatch_disable;
|
||||||
|
#endif
|
||||||
#ifdef RTEMS_SMP
|
#ifdef RTEMS_SMP
|
||||||
volatile bool is_executing;
|
volatile bool is_executing;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user