Implement (very) basic Thumb2-EE support. This doesn't actually implement
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 19 Dec 2008 13:18:36 +0000 (13:18 +0000)
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 19 Dec 2008 13:18:36 +0000 (13:18 +0000)
EE state, just the associated system coprocessor registers.  It is sufficient
to keep OS setup and context switching code happy.

Signed-off-by: Paul Brook <paul@codesourcery.com>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6104 c046a42c-6fe2-441c-8c8c-71466251a162

target-arm/cpu.h
target-arm/helper.c
target-arm/helpers.h
target-arm/translate.c

index d6cb116..84d7aa9 100644 (file)
@@ -151,6 +151,10 @@ typedef struct CPUARMState {
         void *opaque;
     } cp[15];
 
+    /* Thumb-2 EE state.  */
+    uint32_t teecr;
+    uint32_t teehbr;
+
     /* Internal CPU feature flags.  */
     uint32_t features;
 
@@ -329,7 +333,8 @@ enum arm_features {
     ARM_FEATURE_NEON,
     ARM_FEATURE_DIV,
     ARM_FEATURE_M, /* Microcontroller profile.  */
-    ARM_FEATURE_OMAPCP  /* OMAP specific CP15 ops handling.  */
+    ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling.  */
+    ARM_FEATURE_THUMB2EE
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
index 8d98ca3..6d95303 100644 (file)
@@ -88,6 +88,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         set_feature(env, ARM_FEATURE_VFP);
         set_feature(env, ARM_FEATURE_VFP3);
         set_feature(env, ARM_FEATURE_NEON);
+        set_feature(env, ARM_FEATURE_THUMB2EE);
         env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
         env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
         env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
@@ -110,6 +111,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         set_feature(env, ARM_FEATURE_VFP);
         set_feature(env, ARM_FEATURE_VFP3);
         set_feature(env, ARM_FEATURE_NEON);
+        set_feature(env, ARM_FEATURE_THUMB2EE);
         set_feature(env, ARM_FEATURE_DIV);
         break;
     case ARM_CPUID_TI915T:
@@ -2595,3 +2597,12 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
     tmp = float32_scalbn(tmp, 31, s);
     return float32_to_int32(tmp, s);
 }
+
+void HELPER(set_teecr)(CPUState *env, uint32_t val)
+{
+    val &= 1;
+    if (env->teecr != val) {
+        env->teecr = val;
+        tb_flush(env);
+    }
+}
index 67207cb..01175e1 100644 (file)
@@ -453,4 +453,6 @@ DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
 DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
 DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
 
+DEF_HELPER_2(set_teecr, void, env, i32)
+
 #include "def-helper.h"
index 0f6fb01..2b5e5c8 100644 (file)
@@ -5536,6 +5536,71 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
     return 0;
 }
 
+static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
+{
+    int crn = (insn >> 16) & 0xf;
+    int crm = insn & 0xf;
+    int op1 = (insn >> 21) & 7;
+    int op2 = (insn >> 5) & 7;
+    int rt = (insn >> 12) & 0xf;
+    TCGv tmp;
+
+    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
+        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
+            /* TEECR */
+            if (IS_USER(s))
+                return 1;
+            tmp = load_cpu_field(teecr);
+            store_reg(s, rt, tmp);
+            return 0;
+        }
+        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
+            /* TEEHBR */
+            if (IS_USER(s) && (env->teecr & 1))
+                return 1;
+            tmp = load_cpu_field(teehbr);
+            store_reg(s, rt, tmp);
+            return 0;
+        }
+    }
+    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
+            op1, crn, crm, op2);
+    return 1;
+}
+
+static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
+{
+    int crn = (insn >> 16) & 0xf;
+    int crm = insn & 0xf;
+    int op1 = (insn >> 21) & 7;
+    int op2 = (insn >> 5) & 7;
+    int rt = (insn >> 12) & 0xf;
+    TCGv tmp;
+
+    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
+        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
+            /* TEECR */
+            if (IS_USER(s))
+                return 1;
+            tmp = load_reg(s, rt);
+            gen_helper_set_teecr(cpu_env, tmp);
+            dead_tmp(tmp);
+            return 0;
+        }
+        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
+            /* TEEHBR */
+            if (IS_USER(s) && (env->teecr & 1))
+                return 1;
+            tmp = load_reg(s, rt);
+            store_cpu_field(tmp, teehbr);
+            return 0;
+        }
+    }
+    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
+            op1, crn, crm, op2);
+    return 1;
+}
+
 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
 {
     int cpnum;
@@ -5557,9 +5622,19 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
     case 10:
     case 11:
        return disas_vfp_insn (env, s, insn);
+    case 14:
+        /* Coprocessors 7-15 are architecturally reserved by ARM.
+           Unfortunately Intel decided to ignore this.  */
+        if (arm_feature(env, ARM_FEATURE_XSCALE))
+            goto board;
+        if (insn & (1 << 20))
+            return disas_cp14_read(env, s, insn);
+        else
+            return disas_cp14_write(env, s, insn);
     case 15:
        return disas_cp15_insn (env, s, insn);
     default:
+    board:
        /* Unknown coprocessor.  See if the board has hooked it.  */
        return disas_cp_insn (env, s, insn);
     }