diff mbox

[v8,02/14] target-mips-ase-dsp: Add internal dsp resources access check

Message ID 1347415315-2180-3-git-send-email-proljc@gmail.com
State New
Headers show

Commit Message

Jia Liu Sept. 12, 2012, 2:01 a.m. UTC
Add MIPS ASE DSP resources access check.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 linux-user/main.c       |    6 ++++++
 target-mips/cpu.h       |   27 +++++++++++++++++++++++++--
 target-mips/helper.c    |    3 +++
 target-mips/translate.c |   23 +++++++++++++++++++++++
 4 files changed, 57 insertions(+), 2 deletions(-)

Comments

Aurelien Jarno Sept. 18, 2012, 4:36 p.m. UTC | #1
Looks fine to me.

Acked-by: Aurelien Jarno <aurelien@aurel32.net>

On Wed, Sep 12, 2012 at 10:01:43AM +0800, Jia Liu wrote:
> Add MIPS ASE DSP resources access check.
> 
> Signed-off-by: Jia Liu <proljc@gmail.com>
> ---
>  linux-user/main.c       |    6 ++++++
>  target-mips/cpu.h       |   27 +++++++++++++++++++++++++--
>  target-mips/helper.c    |    3 +++
>  target-mips/translate.c |   23 +++++++++++++++++++++++
>  4 files changed, 57 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 1a1c661..5925a49 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -2294,6 +2294,12 @@ done_syscall:
>                  queue_signal(env, info.si_signo, &info);
>              }
>              break;
> +        case EXCP_DSPDIS:
> +            info.si_signo = TARGET_SIGILL;
> +            info.si_errno = 0;
> +            info.si_code = TARGET_ILL_ILLOPC;
> +            queue_signal(env, info.si_signo, &info);
> +            break;
>          default:
>              //        error:
>              fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index 88d92f1..7761a46 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -415,7 +415,7 @@ struct CPUMIPSState {
>      int error_code;
>      uint32_t hflags;    /* CPU State */
>      /* TMASK defines different execution modes */
> -#define MIPS_HFLAG_TMASK  0x007FF
> +#define MIPS_HFLAG_TMASK  0xC07FF
>  #define MIPS_HFLAG_MODE   0x00007 /* execution modes                    */
>      /* The KSU flags must be the lowest bits in hflags. The flag order
>         must be the same as defined for CP0 Status. This allows to use
> @@ -453,6 +453,9 @@ struct CPUMIPSState {
>  #define MIPS_HFLAG_BDS32  0x10000 /* branch requires 32-bit delay slot  */
>  #define MIPS_HFLAG_BX     0x20000 /* branch exchanges execution mode    */
>  #define MIPS_HFLAG_BMASK  (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT)
> +    /* MIPS DSP resources access. */
> +#define MIPS_HFLAG_DSP   0x40000  /* Enable access to MIPS DSP resources. */
> +#define MIPS_HFLAG_DSPR2 0x80000  /* Enable access to MIPS DSPR2 resources. */
>      target_ulong btarget;        /* Jump / branch target               */
>      target_ulong bcond;          /* Branch condition (if needed)       */
>  
> @@ -610,8 +613,9 @@ enum {
>      EXCP_MDMX,
>      EXCP_C2E,
>      EXCP_CACHE, /* 32 */
> +    EXCP_DSPDIS,
>  
> -    EXCP_LAST = EXCP_CACHE,
> +    EXCP_LAST = EXCP_DSPDIS,
>  };
>  /* Dummy exception for conditional stores.  */
>  #define EXCP_SC 0x100
> @@ -772,6 +776,25 @@ static inline void compute_hflags(CPUMIPSState *env)
>      if (env->CP0_Status & (1 << CP0St_FR)) {
>          env->hflags |= MIPS_HFLAG_F64;
>      }
> +    if (env->insn_flags & ASE_DSPR2) {
> +        /* Enables access MIPS DSP resources
> +           on processors implementing one of these ASEs. If the MIPS DSP ASE is
> +           not implemented, this bit must be ignored on write and read as
> +           zero. */
> +        if (env->CP0_Status & (1 << CP0St_MX)) {
> +            env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
> +        }
> +
> +    } else if (env->insn_flags & ASE_DSP) {
> +        /* Enables access MIPS DSP resources
> +           on processors implementing one of these ASEs. If the MIPS DSP ASE is
> +           not implemented, this bit must be ignored on write and read as
> +           zero. */
> +        if (env->CP0_Status & (1 << CP0St_MX)) {
> +            env->hflags |= MIPS_HFLAG_DSP;
> +        }
> +
> +    }
>      if (env->insn_flags & ISA_MIPS32R2) {
>          if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
>              env->hflags |= MIPS_HFLAG_COP1X;
> diff --git a/target-mips/helper.c b/target-mips/helper.c
> index 4208bb2..edbe2b0 100644
> --- a/target-mips/helper.c
> +++ b/target-mips/helper.c
> @@ -592,6 +592,9 @@ void do_interrupt (CPUMIPSState *env)
>      case EXCP_THREAD:
>          cause = 25;
>          goto set_EPC;
> +    case EXCP_DSPDIS:
> +        cause = 26;
> +        goto set_EPC;
>      case EXCP_CACHE:
>          cause = 30;
>          if (env->CP0_Status & (1 << CP0St_BEV)) {
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index a884f75..25adf1d 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -824,6 +824,24 @@ static inline void check_cp1_registers(DisasContext *ctx, int regs)
>          generate_exception(ctx, EXCP_RI);
>  }
>  
> +/* Verify that the processor is running with DSP instructions enabled.
> +   This is enabled by CP0 Status register MX(24) bit.
> + */
> +
> +static inline void check_dsp(DisasContext *ctx)
> +{
> +    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
> +        generate_exception(ctx, EXCP_DSPDIS);
> +    }
> +}
> +
> +static inline void check_dspr2(DisasContext *ctx)
> +{
> +    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
> +        generate_exception(ctx, EXCP_DSPDIS);
> +    }
> +}
> +
>  /* This code generates a "reserved instruction" exception if the
>     CPU does not support the instruction set corresponding to flags. */
>  static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
> @@ -12794,6 +12812,11 @@ void cpu_state_reset(CPUMIPSState *env)
>      if (env->CP0_Config1 & (1 << CP0C1_FP)) {
>          env->CP0_Status |= (1 << CP0St_CU1);
>      }
> +    if (env->cpu_model->insn_flags & ASE_DSPR2) {
> +        env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
> +    } else if (env->cpu_model->insn_flags & ASE_DSP) {
> +        env->hflags |= MIPS_HFLAG_DSP;
> +    }
>  #else
>      if (env->hflags & MIPS_HFLAG_BMASK) {
>          /* If the exception was raised from a delay slot,
> -- 
> 1.7.9.5
> 
> 
>
diff mbox

Patch

diff --git a/linux-user/main.c b/linux-user/main.c
index 1a1c661..5925a49 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2294,6 +2294,12 @@  done_syscall:
                 queue_signal(env, info.si_signo, &info);
             }
             break;
+        case EXCP_DSPDIS:
+            info.si_signo = TARGET_SIGILL;
+            info.si_errno = 0;
+            info.si_code = TARGET_ILL_ILLOPC;
+            queue_signal(env, info.si_signo, &info);
+            break;
         default:
             //        error:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 88d92f1..7761a46 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -415,7 +415,7 @@  struct CPUMIPSState {
     int error_code;
     uint32_t hflags;    /* CPU State */
     /* TMASK defines different execution modes */
-#define MIPS_HFLAG_TMASK  0x007FF
+#define MIPS_HFLAG_TMASK  0xC07FF
 #define MIPS_HFLAG_MODE   0x00007 /* execution modes                    */
     /* The KSU flags must be the lowest bits in hflags. The flag order
        must be the same as defined for CP0 Status. This allows to use
@@ -453,6 +453,9 @@  struct CPUMIPSState {
 #define MIPS_HFLAG_BDS32  0x10000 /* branch requires 32-bit delay slot  */
 #define MIPS_HFLAG_BX     0x20000 /* branch exchanges execution mode    */
 #define MIPS_HFLAG_BMASK  (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT)
+    /* MIPS DSP resources access. */
+#define MIPS_HFLAG_DSP   0x40000  /* Enable access to MIPS DSP resources. */
+#define MIPS_HFLAG_DSPR2 0x80000  /* Enable access to MIPS DSPR2 resources. */
     target_ulong btarget;        /* Jump / branch target               */
     target_ulong bcond;          /* Branch condition (if needed)       */
 
@@ -610,8 +613,9 @@  enum {
     EXCP_MDMX,
     EXCP_C2E,
     EXCP_CACHE, /* 32 */
+    EXCP_DSPDIS,
 
-    EXCP_LAST = EXCP_CACHE,
+    EXCP_LAST = EXCP_DSPDIS,
 };
 /* Dummy exception for conditional stores.  */
 #define EXCP_SC 0x100
@@ -772,6 +776,25 @@  static inline void compute_hflags(CPUMIPSState *env)
     if (env->CP0_Status & (1 << CP0St_FR)) {
         env->hflags |= MIPS_HFLAG_F64;
     }
+    if (env->insn_flags & ASE_DSPR2) {
+        /* Enables access MIPS DSP resources
+           on processors implementing one of these ASEs. If the MIPS DSP ASE is
+           not implemented, this bit must be ignored on write and read as
+           zero. */
+        if (env->CP0_Status & (1 << CP0St_MX)) {
+            env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
+        }
+
+    } else if (env->insn_flags & ASE_DSP) {
+        /* Enables access MIPS DSP resources
+           on processors implementing one of these ASEs. If the MIPS DSP ASE is
+           not implemented, this bit must be ignored on write and read as
+           zero. */
+        if (env->CP0_Status & (1 << CP0St_MX)) {
+            env->hflags |= MIPS_HFLAG_DSP;
+        }
+
+    }
     if (env->insn_flags & ISA_MIPS32R2) {
         if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
             env->hflags |= MIPS_HFLAG_COP1X;
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 4208bb2..edbe2b0 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -592,6 +592,9 @@  void do_interrupt (CPUMIPSState *env)
     case EXCP_THREAD:
         cause = 25;
         goto set_EPC;
+    case EXCP_DSPDIS:
+        cause = 26;
+        goto set_EPC;
     case EXCP_CACHE:
         cause = 30;
         if (env->CP0_Status & (1 << CP0St_BEV)) {
diff --git a/target-mips/translate.c b/target-mips/translate.c
index a884f75..25adf1d 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -824,6 +824,24 @@  static inline void check_cp1_registers(DisasContext *ctx, int regs)
         generate_exception(ctx, EXCP_RI);
 }
 
+/* Verify that the processor is running with DSP instructions enabled.
+   This is enabled by CP0 Status register MX(24) bit.
+ */
+
+static inline void check_dsp(DisasContext *ctx)
+{
+    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
+        generate_exception(ctx, EXCP_DSPDIS);
+    }
+}
+
+static inline void check_dspr2(DisasContext *ctx)
+{
+    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
+        generate_exception(ctx, EXCP_DSPDIS);
+    }
+}
+
 /* This code generates a "reserved instruction" exception if the
    CPU does not support the instruction set corresponding to flags. */
 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
@@ -12794,6 +12812,11 @@  void cpu_state_reset(CPUMIPSState *env)
     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
         env->CP0_Status |= (1 << CP0St_CU1);
     }
+    if (env->cpu_model->insn_flags & ASE_DSPR2) {
+        env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
+    } else if (env->cpu_model->insn_flags & ASE_DSP) {
+        env->hflags |= MIPS_HFLAG_DSP;
+    }
 #else
     if (env->hflags & MIPS_HFLAG_BMASK) {
         /* If the exception was raised from a delay slot,