From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1EoN2b-0003fg-1O for qemu-devel@nongnu.org; Mon, 19 Dec 2005 10:35:09 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1EoN17-0002qc-Np for qemu-devel@nongnu.org; Mon, 19 Dec 2005 10:33:38 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1EoN0M-0002V3-21 for qemu-devel@nongnu.org; Mon, 19 Dec 2005 10:32:51 -0500 Received: from [80.91.229.2] (helo=ciao.gmane.org) by monty-python.gnu.org with esmtp (TLS-1.0:RSA_AES_128_CBC_SHA:16) (Exim 4.34) id 1EoN3J-0002tp-Ga for qemu-devel@nongnu.org; Mon, 19 Dec 2005 10:35:54 -0500 Received: from list by ciao.gmane.org with local (Exim 4.43) id 1EoMvz-0003A4-Kr for qemu-devel@nongnu.org; Mon, 19 Dec 2005 16:28:19 +0100 Received: from a84-231-2-208.elisa-laajakaista.fi ([84.231.2.208]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 19 Dec 2005 16:28:19 +0100 Received: from ananaza by a84-231-2-208.elisa-laajakaista.fi with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 19 Dec 2005 16:28:19 +0100 From: Antti P Miettinen Date: Mon, 19 Dec 2005 17:24:48 +0200 Message-ID: References: <200512150000.07159.paul@codesourcery.com> <200512181651.02705.paul@codesourcery.com> <20051218172558.GA446@nevyn.them.org> <20051218.104216.28085930.imp@bsdimp.com> <20051218175430.GA1580@nevyn.them.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: news Subject: [Qemu-devel] Re: ARM page crossing inside insn? (Re: ARM ethernet fixes) Reply-To: ananaza@iki.fi, qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Antti P Miettinen writes: > but anyway - how would the ldm register update be made atomic? Or > should the restart be able to continue in the middle? How are the > atomicity issues handled in qemu? I wonder how the ARM implementations handle it.. The below is a quick test how the atomicity could be achieved with shadow registers. Is this a feasible approach? The diff is not a proper/complete patch - I just wanted to see whether it makes a different. It does - the firefox compile proceeds.. Hmm.. do people prefer inline diffs or attachments? Index: target-arm/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-arm/cpu.h,v retrieving revision 1.13 diff -u -r1.13 cpu.h --- target-arm/cpu.h 26 Nov 2005 10:46:39 -0000 1.13 +++ target-arm/cpu.h 19 Dec 2005 15:17:14 -0000 @@ -46,6 +46,8 @@ typedef struct CPUARMState { /* Regs for current mode. */ uint32_t regs[16]; + /* Shadow regs for atomic update. */ + uint32_t newregs[16]; /* Frequently accessed CPSR bits are stored separately for efficiently. This contains all the other bits. Use cpsr_{read,write} to accless the whole CPSR. */ Index: target-arm/op.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/op.c,v retrieving revision 1.17 diff -u -r1.17 op.c --- target-arm/op.c 26 Nov 2005 10:46:39 -0000 1.17 +++ target-arm/op.c 19 Dec 2005 15:17:14 -0000 @@ -1175,3 +1175,20 @@ } FORCE_RET(); } + +void OPPROTO op_commit_newregs(void) +{ + int regs = PARAM1; + int i; + //cpu_lock(); + for (i = 0; i < 15; ++i) { + if (regs & (1 << i)) + env->regs[i] = env->newregs[i]; + } + //cpu_unlock(); +} + +void OPPROTO op_movl_T0_newpc(void) +{ + T0 = env->newregs[15]; +} Index: target-arm/op_template.h =================================================================== RCS file: /sources/qemu/qemu/target-arm/op_template.h,v retrieving revision 1.2 diff -u -r1.2 op_template.h --- target-arm/op_template.h 31 Jan 2005 20:43:28 -0000 1.2 +++ target-arm/op_template.h 19 Dec 2005 15:17:14 -0000 @@ -48,6 +48,21 @@ SET_REG (T1); } +/* For storing to shadow regs to make ldm register update atomic */ +#define regs newregs + +void OPPROTO glue(glue(op_movl_, glue(new_, REGNAME)), _T0)(void) +{ + SET_REG (T0); +} + +void OPPROTO glue(glue(op_movl_, glue(new_, REGNAME)), _T1)(void) +{ + SET_REG (T1); +} + +#undef regs + #undef REG #undef REGNAME #undef SET_REG Index: target-arm/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/translate.c,v retrieving revision 1.35 diff -u -r1.35 translate.c --- target-arm/translate.c 18 Dec 2005 16:55:25 -0000 1.35 +++ target-arm/translate.c 19 Dec 2005 15:17:15 -0000 @@ -267,6 +267,45 @@ }, }; +static GenOpFunc *gen_op_movl_newreg_TN[2][16] = { + { + gen_op_movl_new_r0_T0, + gen_op_movl_new_r1_T0, + gen_op_movl_new_r2_T0, + gen_op_movl_new_r3_T0, + gen_op_movl_new_r4_T0, + gen_op_movl_new_r5_T0, + gen_op_movl_new_r6_T0, + gen_op_movl_new_r7_T0, + gen_op_movl_new_r8_T0, + gen_op_movl_new_r9_T0, + gen_op_movl_new_r10_T0, + gen_op_movl_new_r11_T0, + gen_op_movl_new_r12_T0, + gen_op_movl_new_r13_T0, + gen_op_movl_new_r14_T0, + gen_op_movl_new_r15_T0, + }, + { + gen_op_movl_new_r0_T1, + gen_op_movl_new_r1_T1, + gen_op_movl_new_r2_T1, + gen_op_movl_new_r3_T1, + gen_op_movl_new_r4_T1, + gen_op_movl_new_r5_T1, + gen_op_movl_new_r6_T1, + gen_op_movl_new_r7_T1, + gen_op_movl_new_r8_T1, + gen_op_movl_new_r9_T1, + gen_op_movl_new_r10_T1, + gen_op_movl_new_r11_T1, + gen_op_movl_new_r12_T1, + gen_op_movl_new_r13_T1, + gen_op_movl_new_r14_T1, + gen_op_movl_new_r15_T1, + }, +}; + static GenOpFunc1 *gen_op_movl_TN_im[3] = { gen_op_movl_T0_im, gen_op_movl_T1_im, @@ -341,6 +380,16 @@ gen_movl_reg_TN(s, reg, 0); } +static inline void gen_movl_newreg_T0(int reg) +{ + gen_op_movl_newreg_TN[0][reg](); +} + +static inline void gen_movl_newreg_T1(int reg) +{ + gen_op_movl_newreg_TN[1][reg](); +} + static inline void gen_movl_reg_T1(DisasContext *s, int reg) { gen_movl_reg_TN(s, reg, 1); @@ -1665,12 +1714,13 @@ if (insn & (1 << 20)) { /* load */ gen_ldst(ldl, s); - if (i == 15) { + if (0 && i == 15) { gen_bx(s); } else if (user) { gen_op_movl_user_T0(i); } else { - gen_movl_reg_T0(s, i); + gen_movl_newreg_T0(i); + //gen_movl_reg_T0(s, i); } } else { /* store */ @@ -1691,6 +1741,15 @@ gen_op_addl_T1_im(4); } } + if (/*0 &&*/ (insn & (1 << 20)) && !user) { + /* commit the loaded registers */ + gen_op_commit_newregs(insn & 0xffff); + if (insn & (1 << 15)) { + /* PC updated */ + gen_op_movl_T0_newpc(); + gen_bx(s); + } + } if (insn & (1 << 21)) { /* write back */ if (insn & (1 << 23)) { -- http://www.iki.fi/~ananaza/