Index: cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-arm/cpu.h,v retrieving revision 1.28 diff -u -r1.28 cpu.h --- cpu.h 24 Jun 2007 12:09:48 -0000 1.28 +++ cpu.h 2 Jul 2007 13:16:12 -0000 @@ -247,7 +247,9 @@ ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */ ARM_FEATURE_XSCALE, /* Intel XScale extensions. */ ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */ - ARM_FEATURE_MPU /* Only has Memory Protection Unit, not full MMU. */ + ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */ + ARM_FEATURE_THUMB1, /* Thumb v1 (ARM v4 with Thumb) */ + ARM_FEATURE_NO_CP15 /* ARM7TDMI, ARM7TDMI-S, ARM7EJ-S, and ARM9TDMI cores do not have a CP15 */ }; static inline int arm_feature(CPUARMState *env, int feature) @@ -262,6 +264,7 @@ ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write, void *opaque); +#define ARM_CPUID_ARM7TDMI 0x41807000 /* guess; no CP15 on ARM7TDMI */ #define ARM_CPUID_ARM1026 0x4106a262 #define ARM_CPUID_ARM926 0x41069265 #define ARM_CPUID_ARM946 0x41059461 Index: helper.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/helper.c,v retrieving revision 1.17 diff -u -r1.17 helper.c --- helper.c 24 Jun 2007 12:09:48 -0000 1.17 +++ helper.c 2 Jul 2007 13:16:12 -0000 @@ -14,6 +14,11 @@ { env->cp15.c0_cpuid = id; switch (id) { + case ARM_CPUID_ARM7TDMI: + set_feature(env, ARM_FEATURE_THUMB1); + set_feature(env, ARM_FEATURE_NO_CP15); + /* no CP15 here */ + break; case ARM_CPUID_ARM926: set_feature(env, ARM_FEATURE_VFP); env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; @@ -98,6 +103,7 @@ }; static const struct arm_cpu_t arm_cpu_names[] = { + { ARM_CPUID_ARM7TDMI, "arm7tdmi"}, { ARM_CPUID_ARM926, "arm926"}, { ARM_CPUID_ARM946, "arm946"}, { ARM_CPUID_ARM1026, "arm1026"}, Index: translate.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/translate.c,v retrieving revision 1.53 diff -u -r1.53 translate.c --- translate.c 11 Jun 2007 18:59:35 -0000 1.53 +++ translate.c 2 Jul 2007 13:16:13 -0000 @@ -1589,7 +1589,7 @@ uint32_t rd; /* ??? Some cp15 registers are accessible from userspace. */ - if (IS_USER(s)) { + if (IS_USER(s) || arm_feature(env, ARM_FEATURE_NO_CP15)) { return 1; } if ((insn & 0x0fff0fff) == 0x0e070f90 @@ -2958,7 +2958,7 @@ } } -static void disas_thumb_insn(DisasContext *s) +static void disas_thumb_insn(CPUState *env, DisasContext *s) { uint32_t val, insn, op, rm, rn, rd, shift, cond; int32_t offset; @@ -3058,6 +3058,7 @@ break; case 3:/* branch [and link] exchange thumb register */ if (insn & (1 << 7)) { + if(arm_feature(env, ARM_FEATURE_THUMB1)) goto undef; val = (uint32_t)s->pc | 1; gen_op_movl_T1_im(val); gen_movl_reg_T1(s, 14); @@ -3367,11 +3368,16 @@ /* write back the new stack pointer */ gen_movl_reg_T1(s, 13); /* set the new PC value */ - if ((insn & 0x0900) == 0x0900) - gen_bx(s); + if ((insn & 0x0900) == 0x0900) { + if(arm_feature(env, ARM_FEATURE_THUMB1)) + gen_movl_reg_T0(s, 15); + else + gen_bx(s); + } break; case 0xe: /* bkpt */ + if(arm_feature(env, ARM_FEATURE_THUMB1)) goto undef; gen_op_movl_T0_im((long)s->pc - 2); gen_op_movl_reg_TN[0][15](); gen_op_bkpt(); @@ -3442,6 +3448,7 @@ /* unconditional branch */ if (insn & (1 << 11)) { /* Second half of blx. */ + if(arm_feature(env, ARM_FEATURE_THUMB1)) goto undef; offset = ((insn & 0x7ff) << 1); gen_movl_T0_reg(s, 14); gen_op_movl_T1_im(offset); @@ -3571,7 +3578,7 @@ } if (env->thumb) - disas_thumb_insn(dc); + disas_thumb_insn(env, dc); else disas_arm_insn(env, dc);