summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-21 11:40:00 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-21 13:15:35 +0100
commit4e2bc0a308104d96b60d8af1a0c5bcff99fe1564 (patch)
treea37d03f00ab5432c87f9438919b278af5459e7f6
parentpowerpc/mpc5xx: Rename CPU_Interrupt_frame (diff)
downloadrtems-4e2bc0a308104d96b60d8af1a0c5bcff99fe1564.tar.bz2
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.
-rw-r--r--cpukit/score/cpu/arm/arm_exc_interrupt.S20
-rw-r--r--cpukit/score/cpu/arm/rtems/asm.h30
2 files changed, 40 insertions, 10 deletions
diff --git a/cpukit/score/cpu/arm/arm_exc_interrupt.S b/cpukit/score/cpu/arm/arm_exc_interrupt.S
index fc02c91dca..355817e488 100644
--- a/cpukit/score/cpu/arm/arm_exc_interrupt.S
+++ b/cpukit/score/cpu/arm/arm_exc_interrupt.S
@@ -102,8 +102,8 @@ _ARMV4_Exception_interrupt:
cmp r2, #0
moveq sp, r1
- /* Switch to THUMB instructions if necessary */
- SWITCH_FROM_ARM_TO_THUMB r1
+ /* Switch to Thumb-2 instructions if necessary */
+ SWITCH_FROM_ARM_TO_THUMB_2 r1
/* Increment interrupt nest and 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
cmp r2, #1
bne .Lskip_profiling
- bl _CPU_Counter_read
+ BLX_TO_THUMB_1 _CPU_Counter_read
mov SELF_CPU_CONTROL, r0
- bl bsp_interrupt_dispatch
- bl _CPU_Counter_read
+ BLX_TO_THUMB_1 bsp_interrupt_dispatch
+ BLX_TO_THUMB_1 _CPU_Counter_read
mov r2, r0
mov r1, SELF_CPU_CONTROL
GET_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:
#else
- bl bsp_interrupt_dispatch
+ BLX_TO_THUMB_1 bsp_interrupt_dispatch
#endif
/* Load some per-CPU variables */
@@ -175,7 +175,7 @@ _ARMV4_Exception_interrupt:
mov r1, NON_VOLATILE_SCRATCH
mov r2, #0x80
bic r1, r2
- bl _Thread_Do_dispatch
+ BLX_TO_THUMB_1 _Thread_Do_dispatch
/* Disable interrupts */
msr CPSR, NON_VOLATILE_SCRATCH
@@ -196,7 +196,7 @@ _ARMV4_Exception_interrupt:
.Lthread_dispatch_done:
/* Switch to ARM instructions if necessary */
- SWITCH_FROM_THUMB_TO_ARM
+ SWITCH_FROM_THUMB_2_TO_ARM
#ifdef ARM_MULTILIB_VFP
/* Restore VFP context */
@@ -274,7 +274,7 @@ _ARMV4_Exception_interrupt:
.thumb
#endif
.Lskip_profiling:
- bl bsp_interrupt_dispatch
+ BLX_TO_THUMB_1 bsp_interrupt_dispatch
b .Lprofiling_done
#endif
diff --git a/cpukit/score/cpu/arm/rtems/asm.h b/cpukit/score/cpu/arm/rtems/asm.h
index ec5ddc94ac..f72df32325 100644
--- a/cpukit/score/cpu/arm/rtems/asm.h
+++ b/cpukit/score/cpu/arm/rtems/asm.h
@@ -187,6 +187,36 @@
#endif /* __thumb__ */
.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
#ifdef RTEMS_SMP
/* Use PL1 only Thread ID Register (TPIDRPRW) */