target-mips: Add ASE DSP resources access check

Add MIPS ASE DSP resources access check.

Signed-off-by: Jia Liu <proljc@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Jia Liu 2012-10-24 22:17:02 +08:00 committed by Aurelien Jarno
parent 235eb0158c
commit 853c3240c0
4 changed files with 53 additions and 2 deletions

View file

@ -2286,6 +2286,12 @@ done_syscall:
queue_signal(env, info.si_signo, &info); queue_signal(env, info.si_signo, &info);
} }
break; 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: default:
// error: // error:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",

View file

@ -415,7 +415,7 @@ struct CPUMIPSState {
int error_code; int error_code;
uint32_t hflags; /* CPU State */ uint32_t hflags; /* CPU State */
/* TMASK defines different execution modes */ /* TMASK defines different execution modes */
#define MIPS_HFLAG_TMASK 0x007FF #define MIPS_HFLAG_TMASK 0xC07FF
#define MIPS_HFLAG_MODE 0x00007 /* execution modes */ #define MIPS_HFLAG_MODE 0x00007 /* execution modes */
/* The KSU flags must be the lowest bits in hflags. The flag order /* 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 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_BDS32 0x10000 /* branch requires 32-bit delay slot */
#define MIPS_HFLAG_BX 0x20000 /* branch exchanges execution mode */ #define MIPS_HFLAG_BX 0x20000 /* branch exchanges execution mode */
#define MIPS_HFLAG_BMASK (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT) #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 btarget; /* Jump / branch target */
target_ulong bcond; /* Branch condition (if needed) */ target_ulong bcond; /* Branch condition (if needed) */
@ -610,8 +613,9 @@ enum {
EXCP_MDMX, EXCP_MDMX,
EXCP_C2E, EXCP_C2E,
EXCP_CACHE, /* 32 */ EXCP_CACHE, /* 32 */
EXCP_DSPDIS,
EXCP_LAST = EXCP_CACHE, EXCP_LAST = EXCP_DSPDIS,
}; };
/* Dummy exception for conditional stores. */ /* Dummy exception for conditional stores. */
#define EXCP_SC 0x100 #define EXCP_SC 0x100
@ -772,6 +776,21 @@ static inline void compute_hflags(CPUMIPSState *env)
if (env->CP0_Status & (1 << CP0St_FR)) { if (env->CP0_Status & (1 << CP0St_FR)) {
env->hflags |= MIPS_HFLAG_F64; env->hflags |= MIPS_HFLAG_F64;
} }
if (env->insn_flags & ASE_DSPR2) {
/* Enables access MIPS DSP resources, now our cpu is DSP ASER2,
so enable to access DSPR2 resources. */
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, now our cpu is DSP ASE,
so enable to access DSP resources. */
if (env->CP0_Status & (1 << CP0St_MX)) {
env->hflags |= MIPS_HFLAG_DSP;
}
}
if (env->insn_flags & ISA_MIPS32R2) { if (env->insn_flags & ISA_MIPS32R2) {
if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
env->hflags |= MIPS_HFLAG_COP1X; env->hflags |= MIPS_HFLAG_COP1X;

View file

@ -592,6 +592,9 @@ void do_interrupt (CPUMIPSState *env)
case EXCP_THREAD: case EXCP_THREAD:
cause = 25; cause = 25;
goto set_EPC; goto set_EPC;
case EXCP_DSPDIS:
cause = 26;
goto set_EPC;
case EXCP_CACHE: case EXCP_CACHE:
cause = 30; cause = 30;
if (env->CP0_Status & (1 << CP0St_BEV)) { if (env->CP0_Status & (1 << CP0St_BEV)) {

View file

@ -948,6 +948,24 @@ static inline void check_cp1_registers(DisasContext *ctx, int regs)
generate_exception(ctx, EXCP_RI); 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 /* This code generates a "reserved instruction" exception if the
CPU does not support the instruction set corresponding to flags. */ CPU does not support the instruction set corresponding to flags. */
static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags) static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
@ -13209,6 +13227,11 @@ void cpu_state_reset(CPUMIPSState *env)
if (env->CP0_Config1 & (1 << CP0C1_FP)) { if (env->CP0_Config1 & (1 << CP0C1_FP)) {
env->CP0_Status |= (1 << CP0St_CU1); 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 #else
if (env->hflags & MIPS_HFLAG_BMASK) { if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot, /* If the exception was raised from a delay slot,