Message ID | 1346135785-12119-3-git-send-email-proljc@gmail.com |
---|---|
State | New |
Headers | show |
On Tue, Aug 28, 2012 at 02:36:13PM +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 | 8 ++++++-- > target-mips/helper.c | 3 +++ > target-mips/op_helper.c | 19 +++++++++++++++++++ > target-mips/translate.c | 23 +++++++++++++++++++++++ > 5 files changed, 57 insertions(+), 2 deletions(-) > > diff --git a/linux-user/main.c b/linux-user/main.c > index 7dea084..f70b31d 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 ce3467f..0aada15 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 > 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/op_helper.c b/target-mips/op_helper.c > index e5bc93e..f2bef2a 100644 > --- a/target-mips/op_helper.c > +++ b/target-mips/op_helper.c > @@ -62,6 +62,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_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; > + } > + > + } else 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; > + } > + > + } This check is wrong on CPUs having both DSP and DSPR2 support, as the second test will never be reached. Also there is no need to check if the instruction are supported (at least for ASE_DSP), as for each CPU CP0_Status_rw_bitmask ensures that only supported bits can be written. > if (env->insn_flags & ISA_MIPS32R2) { > if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { > env->hflags |= MIPS_HFLAG_COP1X; > diff --git a/target-mips/translate.c b/target-mips/translate.c > index b293419..6000183 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) > @@ -12861,6 +12879,11 @@ void cpu_state_reset(CPUMIPSState *env) > env->hflags |= MIPS_HFLAG_64; > } > #endif > + 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; > + } You can put two distinct if there without else, so that the fact that ASE_DSPR2 implies ASE_DSP is not hardcoded (though it is unlikely to change). > env->exception_index = EXCP_NONE; > } > > -- > 1.7.9.5 > >
diff --git a/linux-user/main.c b/linux-user/main.c index 7dea084..f70b31d 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 ce3467f..0aada15 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 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/op_helper.c b/target-mips/op_helper.c index e5bc93e..f2bef2a 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -62,6 +62,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_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; + } + + } else 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; + } + + } if (env->insn_flags & ISA_MIPS32R2) { if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { env->hflags |= MIPS_HFLAG_COP1X; diff --git a/target-mips/translate.c b/target-mips/translate.c index b293419..6000183 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) @@ -12861,6 +12879,11 @@ void cpu_state_reset(CPUMIPSState *env) env->hflags |= MIPS_HFLAG_64; } #endif + 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; + } env->exception_index = EXCP_NONE; }
Add MIPS ASE DSP resources access check. Signed-off-by: Jia Liu <proljc@gmail.com> --- linux-user/main.c | 6 ++++++ target-mips/cpu.h | 8 ++++++-- target-mips/helper.c | 3 +++ target-mips/op_helper.c | 19 +++++++++++++++++++ target-mips/translate.c | 23 +++++++++++++++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-)