All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nathan Froyd <froydnj@codesourcery.com>
To: Khansa Butt <khansa@kics.edu.pk>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] MIPS64 user mode emulation Patch
Date: Wed, 30 Mar 2011 09:38:51 -0700	[thread overview]
Message-ID: <20110330163850.GA23480@codesourcery.com> (raw)
In-Reply-To: <BANLkTinXJEsQ2+xGr5+sO4uv2L4qXxp-cQ@mail.gmail.com>

On Sat, Mar 26, 2011 at 11:58:37AM +0500, Khansa Butt wrote:
> Subject: [PATCH] MIPS64 user mode emulation in QEMU
>  This patch adds support for Cavium Network's
>  Octeon 57XX user mode instructions.  Octeon
>  57xx is based on MIPS64.  So this patch is
>  the first MIPS64 User Mode Emulation in QEMU
>  This is the team(Khansa Butt, Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed)
>  work of HPCNL Lab at KICS-UET Lahore.

Thanks for doing this.  As already noted, this patch should be split
into at least two patches: one to add Octeon-specific instructions in
target-mips/ and one adding the necessary linux-user bits.

> +extern int TARGET_OCTEON;

I don't think a global like this is the right way to go.  Perhaps the
elfload.c code should set a flag in image_info , which can then be used
to set a flag in CPUMIPSState later on.

If we must use a global variable, it should be declared in
target-mips/cpu.h.

> @@ -2013,7 +2024,8 @@ void cpu_loop(CPUMIPSState *env)
>                                   env->active_tc.gpr[5],
>                                   env->active_tc.gpr[6],
>                                   env->active_tc.gpr[7],
> -                                 arg5, arg6/*, arg7, arg8*/);
> +                                 env->active_tc.gpr[8],
> +                                 env->active_tc.gpr[9]/*, arg7, arg8*/);
>              }
>              if (ret == -TARGET_QEMU_ESIGRETURN) {
>                  /* Returning from a successful sigreturn syscall.

This change breaks O32 binaries; it needs to be done in a different way.

> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 499c4d7..47fef05 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -7195,6 +7195,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long
> arg1,
>      case TARGET_NR_set_thread_area:
>  #if defined(TARGET_MIPS)
>        ((CPUMIPSState *) cpu_env)->tls_value = arg1;
> +       /*tls entry is moved to k0 so that this can be used later*/
> +      ((CPUMIPSState *) cpu_env)->active_tc.gpr[26] = arg1;
>        ret = 0;
>        break;
>  #elif defined(TARGET_CRIS)

I believe this is only correct for Octeon binaries; it's not how the
rest of the MIPS world works.  It therefore needs to be conditional on
Octeon-ness.

> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -140,6 +140,20 @@ typedef struct mips_def_t mips_def_t;
>  #define MIPS_FPU_MAX 1
>  #define MIPS_DSP_ACC 4
> 
> +typedef struct cavium_mul cavium_mul;
> +struct cavium_mul {
> + target_ulong MPL0;
> + target_ulong MPL1;
> + target_ulong MPL2;
> + target_ulong P0;
> + target_ulong P1;
> + target_ulong P2;
> +};
> +typedef struct cvmctl_register cvmctl_register;
> +struct cvmctl_register {
> + target_ulong cvmctl;
> +};

The indentation here needs to be fixed.  I don't think there's any
reason why these need to be defined outside TCState, either.

> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index cce77be..9c3d772 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -36,6 +36,15 @@
>  #define GEN_HELPER 1
>  #include "helper.h"
> 
> +int TARGET_OCTEON;
> +#if defined(TARGET_MIPS64)
> +/*Macros for setting values of cvmctl registers*/
> +#define FUSE_START_BIT(cvmctl)(cvmctl | 0x80000000)
> +#define KASUMI(cvmctl)(cvmctl | 0x20000000)
> +#define IPPCI(cvmctl)(cvmctl | 0x380)
> +#define IPTI(cvmctl)(cvmctl | 0x70)
> +#endif

Please follow existing style; spaces between the comment and comment
markers (many examples in translate.c, not just here) and spaces between
the macro argument list and definition.

> @@ -779,7 +818,9 @@ static inline void gen_op_addr_add (DisasContext *ctx,
> TCGv ret, TCGv arg0, TCGv
>         See the MIPS64 PRA manual, section 4.10. */
>      if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
>          !(ctx->hflags & MIPS_HFLAG_UX)) {
> -        tcg_gen_ext32s_i64(ret, ret);
> +        /*This function sign extend 32 bit value to 64 bit, was causing
> error
> +          when ld instruction came.Thats why it is commmented out*/
> +       /* tcg_gen_ext32s_i64(ret, ret);*/
>      }
>  #endif
>  }

Um, no.  If you needed to comment this out, you have a bug someplace
else.  Don't paper over the bug here.

> +        case OPC_VMULU:
> +        case OPC_V3MULU:

These two are large enough that they should be done as out-of-line
helpers.

Also, since all these new instructions are Octeon-specific, there should
be checks emitted to ensure that they produce appropriate errors when
non-Octeon hardware is being simulated, similar in style to
check_mips_64.

>  /* Arithmetic */
>  static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
>                         int rd, int rs, int rt)
>  {
>      const char *opn = "arith";
> 
> +    target_ulong mask = 0xFF;

I don't think it's really necessary to have this, but if you feel it's
necessary, please move the declaration closer to the point of use.

> +#if defined(TARGET_MIPS64)
> +static void gen_seqsne (DisasContext *ctx, uint32_t opc,
> +                        int rd, int rs, int rt)
> +{
> +    const char *opn = "seq/sne";
> +    TCGv t0, t1;
> +    t0 = tcg_temp_new();
> +    t1 = tcg_temp_new();
> +    switch (opc) {
> +    case OPC_SEQ:
> +        {
> +            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> +            gen_load_gpr(t0, rd);
> +            tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rd], t0, 1);
> +        }
> +        opn = "seq";
> +        break;

This looks like you are comparing rd with itself?

> +    case OPC_SNE:
> +        {
> +            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
> +            gen_load_gpr(t0, rd);
> +            gen_load_gpr(t1, 0);
> +            tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t1, t0);

You could use setcondi here by reversing the condition.

> +#if defined(TARGET_MIPS64)
> +static void insn_opc_pop (DisasContext *ctx, CPUState *env, uint32_t opc,
> +                          int rd, int rs, int rt)
> +static void insn_opc_dpop (DisasContext *ctx, CPUState *env, uint32_t opc,
> +                           int rd, int rs, int rt)

These should also be done as out-of-line helpers.

> @@ -2983,7 +3408,44 @@ static void gen_compute_branch (DisasContext *ctx,
> uint32_t opc,
>      tcg_temp_free(t0);
>      tcg_temp_free(t1);
>  }
> +/*For cavium specific extract instructions*/
> +#if defined(TARGET_MIPS64)
> +static void gen_exts (CPUState *env,DisasContext *ctx, uint32_t opc, int
> rt,
> +                      int rs, int lsb, int msb)
> +{
> +    TCGv t0 = tcg_temp_new();
> +    TCGv t1 = tcg_temp_new();
> +    target_ulong mask;
> +    gen_load_gpr(t1, rs);
> +    switch (opc) {
> +    case OPC_EXTS:
> +        tcg_gen_shri_tl(t0, t1, lsb);
> +        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
> +        /* To sign extened the remaining bits according to
> +           the msb of the bit field */
> +        mask = 1ULL << msb;
> +        tcg_gen_andi_tl(t1, t0, mask);
> +        tcg_gen_addi_tl(t1, t1, -1);
> +        tcg_gen_not_i64(t1, t1);
> +        tcg_gen_or_tl(t0, t0, t1);

You can use tcg_gen_orc_tl here and elsewhere.

-Nathan

  parent reply	other threads:[~2011-03-30 16:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-26  6:58 [Qemu-devel] MIPS64 user mode emulation Patch Khansa Butt
2011-03-29  8:55 ` Riku Voipio
2011-03-29 10:49   ` maheen butt
2011-04-09  8:36   ` Khansa Butt
2011-03-30 16:38 ` Nathan Froyd [this message]
2011-04-09  9:57   ` Khansa Butt
2011-04-03 22:03 ` Aurelien Jarno

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=20110330163850.GA23480@codesourcery.com \
    --to=froydnj@codesourcery.com \
    --cc=khansa@kics.edu.pk \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.