From: Ulrich Hecht <uli@suse.de>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] ARM7TDMI emulation
Date: Tue, 3 Jul 2007 16:45:51 +0200 [thread overview]
Message-ID: <200707031645.51832.uli@suse.de> (raw)
In-Reply-To: <200707021814.44821.uli@suse.de>
[-- Attachment #1: Type: text/plain, Size: 323 bytes --]
On Monday 02 July 2007 18:14, Ulrich Hecht wrote:
> Anyway, here's the 920T version. The magic numbers may or may not be
> correct.
And here's an even better version that implements both 920T and 7TDMI
(with base-updated aborts).
CU
Uli
--
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
[-- Attachment #2: qemu-arm7tdmi920t.patch --]
[-- Type: text/x-diff, Size: 10154 bytes --]
Index: target-arm/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.28
diff -u -r1.28 cpu.h
--- target-arm/cpu.h 24 Jun 2007 12:09:48 -0000 1.28
+++ target-arm/cpu.h 3 Jul 2007 14:36:00 -0000
@@ -247,7 +247,10 @@
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_V5, /* ARM v5 instruction set */
+ ARM_FEATURE_NO_CP15, /* ARM7TDMI, ARM7TDMI-S, ARM7EJ-S, and ARM9TDMI cores do not have a CP15 */
+ ARM_FEATURE_ABORT_BU /* base updated abort model, e.g. ARMxTDMI */
};
static inline int arm_feature(CPUARMState *env, int feature)
@@ -262,7 +265,9 @@
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_ARM920T 0x41129200
#define ARM_CPUID_ARM926 0x41069265
#define ARM_CPUID_ARM946 0x41059461
#define ARM_CPUID_PXA250 0x69052100
Index: target-arm/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/helper.c,v
retrieving revision 1.17
diff -u -r1.17 helper.c
--- target-arm/helper.c 24 Jun 2007 12:09:48 -0000 1.17
+++ target-arm/helper.c 3 Jul 2007 14:36:00 -0000
@@ -14,20 +14,31 @@
{
env->cp15.c0_cpuid = id;
switch (id) {
+ case ARM_CPUID_ARM7TDMI:
+ set_feature(env, ARM_FEATURE_ABORT_BU);
+ set_feature(env, ARM_FEATURE_NO_CP15);
+ break;
+ case ARM_CPUID_ARM920T:
+ env->cp15.c0_cachetype = 0x0d172172;
+ env->cp15.c1_sys = 0x00000078;
+ break;
case ARM_CPUID_ARM926:
set_feature(env, ARM_FEATURE_VFP);
+ set_feature(env, ARM_FEATURE_V5);
env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
env->cp15.c0_cachetype = 0x1dd20d2;
env->cp15.c1_sys = 0x00090078;
break;
case ARM_CPUID_ARM946:
set_feature(env, ARM_FEATURE_MPU);
+ set_feature(env, ARM_FEATURE_V5);
env->cp15.c0_cachetype = 0x0f004006;
env->cp15.c1_sys = 0x00000078;
break;
case ARM_CPUID_ARM1026:
set_feature(env, ARM_FEATURE_VFP);
set_feature(env, ARM_FEATURE_AUXCR);
+ set_feature(env, ARM_FEATURE_V5);
env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
env->cp15.c0_cachetype = 0x1dd20d2;
env->cp15.c1_sys = 0x00090078;
@@ -38,6 +49,7 @@
case ARM_CPUID_PXA261:
case ARM_CPUID_PXA262:
set_feature(env, ARM_FEATURE_XSCALE);
+ set_feature(env, ARM_FEATURE_V5);
/* JTAG_ID is ((id << 28) | 0x09265013) */
env->cp15.c0_cachetype = 0xd172172;
env->cp15.c1_sys = 0x00000078;
@@ -49,6 +61,7 @@
case ARM_CPUID_PXA270_C0:
case ARM_CPUID_PXA270_C5:
set_feature(env, ARM_FEATURE_XSCALE);
+ set_feature(env, ARM_FEATURE_V5);
/* JTAG_ID is ((id << 28) | 0x09265013) */
set_feature(env, ARM_FEATURE_IWMMXT);
env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
@@ -98,6 +111,8 @@
};
static const struct arm_cpu_t arm_cpu_names[] = {
+ { ARM_CPUID_ARM7TDMI, "arm7tdmi"},
+ { ARM_CPUID_ARM920T, "arm920t"},
{ ARM_CPUID_ARM926, "arm926"},
{ ARM_CPUID_ARM946, "arm946"},
{ ARM_CPUID_ARM1026, "arm1026"},
Index: target-arm/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/translate.c,v
retrieving revision 1.53
diff -u -r1.53 translate.c
--- target-arm/translate.c 11 Jun 2007 18:59:35 -0000 1.53
+++ target-arm/translate.c 3 Jul 2007 14:36:00 -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
@@ -2780,6 +2780,7 @@
case 0x09:
{
int j, n, user, loaded_base;
+ int crement;
/* load/store multiple words */
/* XXX: store correct base if write back */
user = 0;
@@ -2819,6 +2820,36 @@
}
}
j = 0;
+
+ crement = 0;
+ if(insn & (1 << 21)) {
+ /* write back */
+ if(insn & (1 << 23)) {
+ if(insn & (1 << 24)) {
+ /* pre increment */
+ } else {
+ /* post increment */
+ crement += 4;
+ }
+ } else {
+ if(insn & (1 << 24)) {
+ /* pre decrement */
+ if(n!=1) crement -= (n-1)*4;
+ } else {
+ /* post decrement */
+ crement -= n*4;
+ }
+ }
+ if(arm_feature(env, ARM_FEATURE_ABORT_BU)) {
+ /* base-updated abort model: update base register
+ before an abort can happen */
+ crement += (n - 1) * 4;
+ gen_op_addl_T1_im(crement);
+ gen_movl_reg_T1(s, rn);
+ gen_op_addl_T1_im(-crement);
+ }
+ }
+
for(i=0;i<16;i++) {
if (insn & (1 << i)) {
if (insn & (1 << 20)) {
@@ -2853,25 +2884,10 @@
gen_op_addl_T1_im(4);
}
}
- if (insn & (1 << 21)) {
- /* write back */
- if (insn & (1 << 23)) {
- if (insn & (1 << 24)) {
- /* pre increment */
- } else {
- /* post increment */
- gen_op_addl_T1_im(4);
- }
- } else {
- if (insn & (1 << 24)) {
- /* pre decrement */
- if (n != 1)
- gen_op_addl_T1_im(-((n - 1) * 4));
- } else {
- /* post decrement */
- gen_op_addl_T1_im(-(n * 4));
- }
- }
+ if(!loaded_base && (insn & (1 << 21)) && !arm_feature(env, ARM_FEATURE_ABORT_BU)) {
+ /* base-restored abort model: only update base register
+ after all memory accesses went through */
+ gen_op_addl_T1_im(crement);
gen_movl_reg_T1(s, rn);
}
if (loaded_base) {
@@ -2958,11 +2974,12 @@
}
}
-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;
int i;
+ int crement;
insn = lduw_code(s->pc);
s->pc += 2;
@@ -3058,6 +3075,7 @@
break;
case 3:/* branch [and link] exchange thumb register */
if (insn & (1 << 7)) {
+ if(!arm_feature(env, ARM_FEATURE_V5)) goto undef;
val = (uint32_t)s->pc | 1;
gen_op_movl_T1_im(val);
gen_movl_reg_T1(s, 14);
@@ -3367,11 +3385,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_V5))
+ gen_movl_reg_T0(s, 15);
+ else
+ gen_bx(s);
+ }
break;
case 0xe: /* bkpt */
+ if(!arm_feature(env, ARM_FEATURE_V5)) goto undef;
gen_op_movl_T0_im((long)s->pc - 2);
gen_op_movl_reg_TN[0][15]();
gen_op_bkpt();
@@ -3387,6 +3410,17 @@
/* load/store multiple */
rn = (insn >> 8) & 0x7;
gen_movl_T1_reg(s, rn);
+ crement = 0;
+ for (i = 0; i < 8; i++) {
+ if (insn & (1 << i)) crement += 4;
+ }
+ if(arm_feature(env, ARM_FEATURE_ABORT_BU) && (insn & (1 << rn)) == 0) {
+ /* base-updated abort model: update base register
+ before an abort can happen */
+ gen_op_addl_T1_im(crement);
+ gen_movl_reg_T1(s, rn);
+ gen_op_addl_T1_im(-crement);
+ }
gen_op_movl_T2_im(4);
for (i = 0; i < 8; i++) {
if (insn & (1 << i)) {
@@ -3403,8 +3437,8 @@
gen_op_addl_T1_T2();
}
}
- /* Base register writeback. */
- if ((insn & (1 << rn)) == 0)
+ /* Base register writeback, base-restored abort model */
+ if (!arm_feature(env, ARM_FEATURE_ABORT_BU) && (insn & (1 << rn)) == 0)
gen_movl_reg_T1(s, rn);
break;
@@ -3442,6 +3476,7 @@
/* unconditional branch */
if (insn & (1 << 11)) {
/* Second half of blx. */
+ if(!arm_feature(env, ARM_FEATURE_V5)) goto undef;
offset = ((insn & 0x7ff) << 1);
gen_movl_T0_reg(s, 14);
gen_op_movl_T1_im(offset);
@@ -3571,7 +3606,7 @@
}
if (env->thumb)
- disas_thumb_insn(dc);
+ disas_thumb_insn(env, dc);
else
disas_arm_insn(env, dc);
next prev parent reply other threads:[~2007-07-03 14:45 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-02 13:27 [Qemu-devel] [PATCH] ARM7TDMI emulation Ulrich Hecht
2007-07-02 13:40 ` Paul Brook
2007-07-02 16:14 ` Ulrich Hecht
2007-07-03 14:45 ` Ulrich Hecht [this message]
2009-06-15 19:11 ` Filip Navara
2009-06-16 17:25 ` Paul Brook
2009-06-16 19:02 ` Jamie Lokier
2009-06-16 19:05 ` Paul Brook
2009-06-16 20:49 ` Filip Navara
2009-06-16 21:47 ` Filip Navara
2009-06-17 9:55 ` Filip Navara
2009-06-17 10:24 ` Filip Navara
-- strict thread matches above, loose matches on Subject: below --
2009-07-15 12:08 Filip Navara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200707031645.51832.uli@suse.de \
--to=uli@suse.de \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).