Message ID | 1347415315-2180-3-git-send-email-proljc@gmail.com |
---|---|
State | New |
Headers | show |
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 --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,
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(-)