qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Added specific ARM_FEATURE for Thumb-exception enab


From: GitNoviceMikeH
Subject: [Qemu-devel] [PATCH] Added specific ARM_FEATURE for Thumb-exception enable bit
Date: Thu, 3 Sep 2015 10:27:33 +0100

From: GitNoviceMikeH <address@hidden>

Most ARM cores switch unconditionally to ARM mode when an exception occurs;
a few (Cortex) variants have a "Thumb-exception enable" bit in the system
control register that allows an unconditional switch to Thumb mode instead
when handling exceptions.  The presence of this bit seems unrelated to the 
version of instruction set, so seems sensible to handle it as yet another
ARM feature?
Also added four V4T ARM CPU definitions - 720T, 920T, 922T and 940T.

---
 target-arm/cpu.c    | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/cpu.h    |  1 +
 target-arm/helper.c | 11 ++++++++---
 3 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index cc6c6f3..1e81a81 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -699,6 +699,53 @@ static ObjectClass *arm_cpu_class_by_name(const char 
*cpu_model)
 /* CPU models. These are not needed for the AArch64 linux-user build. */
 #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
 
+static void arm720t_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm720t";
+    set_feature(&cpu->env, ARM_FEATURE_V4T);
+    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    cpu->midr = 0x41807204;
+    cpu->reset_sctlr = 0x00090078;
+}
+
+static void arm920t_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm920t";
+    set_feature(&cpu->env, ARM_FEATURE_V4T);
+    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    cpu->midr = 0x41129200;
+    cpu->ctr = 0x0d172172;
+    cpu->reset_sctlr = 0x00090078;
+}
+
+static void arm922t_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm922t";
+    set_feature(&cpu->env, ARM_FEATURE_V4T);
+    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    cpu->midr = 0x41029220;
+    cpu->ctr = 0x0d132132;
+    cpu->reset_sctlr = 0x00090078;
+}
+
+static void arm940t_initfn(Object *obj)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm940t";
+    set_feature(&cpu->env, ARM_FEATURE_V4T);
+    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    cpu->midr = 0x41029400;
+    cpu->ctr = 0x0f0f10f1;
+    cpu->reset_sctlr = 0x00090078;
+}
+
 static void arm926_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
@@ -933,6 +980,7 @@ static void cortex_r5_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
     set_feature(&cpu->env, ARM_FEATURE_V7MP);
     set_feature(&cpu->env, ARM_FEATURE_MPU);
+    set_feature(&cpu->env, ARM_FEATURE_SCTLR_TE_BIT);
     cpu->midr = 0x411fc153; /* r1p3 */
     cpu->id_pfr0 = 0x0131;
     cpu->id_pfr1 = 0x001;
@@ -971,6 +1019,7 @@ static void cortex_a8_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
     set_feature(&cpu->env, ARM_FEATURE_EL3);
+    set_feature(&cpu->env, ARM_FEATURE_SCTLR_TE_BIT);
     cpu->midr = 0x410fc080;
     cpu->reset_fpsid = 0x410330c0;
     cpu->mvfr0 = 0x11110222;
@@ -1039,6 +1088,7 @@ static void cortex_a9_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_NEON);
     set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
     set_feature(&cpu->env, ARM_FEATURE_EL3);
+    set_feature(&cpu->env, ARM_FEATURE_SCTLR_TE_BIT);
     /* Note that A9 supports the MP extensions even for
      * A9UP and single-core A9MP (which are both different
      * and valid configurations; we don't model A9UP).
@@ -1107,6 +1157,7 @@ static void cortex_a15_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
     set_feature(&cpu->env, ARM_FEATURE_LPAE);
     set_feature(&cpu->env, ARM_FEATURE_EL3);
+    set_feature(&cpu->env, ARM_FEATURE_SCTLR_TE_BIT);
     cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
     cpu->midr = 0x412fc0f1;
     cpu->reset_fpsid = 0x410430f0;
@@ -1330,6 +1381,10 @@ typedef struct ARMCPUInfo {
 
 static const ARMCPUInfo arm_cpus[] = {
 #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
+    { .name = "arm720t",     .initfn = arm720t_initfn },
+    { .name = "arm920t",     .initfn = arm920t_initfn },
+    { .name = "arm922t",     .initfn = arm922t_initfn },
+    { .name = "arm940t",     .initfn = arm940t_initfn },
     { .name = "arm926",      .initfn = arm926_initfn },
     { .name = "arm946",      .initfn = arm946_initfn },
     { .name = "arm1026",     .initfn = arm1026_initfn },
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 31825d3..f922da2 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -905,6 +905,7 @@ enum arm_features {
     ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */
     ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */
     ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
+    ARM_FEATURE_SCTLR_TE_BIT, /* Thumb-exception bit in control register */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7df1f06..e8bd71e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5658,11 +5658,16 @@ void arm_cpu_do_interrupt(CPUState *cs)
     /* Switch to the new mode, and to the correct instruction set.  */
     env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
     env->daif |= mask;
-    /* this is a lie, as the was no c1_sys on V4T/V5, but who cares
-     * and we should just guard the thumb mode on V4 */
-    if (arm_feature(env, ARM_FEATURE_V4T)) {
+    
+    /* Most ARM cores switch unconditionally to ARM mode when an exception
+     * occurs: */
+    env->thumb = false;
+    /* ...but certain cores have a Thumb-exception enable bit in the system
+     * control register: */
+    if (arm_feature(env, ARM_FEATURE_SCTLR_TE_BIT)) {
         env->thumb = (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;
     }
+    
     env->regs[14] = env->regs[15] + offset;
     env->regs[15] = addr;
     cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
-- 
1.9.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]