@@ -394,11 +394,21 @@ void switch_to_hypervisor_ret(void);
#define wfi()
#endif
+#if !defined(__thumb2__)
+/*
+ * We will need to switch to ARM mode (.arm) for some instructions such as
+ * mrc p15 etc.
+ */
+#define asm_arm_or_thumb2(insn) asm volatile(".arm\n\t" insn)
+#else
+#define asm_arm_or_thumb2(insn) asm volatile(insn)
+#endif
+
static inline unsigned long read_mpidr(void)
{
unsigned long val;
- asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (val));
+ asm_arm_or_thumb2("mrc p15, 0, %0, c0, c0, 5" : "=r" (val));
return val;
}
@@ -427,11 +437,13 @@ static inline unsigned int get_cr(void)
unsigned int val;
if (is_hyp())
- asm volatile("mrc p15, 4, %0, c1, c0, 0 @ get CR" : "=r" (val)
+ asm_arm_or_thumb2("mrc p15, 4, %0, c1, c0, 0 @ get CR"
+ : "=r" (val)
:
: "cc");
else
- asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val)
+ asm_arm_or_thumb2("mrc p15, 0, %0, c1, c0, 0 @ get CR"
+ : "=r" (val)
:
: "cc");
return val;
@@ -440,11 +452,11 @@ static inline unsigned int get_cr(void)
static inline void set_cr(unsigned int val)
{
if (is_hyp())
- asm volatile("mcr p15, 4, %0, c1, c0, 0 @ set CR" :
+ asm_arm_or_thumb2("mcr p15, 4, %0, c1, c0, 0 @ set CR" :
: "r" (val)
: "cc");
else
- asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" :
+ asm_arm_or_thumb2("mcr p15, 0, %0, c1, c0, 0 @ set CR" :
: "r" (val)
: "cc");
isb();
@@ -10,6 +10,7 @@
#include <malloc.h>
#include <asm/cache.h>
#include <asm/global_data.h>
+#include <asm/system.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -125,8 +126,8 @@ void invalidate_l2_cache(void)
{
unsigned int val = 0;
- asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
- : : "r" (val) : "cc");
+ asm_arm_or_thumb2("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
+ : : "r" (val) : "cc");
isb();
}
#endif
@@ -85,8 +85,9 @@ struct mbus_win {
static inline unsigned int readfr_extra_feature_reg(void)
{
unsigned int val;
- asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r"
- (val)::"cc");
+
+ asm_arm_or_thumb2("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r"
+ (val)::"cc");
return val;
}
@@ -96,8 +97,8 @@ static inline unsigned int readfr_extra_feature_reg(void)
*/
static inline void writefr_extra_feature_reg(unsigned int val)
{
- asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r"
- (val):"cc");
+ asm_arm_or_thumb2("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r"
+ (val):"cc");
isb();
}
The mcr and msr instructions are available in Thumb mode only if Thumb2 is supported. Therefore, if __thumb2__ is not set, make sure we switch to ARM mode by inserting a .arm directive in the inline assembly. Fixes LTO link errors with kirkwood platforms, triggered by a later commit: tools/buildman/buildman -o /tmp/build -eP sheevaplug [...] {standard input}:24085: Error: selected processor does not support `mrc p15,0,r3,c1,c0,0' in Thumb mode Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> --- arch/arm/include/asm/system.h | 22 +++++++++++++++++----- arch/arm/lib/cache.c | 5 +++-- arch/arm/mach-kirkwood/include/mach/cpu.h | 9 +++++---- 3 files changed, 25 insertions(+), 11 deletions(-)