提交 f41c52f1 编写于 作者: T ths

Save state for all CP0 instructions, they may throw a CPU exception.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2622 c046a42c-6fe2-441c-8c8c-71466251a162
上级 42a10898
...@@ -1360,9 +1360,14 @@ void op_mtc0_status (void) ...@@ -1360,9 +1360,14 @@ void op_mtc0_status (void)
no 64bit addressing implemented. */ no 64bit addressing implemented. */
val = (int32_t)T0 & 0xF878FF17; val = (int32_t)T0 & 0xF878FF17;
old = env->CP0_Status; old = env->CP0_Status;
if (!(val & (1 << CP0St_EXL)) &&
!(val & (1 << CP0St_ERL)) &&
!(env->hflags & MIPS_HFLAG_DM) &&
(val & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM;
env->CP0_Status = val; env->CP0_Status = val;
if (loglevel & CPU_LOG_TB_IN_ASM) if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB2(do_mtc0_status_debug, old, val); CALL_FROM_TB2(do_mtc0_status_debug, old, val);
CALL_FROM_TB1(cpu_mips_update_irq, env); CALL_FROM_TB1(cpu_mips_update_irq, env);
RETURN(); RETURN();
} }
...@@ -2077,10 +2082,12 @@ void op_set_lladdr (void) ...@@ -2077,10 +2082,12 @@ void op_set_lladdr (void)
RETURN(); RETURN();
} }
void debug_eret (void); void debug_pre_eret (void);
void debug_post_eret (void);
void op_eret (void) void op_eret (void)
{ {
CALL_FROM_TB0(debug_eret); if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB0(debug_pre_eret);
if (env->CP0_Status & (1 << CP0St_ERL)) { if (env->CP0_Status & (1 << CP0St_ERL)) {
env->PC = env->CP0_ErrorEPC; env->PC = env->CP0_ErrorEPC;
env->CP0_Status &= ~(1 << CP0St_ERL); env->CP0_Status &= ~(1 << CP0St_ERL);
...@@ -2093,13 +2100,16 @@ void op_eret (void) ...@@ -2093,13 +2100,16 @@ void op_eret (void)
!(env->hflags & MIPS_HFLAG_DM) && !(env->hflags & MIPS_HFLAG_DM) &&
(env->CP0_Status & (1 << CP0St_UM))) (env->CP0_Status & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM; env->hflags |= MIPS_HFLAG_UM;
if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB0(debug_post_eret);
env->CP0_LLAddr = 1; env->CP0_LLAddr = 1;
RETURN(); RETURN();
} }
void op_deret (void) void op_deret (void)
{ {
CALL_FROM_TB0(debug_eret); if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB0(debug_pre_eret);
env->PC = env->CP0_DEPC; env->PC = env->CP0_DEPC;
env->hflags |= MIPS_HFLAG_DM; env->hflags |= MIPS_HFLAG_DM;
if (!(env->CP0_Status & (1 << CP0St_EXL)) && if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
...@@ -2107,6 +2117,8 @@ void op_deret (void) ...@@ -2107,6 +2117,8 @@ void op_deret (void)
!(env->hflags & MIPS_HFLAG_DM) && !(env->hflags & MIPS_HFLAG_DM) &&
(env->CP0_Status & (1 << CP0St_UM))) (env->CP0_Status & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM; env->hflags |= MIPS_HFLAG_UM;
if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB0(debug_post_eret);
env->CP0_LLAddr = 1; env->CP0_LLAddr = 1;
RETURN(); RETURN();
} }
......
...@@ -329,10 +329,12 @@ void do_mfc0_count (void) ...@@ -329,10 +329,12 @@ void do_mfc0_count (void)
void do_mtc0_status_debug(uint32_t old, uint32_t val) void do_mtc0_status_debug(uint32_t old, uint32_t val)
{ {
const uint32_t mask = 0x0000FF00; fprintf(logfile, "Status %08x (%08x) => %08x (%08x) Cause %08x",
fprintf(logfile, "Status %08x => %08x Cause %08x (%08x %08x %08x)\n", old, old & env->CP0_Cause & CP0Ca_IP_mask,
old, val, env->CP0_Cause, old & mask, val & mask, val, val & env->CP0_Cause & CP0Ca_IP_mask,
env->CP0_Cause & mask); env->CP0_Cause);
(env->hflags & MIPS_HFLAG_UM) ? fputs(", UM\n", logfile)
: fputs("\n", logfile);
} }
void do_mtc0_status_irqraise_debug(void) void do_mtc0_status_irqraise_debug(void)
...@@ -508,15 +510,29 @@ void dump_sc (void) ...@@ -508,15 +510,29 @@ void dump_sc (void)
} }
} }
void debug_eret (void) void debug_pre_eret (void)
{ {
if (loglevel) { fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
fprintf(logfile, "ERET: pc " TARGET_FMT_lx " EPC " TARGET_FMT_lx, env->PC, env->CP0_EPC);
env->PC, env->CP0_EPC); if (env->CP0_Status & (1 << CP0St_ERL))
if (env->CP0_Status & (1 << CP0St_ERL)) fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); if (env->hflags & MIPS_HFLAG_DM)
fprintf(logfile, " DEPC " TARGET_FMT_lx, env->CP0_DEPC);
fputs("\n", logfile);
}
void debug_post_eret (void)
{
fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
env->PC, env->CP0_EPC);
if (env->CP0_Status & (1 << CP0St_ERL))
fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
if (env->hflags & MIPS_HFLAG_DM)
fprintf(logfile, " DEPC " TARGET_FMT_lx, env->CP0_DEPC);
if (env->hflags & MIPS_HFLAG_UM)
fputs(", UM\n", logfile);
else
fputs("\n", logfile); fputs("\n", logfile);
}
} }
void do_pmon (int function) void do_pmon (int function)
......
...@@ -4880,6 +4880,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) ...@@ -4880,6 +4880,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
} }
break; break;
case OPC_CP0: case OPC_CP0:
save_cpu_state(ctx, 1);
gen_op_cp0_enabled(); gen_op_cp0_enabled();
op1 = MASK_CP0(ctx->opcode); op1 = MASK_CP0(ctx->opcode);
switch (op1) { switch (op1) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册