qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] MIPS/user: Fix reset CPU state initialization


From: Meador Inge
Subject: Re: [Qemu-devel] [PATCH] MIPS/user: Fix reset CPU state initialization
Date: Fri, 8 Jun 2012 08:37:16 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120424 Thunderbird/12.0

On 06/07/2012 08:04 PM, Maciej W. Rozycki wrote:

>  This change updates the CPU reset sequence to use a common piece of code 
> that figures out CPU state flags, fixing the problem with MIPS_HFLAG_COP1X 
> not being set where applicable that causes floating-point MADD family 
> instructions (and other instructions from the MIPS IV FP subset) to trap.
> 
>  As compute_hflags is now shared between op_helper.c and translate.c, the 
> function is now moved to a common header.  There are no changes to this 
> function.
> 
>  The problem was seen with the 24Kf MIPS32r2 processor in user emulation.  
> The new approach prevents system and user emulation from diverging -- all 
> the hflags state is initialized in one place now.

I submitted a patch to fix this issue and the FCR0 issue a few months back [1].
Andreas reviewed it, but the patch never got committed.

[1] http://patchwork.ozlabs.org/patch/144353/

> Signed-off-by: Maciej W. Rozycki <address@hidden>
> ---
> 
>  This is effectively a follow-up to Nathan's FCR0 fix -- please apply.
> 
>   Maciej
> 
> qemu-mips-hflags.patch
> Index: qemu-git-trunk/target-mips/cpu.h
> ===================================================================
> --- qemu-git-trunk.orig/target-mips/cpu.h     2012-06-07 03:15:53.645461055 
> +0100
> +++ qemu-git-trunk/target-mips/cpu.h  2012-06-07 03:18:48.345427587 +0100
> @@ -753,4 +753,53 @@ static inline void cpu_pc_from_tb(CPUMIP
>      env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
>  }
>  
> +static inline void compute_hflags(CPUMIPSState *env)
> +{
> +    env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
> +                     MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
> +                     MIPS_HFLAG_UX);
> +    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
> +        !(env->CP0_Status & (1 << CP0St_ERL)) &&
> +        !(env->hflags & MIPS_HFLAG_DM)) {
> +        env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
> +    }
> +#if defined(TARGET_MIPS64)
> +    if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
> +        (env->CP0_Status & (1 << CP0St_PX)) ||
> +        (env->CP0_Status & (1 << CP0St_UX))) {
> +        env->hflags |= MIPS_HFLAG_64;
> +    }
> +    if (env->CP0_Status & (1 << CP0St_UX)) {
> +        env->hflags |= MIPS_HFLAG_UX;
> +    }
> +#endif
> +    if ((env->CP0_Status & (1 << CP0St_CU0)) ||
> +        !(env->hflags & MIPS_HFLAG_KSU)) {
> +        env->hflags |= MIPS_HFLAG_CP0;
> +    }
> +    if (env->CP0_Status & (1 << CP0St_CU1)) {
> +        env->hflags |= MIPS_HFLAG_FPU;
> +    }
> +    if (env->CP0_Status & (1 << CP0St_FR)) {
> +        env->hflags |= MIPS_HFLAG_F64;
> +    }
> +    if (env->insn_flags & ISA_MIPS32R2) {
> +        if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
> +            env->hflags |= MIPS_HFLAG_COP1X;
> +        }
> +    } else if (env->insn_flags & ISA_MIPS32) {
> +        if (env->hflags & MIPS_HFLAG_64) {
> +            env->hflags |= MIPS_HFLAG_COP1X;
> +        }
> +    } else if (env->insn_flags & ISA_MIPS4) {
> +        /* All supported MIPS IV CPUs use the XX (CU3) to enable
> +           and disable the MIPS IV extensions to the MIPS III ISA.
> +           Some other MIPS IV CPUs ignore the bit, so the check here
> +           would be too restrictive for them.  */
> +        if (env->CP0_Status & (1 << CP0St_CU3)) {
> +            env->hflags |= MIPS_HFLAG_COP1X;
> +        }
> +    }
> +}
> +
>  #endif /* !defined (__MIPS_CPU_H__) */
> Index: qemu-git-trunk/target-mips/op_helper.c
> ===================================================================
> --- qemu-git-trunk.orig/target-mips/op_helper.c       2012-06-07 
> 03:15:53.645461055 +0100
> +++ qemu-git-trunk/target-mips/op_helper.c    2012-06-07 03:18:48.345427587 
> +0100
> @@ -32,55 +32,6 @@
>  static inline void cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global);
>  #endif
>  
> -static inline void compute_hflags(CPUMIPSState *env)
> -{
> -    env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
> -                     MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
> -                     MIPS_HFLAG_UX);
> -    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
> -        !(env->CP0_Status & (1 << CP0St_ERL)) &&
> -        !(env->hflags & MIPS_HFLAG_DM)) {
> -        env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
> -    }
> -#if defined(TARGET_MIPS64)
> -    if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
> -        (env->CP0_Status & (1 << CP0St_PX)) ||
> -        (env->CP0_Status & (1 << CP0St_UX))) {
> -        env->hflags |= MIPS_HFLAG_64;
> -    }
> -    if (env->CP0_Status & (1 << CP0St_UX)) {
> -        env->hflags |= MIPS_HFLAG_UX;
> -    }
> -#endif
> -    if ((env->CP0_Status & (1 << CP0St_CU0)) ||
> -        !(env->hflags & MIPS_HFLAG_KSU)) {
> -        env->hflags |= MIPS_HFLAG_CP0;
> -    }
> -    if (env->CP0_Status & (1 << CP0St_CU1)) {
> -        env->hflags |= MIPS_HFLAG_FPU;
> -    }
> -    if (env->CP0_Status & (1 << CP0St_FR)) {
> -        env->hflags |= MIPS_HFLAG_F64;
> -    }
> -    if (env->insn_flags & ISA_MIPS32R2) {
> -        if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
> -            env->hflags |= MIPS_HFLAG_COP1X;
> -        }
> -    } else if (env->insn_flags & ISA_MIPS32) {
> -        if (env->hflags & MIPS_HFLAG_64) {
> -            env->hflags |= MIPS_HFLAG_COP1X;
> -        }
> -    } else if (env->insn_flags & ISA_MIPS4) {
> -        /* All supported MIPS IV CPUs use the XX (CU3) to enable
> -           and disable the MIPS IV extensions to the MIPS III ISA.
> -           Some other MIPS IV CPUs ignore the bit, so the check here
> -           would be too restrictive for them.  */
> -        if (env->CP0_Status & (1 << CP0St_CU3)) {
> -            env->hflags |= MIPS_HFLAG_COP1X;
> -        }
> -    }
> -}
> -
>  
> /*****************************************************************************/
>  /* Exceptions processing helpers */
>  
> Index: qemu-git-trunk/target-mips/translate.c
> ===================================================================
> --- qemu-git-trunk.orig/target-mips/translate.c       2012-06-07 
> 03:18:46.275645763 +0100
> +++ qemu-git-trunk/target-mips/translate.c    2012-06-07 03:18:48.345427587 
> +0100
> @@ -12780,17 +12780,12 @@ void cpu_state_reset(CPUMIPSState *env)
>      env->insn_flags = env->cpu_model->insn_flags;
>  
>  #if defined(CONFIG_USER_ONLY)
> -    env->hflags = MIPS_HFLAG_UM;
> +    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
>      /* Enable access to the SYNCI_Step register.  */
>      env->CP0_HWREna |= (1 << 1);
>      if (env->CP0_Config1 & (1 << CP0C1_FP)) {
> -        env->hflags |= MIPS_HFLAG_FPU;
> -    }
> -#ifdef TARGET_MIPS64
> -    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
> -        env->hflags |= MIPS_HFLAG_F64;
> +        env->CP0_Status |= (1 << CP0St_CU1);
>      }
> -#endif
>  #else
>      if (env->hflags & MIPS_HFLAG_BMASK) {
>          /* If the exception was raised from a delay slot,
> @@ -12820,7 +12815,6 @@ void cpu_state_reset(CPUMIPSState *env)
>      }
>      /* Count register increments in debug mode, EJTAG version 1 */
>      env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
> -    env->hflags = MIPS_HFLAG_CP0;
>  
>      if (env->CP0_Config3 & (1 << CP0C3_MT)) {
>          int i;
> @@ -12848,11 +12842,7 @@ void cpu_state_reset(CPUMIPSState *env)
>          }
>      }
>  #endif
> -#if defined(TARGET_MIPS64)
> -    if (env->cpu_model->insn_flags & ISA_MIPS3) {
> -        env->hflags |= MIPS_HFLAG_64;
> -    }
> -#endif
> +    compute_hflags(env);
>      env->exception_index = EXCP_NONE;
>  }
>  
> 


-- 
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software



reply via email to

[Prev in Thread] Current Thread [Next in Thread]