arm: Fix Thumb-1 targets

We cannot use the MRS or MSR instructions in Thumb-1 mode.  Stay in ARM
mode for the Thumb-1 targets during interrupt low-level processing.

Update #2751.
This commit is contained in:
Sebastian Huber
2016-11-21 11:40:00 +01:00
parent f730c25b70
commit 4e2bc0a308
2 changed files with 40 additions and 10 deletions

View File

@@ -102,8 +102,8 @@ _ARMV4_Exception_interrupt:
cmp r2, #0 cmp r2, #0
moveq sp, r1 moveq sp, r1
/* Switch to THUMB instructions if necessary */ /* Switch to Thumb-2 instructions if necessary */
SWITCH_FROM_ARM_TO_THUMB r1 SWITCH_FROM_ARM_TO_THUMB_2 r1
/* Increment interrupt nest and thread dispatch disable level */ /* Increment interrupt nest and thread dispatch disable level */
ldr r3, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL] ldr r3, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
@@ -116,18 +116,18 @@ _ARMV4_Exception_interrupt:
#ifdef RTEMS_PROFILING #ifdef RTEMS_PROFILING
cmp r2, #1 cmp r2, #1
bne .Lskip_profiling bne .Lskip_profiling
bl _CPU_Counter_read BLX_TO_THUMB_1 _CPU_Counter_read
mov SELF_CPU_CONTROL, r0 mov SELF_CPU_CONTROL, r0
bl bsp_interrupt_dispatch BLX_TO_THUMB_1 bsp_interrupt_dispatch
bl _CPU_Counter_read BLX_TO_THUMB_1 _CPU_Counter_read
mov r2, r0 mov r2, r0
mov r1, SELF_CPU_CONTROL mov r1, SELF_CPU_CONTROL
GET_SELF_CPU_CONTROL r0 GET_SELF_CPU_CONTROL r0
mov SELF_CPU_CONTROL, r0 mov SELF_CPU_CONTROL, r0
bl _Profiling_Outer_most_interrupt_entry_and_exit BLX_TO_THUMB_1 _Profiling_Outer_most_interrupt_entry_and_exit
.Lprofiling_done: .Lprofiling_done:
#else #else
bl bsp_interrupt_dispatch BLX_TO_THUMB_1 bsp_interrupt_dispatch
#endif #endif
/* Load some per-CPU variables */ /* Load some per-CPU variables */
@@ -175,7 +175,7 @@ _ARMV4_Exception_interrupt:
mov r1, NON_VOLATILE_SCRATCH mov r1, NON_VOLATILE_SCRATCH
mov r2, #0x80 mov r2, #0x80
bic r1, r2 bic r1, r2
bl _Thread_Do_dispatch BLX_TO_THUMB_1 _Thread_Do_dispatch
/* Disable interrupts */ /* Disable interrupts */
msr CPSR, NON_VOLATILE_SCRATCH msr CPSR, NON_VOLATILE_SCRATCH
@@ -196,7 +196,7 @@ _ARMV4_Exception_interrupt:
.Lthread_dispatch_done: .Lthread_dispatch_done:
/* Switch to ARM instructions if necessary */ /* Switch to ARM instructions if necessary */
SWITCH_FROM_THUMB_TO_ARM SWITCH_FROM_THUMB_2_TO_ARM
#ifdef ARM_MULTILIB_VFP #ifdef ARM_MULTILIB_VFP
/* Restore VFP context */ /* Restore VFP context */
@@ -274,7 +274,7 @@ _ARMV4_Exception_interrupt:
.thumb .thumb
#endif #endif
.Lskip_profiling: .Lskip_profiling:
bl bsp_interrupt_dispatch BLX_TO_THUMB_1 bsp_interrupt_dispatch
b .Lprofiling_done b .Lprofiling_done
#endif #endif

View File

@@ -187,6 +187,36 @@
#endif /* __thumb__ */ #endif /* __thumb__ */
.endm .endm
.macro SWITCH_FROM_THUMB_2_TO_ARM
#ifdef __thumb2__
.align 2
bx pc
.arm
#endif /* __thumb__ */
.endm
.macro SWITCH_FROM_ARM_TO_THUMB_2 REG
#ifdef __thumb2__
add \REG, pc, #1
bx \REG
.thumb
#endif /* __thumb__ */
.endm
.macro BLX_TO_THUMB_1 TARGET
#if defined(__thumb__) && !defined(__thumb2__)
add lr, pc, #1
bx lr
.thumb
bl \TARGET
.align 2
bx pc
.arm
#else
bl \TARGET
#endif
.endm
.macro GET_SELF_CPU_CONTROL REG .macro GET_SELF_CPU_CONTROL REG
#ifdef RTEMS_SMP #ifdef RTEMS_SMP
/* Use PL1 only Thread ID Register (TPIDRPRW) */ /* Use PL1 only Thread ID Register (TPIDRPRW) */