From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36272) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YrnW3-0001fo-2Z for qemu-devel@nongnu.org; Mon, 11 May 2015 09:13:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YrnVy-0004a6-2n for qemu-devel@nongnu.org; Mon, 11 May 2015 09:13:02 -0400 Received: from cantor2.suse.de ([195.135.220.15]:47599 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YrnVx-0004ZB-QJ for qemu-devel@nongnu.org; Mon, 11 May 2015 09:12:58 -0400 Message-ID: <5550AAD8.2080601@suse.de> Date: Mon, 11 May 2015 15:12:56 +0200 From: =?ISO-8859-15?Q?Andreas_F=E4rber?= MIME-Version: 1.0 References: <1431343850-46198-1-git-send-email-yongbok.kim@imgtec.com> <1431343850-46198-3-git-send-email-yongbok.kim@imgtec.com> In-Reply-To: <1431343850-46198-3-git-send-email-yongbok.kim@imgtec.com> Content-Type: text/plain; charset=iso-8859-15 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v2 2/2] target-mips: Misaligned memory accesses for MSA List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Yongbok Kim , qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, leon.alrae@imgtec.com Am 11.05.2015 um 13:30 schrieb Yongbok Kim: > MIPS SIMD Architecture vector loads and stores require misalignment sup= port. > MSA Memory access should work as an atomic operation. Therefore, it has= to > check validity of all addresses for an access if it is spanning into tw= o pages. >=20 > Introduced misaligned flag to indicate MSA ld/st is ongoing, is used to= allow > misaligned accesses in the mips_cpu_do_unaligned_access() callback. > This is crucial to support MSA misaligned accesses in Release 5 cores. >=20 > Further clean up to use mmu_idx from cpu_mmu_index() instead of calcula= ting it > from hflag. >=20 > Signed-off-by: Yongbok Kim > --- > target-mips/cpu.h | 5 +++ > target-mips/helper.c | 33 ++++++++++++++++++++++ > target-mips/op_helper.c | 69 ++++++++++++++++++++++++++++++++++-----= ------- > target-mips/translate.c | 4 +++ > 4 files changed, 93 insertions(+), 18 deletions(-) >=20 > diff --git a/target-mips/cpu.h b/target-mips/cpu.h > index f9d2b4c..1bd1229 100644 > --- a/target-mips/cpu.h > +++ b/target-mips/cpu.h > @@ -211,6 +211,9 @@ struct TCState { > MSACSR_FS_MASK) > =20 > float_status msa_fp_status; > +#if !defined(CONFIG_USER_ONLY) > + bool misaligned; /* indicates misaligned access is allowed */ > +#endif > }; > =20 > typedef struct CPUMIPSState CPUMIPSState; > @@ -760,6 +763,8 @@ int mips_cpu_handle_mmu_fault(CPUState *cpu, vaddr = address, int rw, > void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra); > hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong add= ress, > int rw); > +bool cpu_mips_validate_msa_block_access(CPUMIPSState *env, target_ulon= g addr, > + int rw, int mmu_idx); Can you please adopt the new style of using mips_cpu_... prefix and MIPSCPU *cpu argument? You're dealing with conversions both in the call site and inside the implementation anyway. > #endif > target_ulong exception_resume_pc (CPUMIPSState *env); > =20 > diff --git a/target-mips/helper.c b/target-mips/helper.c > index 8e3204a..951aea8 100644 > --- a/target-mips/helper.c > +++ b/target-mips/helper.c > @@ -391,6 +391,37 @@ hwaddr cpu_mips_translate_address(CPUMIPSState *en= v, target_ulong address, int r > } > } > =20 > +bool cpu_mips_validate_msa_block_access(CPUMIPSState *env, target_ulon= g addr, > + int rw, int mmu_idx) > +{ > + target_ulong vaddr =3D addr & TARGET_PAGE_MASK; > + target_ulong badvaddr =3D addr; > + > + CPUState *cs =3D CPU(mips_env_get_cpu(env)); This becomes CPU(cpu) then. CPUMIPSState *env =3D &cpu->env; > + int ret; > + > + ret =3D mips_cpu_handle_mmu_fault(cs, vaddr, rw, mmu_idx); > + if (ret !=3D TLBRET_MATCH) { > + /* calling raise_mmu_exeception again to correct badvaddr */ > + raise_mmu_exception(env, badvaddr, rw, ret); > + return false; > + } > + if (unlikely(((addr & ~TARGET_PAGE_MASK) + MSA_WRLEN - 1) > + >=3D TARGET_PAGE_SIZE)) { > + vaddr +=3D TARGET_PAGE_SIZE; > + ret =3D mips_cpu_handle_mmu_fault(cs, vaddr, rw, mmu_idx); > + if (ret !=3D TLBRET_MATCH) { > + if (ret !=3D TLBRET_BADADDR) { > + badvaddr =3D vaddr; > + } > + /* calling raise_mmu_exeception again to correct badvaddr = */ > + raise_mmu_exception(env, badvaddr, rw, ret); > + return false; > + } > + } > + return true; > +} > + > static const char * const excp_names[EXCP_LAST + 1] =3D { > [EXCP_RESET] =3D "reset", > [EXCP_SRESET] =3D "soft reset", > @@ -497,6 +528,8 @@ void mips_cpu_do_interrupt(CPUState *cs) > qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx "= %s exception\n", > __func__, env->active_tc.PC, env->CP0_EPC, name); > } > + > + env->active_tc.misaligned =3D false; > if (cs->exception_index =3D=3D EXCP_EXT_INTERRUPT && > (env->hflags & MIPS_HFLAG_DM)) { > cs->exception_index =3D EXCP_DINT; > diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c > index 58f02cf..b3b8d52 100644 > --- a/target-mips/op_helper.c > +++ b/target-mips/op_helper.c > @@ -47,7 +47,9 @@ static inline void QEMU_NORETURN do_raise_exception_e= rr(CPUMIPSState *env, > /* now we have a real cpu fault */ > cpu_restore_state(cs, pc); > } > - > +#if !defined(CONFIG_USER_ONLY) > + env->active_tc.misaligned =3D false; > +#endif > cpu_loop_exit(cs); > } > =20 > @@ -2215,9 +2217,12 @@ void mips_cpu_do_unaligned_access(CPUState *cs, = vaddr addr, > int error_code =3D 0; > int excp; > =20 > - if (env->insn_flags & ISA_MIPS32R6) { > + if ((env->insn_flags & ISA_MIPS32R6) || (env->active_tc.misaligned= )) { > /* Release 6 provides support for misaligned memory access for > * all ordinary memory reference instructions > + * > + * MIPS SIMD Architecture vector loads and stores support misa= lignment > + * memory access > * */ > return; > } > @@ -3571,33 +3576,47 @@ void helper_msa_ld_df(CPUMIPSState *env, uint32= _t df, uint32_t wd, uint32_t rs, > wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); > target_ulong addr =3D env->active_tc.gpr[rs] + (s10 << df); > int i; > + int mmu_idx =3D cpu_mmu_index(env); > + > +#if !defined(CONFIG_USER_ONLY) > + if (unlikely(((addr & ~TARGET_PAGE_MASK) + MSA_WRLEN - 1) > + >=3D TARGET_PAGE_SIZE)) { > + if (!cpu_mips_validate_msa_block_access(env, addr, MMU_DATA_LO= AD, > + mmu_idx)) { > + CPUState *cs =3D CPU(mips_env_get_cpu(env)); MIPSCPU *cpu =3D mips_env_get_cpu(env); CPUState *cs =3D CPU(cpu); Regards, Andreas > + helper_raise_exception_err(env, cs->exception_index, > + env->error_code); > + return; > + } > + } > + env->active_tc.misaligned =3D true; > +#endif > =20 > switch (df) { > case DF_BYTE: > for (i =3D 0; i < DF_ELEMENTS(DF_BYTE); i++) { > - pwd->b[i] =3D do_lbu(env, addr + (i << DF_BYTE), > - env->hflags & MIPS_HFLAG_KSU); > + pwd->b[i] =3D do_lbu(env, addr + (i << DF_BYTE), mmu_idx); > } > break; > case DF_HALF: > for (i =3D 0; i < DF_ELEMENTS(DF_HALF); i++) { > - pwd->h[i] =3D do_lhu(env, addr + (i << DF_HALF), > - env->hflags & MIPS_HFLAG_KSU); > + pwd->h[i] =3D do_lhu(env, addr + (i << DF_HALF), mmu_idx); > } > break; > case DF_WORD: > for (i =3D 0; i < DF_ELEMENTS(DF_WORD); i++) { > - pwd->w[i] =3D do_lw(env, addr + (i << DF_WORD), > - env->hflags & MIPS_HFLAG_KSU); > + pwd->w[i] =3D do_lw(env, addr + (i << DF_WORD), mmu_idx); > } > break; > case DF_DOUBLE: > for (i =3D 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { > - pwd->d[i] =3D do_ld(env, addr + (i << DF_DOUBLE), > - env->hflags & MIPS_HFLAG_KSU); > + pwd->d[i] =3D do_ld(env, addr + (i << DF_DOUBLE), mmu_idx)= ; > } > break; > } > +#if !defined(CONFIG_USER_ONLY) > + env->active_tc.misaligned =3D false; > +#endif > } > =20 > void helper_msa_st_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uin= t32_t rs, > @@ -3606,31 +3625,45 @@ void helper_msa_st_df(CPUMIPSState *env, uint32= _t df, uint32_t wd, uint32_t rs, > wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); > target_ulong addr =3D env->active_tc.gpr[rs] + (s10 << df); > int i; > + int mmu_idx =3D cpu_mmu_index(env); > + > +#if !defined(CONFIG_USER_ONLY) > + if (unlikely(((addr & ~TARGET_PAGE_MASK) + MSA_WRLEN - 1) > + >=3D TARGET_PAGE_SIZE)) { > + if (!cpu_mips_validate_msa_block_access(env, addr, MMU_DATA_ST= ORE, > + mmu_idx)) { > + CPUState *cs =3D CPU(mips_env_get_cpu(env)); > + helper_raise_exception_err(env, cs->exception_index, > + env->error_code); > + return; > + } > + } > + env->active_tc.misaligned =3D true; > +#endif > =20 > switch (df) { > case DF_BYTE: > for (i =3D 0; i < DF_ELEMENTS(DF_BYTE); i++) { > - do_sb(env, addr + (i << DF_BYTE), pwd->b[i], > - env->hflags & MIPS_HFLAG_KSU); > + do_sb(env, addr + (i << DF_BYTE), pwd->b[i], mmu_idx); > } > break; > case DF_HALF: > for (i =3D 0; i < DF_ELEMENTS(DF_HALF); i++) { > - do_sh(env, addr + (i << DF_HALF), pwd->h[i], > - env->hflags & MIPS_HFLAG_KSU); > + do_sh(env, addr + (i << DF_HALF), pwd->h[i], mmu_idx); > } > break; > case DF_WORD: > for (i =3D 0; i < DF_ELEMENTS(DF_WORD); i++) { > - do_sw(env, addr + (i << DF_WORD), pwd->w[i], > - env->hflags & MIPS_HFLAG_KSU); > + do_sw(env, addr + (i << DF_WORD), pwd->w[i], mmu_idx); > } > break; > case DF_DOUBLE: > for (i =3D 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { > - do_sd(env, addr + (i << DF_DOUBLE), pwd->d[i], > - env->hflags & MIPS_HFLAG_KSU); > + do_sd(env, addr + (i << DF_DOUBLE), pwd->d[i], mmu_idx); > } > break; > } > +#if !defined(CONFIG_USER_ONLY) > + env->active_tc.misaligned =3D false; > +#endif > } > diff --git a/target-mips/translate.c b/target-mips/translate.c > index fd063a2..674b1cb 100644 > --- a/target-mips/translate.c > +++ b/target-mips/translate.c > @@ -19641,6 +19641,10 @@ void cpu_state_reset(CPUMIPSState *env) > restore_rounding_mode(env); > restore_flush_mode(env); > cs->exception_index =3D EXCP_NONE; > + > +#ifndef CONFIG_USER_ONLY > + env->active_tc.misaligned =3D false; > +#endif > } > =20 > void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int= pc_pos) >=20 --=20 SUSE Linux GmbH, Maxfeldstr. 5, 90409 N=FCrnberg, Germany GF: Felix Imend=F6rffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB 21284 (AG N=FCrnberg)