Hi!
This patch adds ARM7TDMI emulation with Thumb v1 (no BLX, no BKPT, ignore
bit 0 on POP PC) and without CP15.
CU
Uli
--
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
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);