void do_interrupt (CPUState *env)
{
- target_ulong pc, offset;
+ target_ulong offset;
int cause = -1;
if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
set_DEPC:
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
- * come back to the jump
- */
+ come back to the jump. */
env->CP0_DEPC = env->PC - 4;
env->hflags &= ~MIPS_HFLAG_BMASK;
} else {
enter_debug_mode:
env->hflags |= MIPS_HFLAG_DM;
/* EJTAG probe trap enable is not implemented... */
- pc = 0xBFC00480;
+ env->PC = 0xBFC00480;
break;
case EXCP_RESET:
-#ifdef MIPS_USES_R4K_TLB
- env->CP0_random = MIPS_TLB_NB - 1;
-#endif
- env->CP0_Wired = 0;
- env->CP0_Config0 = MIPS_CONFIG0;
- env->CP0_Config1 = MIPS_CONFIG1;
- env->CP0_Config2 = MIPS_CONFIG2;
- env->CP0_Config3 = MIPS_CONFIG3;
- env->CP0_WatchLo = 0;
- env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
- goto set_error_EPC;
+ cpu_reset(env);
+ break;
case EXCP_SRESET:
- env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV) |
- (1 << CP0St_SR);
+ env->CP0_Status = (1 << CP0St_SR);
env->CP0_WatchLo = 0;
goto set_error_EPC;
case EXCP_NMI:
- env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV) |
- (1 << CP0St_NMI);
+ env->CP0_Status = (1 << CP0St_NMI);
set_error_EPC:
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
- * come back to the jump
- */
+ come back to the jump. */
env->CP0_ErrorEPC = env->PC - 4;
env->hflags &= ~MIPS_HFLAG_BMASK;
} else {
env->CP0_ErrorEPC = env->PC;
}
env->hflags |= MIPS_HFLAG_ERL;
- env->CP0_Status |= (1 << CP0St_ERL);
- pc = 0xBFC00000;
+ env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
+ env->PC = 0xBFC00000;
break;
case EXCP_MCHECK:
cause = 24;
offset = 0x000;
goto set_EPC;
set_EPC:
- if (env->CP0_Status & (1 << CP0St_BEV)) {
- pc = 0xBFC00200;
- } else {
- pc = 0x80000000;
- }
- env->hflags |= MIPS_HFLAG_EXL;
- env->CP0_Status |= (1 << CP0St_EXL);
- pc += offset;
- env->CP0_Cause = (env->CP0_Cause & ~0x7C) | (cause << 2);
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
- * come back to the jump
- */
+ come back to the jump. */
env->CP0_EPC = env->PC - 4;
env->CP0_Cause |= 0x80000000;
env->hflags &= ~MIPS_HFLAG_BMASK;
env->CP0_EPC = env->PC;
env->CP0_Cause &= ~0x80000000;
}
+ if (env->CP0_Status & (1 << CP0St_BEV)) {
+ env->PC = 0xBFC00200;
+ } else {
+ env->PC = 0x80000000;
+ }
+ env->hflags |= MIPS_HFLAG_EXL;
+ env->CP0_Status |= (1 << CP0St_EXL);
+ env->PC += offset;
+ env->CP0_Cause = (env->CP0_Cause & ~0x7C) | (cause << 2);
break;
default:
if (logfile) {
printf("Invalid MIPS exception %d. Exiting\n", env->exception_index);
exit(1);
}
- env->PC = pc;
if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
fprintf(logfile, "%s: PC %08x EPC %08x cause %d excp %d\n"
" S %08x C %08x A %08x D %08x\n",
{
const char *opn = "unk";
- if (!(ctx->CP0_Status & (1 << CP0St_CU0)) &&
- (ctx->hflags & MIPS_HFLAG_UM) &&
+ if ((!ctx->CP0_Status & (1 << CP0St_CU0) &&
+ (ctx->hflags & MIPS_HFLAG_UM)) &&
!(ctx->hflags & MIPS_HFLAG_ERL) &&
!(ctx->hflags & MIPS_HFLAG_EXL)) {
if (loglevel & CPU_LOG_TB_IN_ASM) {
tlb_flush(env, 1);
/* Minimal init */
+ if (env->hflags & MIPS_HFLAG_BMASK) {
+ /* If the exception was raised from a delay slot,
+ * come back to the jump. */
+ env->CP0_ErrorEPC = env->PC - 4;
+ env->hflags &= ~MIPS_HFLAG_BMASK;
+ } else {
+ env->CP0_ErrorEPC = env->PC;
+ }
env->PC = 0xBFC00000;
#if defined (MIPS_USES_R4K_TLB)
env->CP0_random = MIPS_TLB_NB - 1;
env->CP0_Config1 = MIPS_CONFIG1;
env->CP0_Config2 = MIPS_CONFIG2;
env->CP0_Config3 = MIPS_CONFIG3;
- env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
+ env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
env->CP0_WatchLo = 0;
env->hflags = MIPS_HFLAG_ERL;
/* Count register increments in debug mode, EJTAG version 1 */