Commit f41c52f17031325652387086006c5847bc703abd
1 parent
42a10898
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
Showing
3 changed files
with
45 additions
and
16 deletions
target-mips/op.c
@@ -1360,9 +1360,14 @@ void op_mtc0_status (void) | @@ -1360,9 +1360,14 @@ void op_mtc0_status (void) | ||
1360 | no 64bit addressing implemented. */ | 1360 | no 64bit addressing implemented. */ |
1361 | val = (int32_t)T0 & 0xF878FF17; | 1361 | val = (int32_t)T0 & 0xF878FF17; |
1362 | old = env->CP0_Status; | 1362 | old = env->CP0_Status; |
1363 | + if (!(val & (1 << CP0St_EXL)) && | ||
1364 | + !(val & (1 << CP0St_ERL)) && | ||
1365 | + !(env->hflags & MIPS_HFLAG_DM) && | ||
1366 | + (val & (1 << CP0St_UM))) | ||
1367 | + env->hflags |= MIPS_HFLAG_UM; | ||
1363 | env->CP0_Status = val; | 1368 | env->CP0_Status = val; |
1364 | - if (loglevel & CPU_LOG_TB_IN_ASM) | ||
1365 | - CALL_FROM_TB2(do_mtc0_status_debug, old, val); | 1369 | + if (loglevel & CPU_LOG_EXEC) |
1370 | + CALL_FROM_TB2(do_mtc0_status_debug, old, val); | ||
1366 | CALL_FROM_TB1(cpu_mips_update_irq, env); | 1371 | CALL_FROM_TB1(cpu_mips_update_irq, env); |
1367 | RETURN(); | 1372 | RETURN(); |
1368 | } | 1373 | } |
@@ -2077,10 +2082,12 @@ void op_set_lladdr (void) | @@ -2077,10 +2082,12 @@ void op_set_lladdr (void) | ||
2077 | RETURN(); | 2082 | RETURN(); |
2078 | } | 2083 | } |
2079 | 2084 | ||
2080 | -void debug_eret (void); | 2085 | +void debug_pre_eret (void); |
2086 | +void debug_post_eret (void); | ||
2081 | void op_eret (void) | 2087 | void op_eret (void) |
2082 | { | 2088 | { |
2083 | - CALL_FROM_TB0(debug_eret); | 2089 | + if (loglevel & CPU_LOG_EXEC) |
2090 | + CALL_FROM_TB0(debug_pre_eret); | ||
2084 | if (env->CP0_Status & (1 << CP0St_ERL)) { | 2091 | if (env->CP0_Status & (1 << CP0St_ERL)) { |
2085 | env->PC = env->CP0_ErrorEPC; | 2092 | env->PC = env->CP0_ErrorEPC; |
2086 | env->CP0_Status &= ~(1 << CP0St_ERL); | 2093 | env->CP0_Status &= ~(1 << CP0St_ERL); |
@@ -2093,13 +2100,16 @@ void op_eret (void) | @@ -2093,13 +2100,16 @@ void op_eret (void) | ||
2093 | !(env->hflags & MIPS_HFLAG_DM) && | 2100 | !(env->hflags & MIPS_HFLAG_DM) && |
2094 | (env->CP0_Status & (1 << CP0St_UM))) | 2101 | (env->CP0_Status & (1 << CP0St_UM))) |
2095 | env->hflags |= MIPS_HFLAG_UM; | 2102 | env->hflags |= MIPS_HFLAG_UM; |
2103 | + if (loglevel & CPU_LOG_EXEC) | ||
2104 | + CALL_FROM_TB0(debug_post_eret); | ||
2096 | env->CP0_LLAddr = 1; | 2105 | env->CP0_LLAddr = 1; |
2097 | RETURN(); | 2106 | RETURN(); |
2098 | } | 2107 | } |
2099 | 2108 | ||
2100 | void op_deret (void) | 2109 | void op_deret (void) |
2101 | { | 2110 | { |
2102 | - CALL_FROM_TB0(debug_eret); | 2111 | + if (loglevel & CPU_LOG_EXEC) |
2112 | + CALL_FROM_TB0(debug_pre_eret); | ||
2103 | env->PC = env->CP0_DEPC; | 2113 | env->PC = env->CP0_DEPC; |
2104 | env->hflags |= MIPS_HFLAG_DM; | 2114 | env->hflags |= MIPS_HFLAG_DM; |
2105 | if (!(env->CP0_Status & (1 << CP0St_EXL)) && | 2115 | if (!(env->CP0_Status & (1 << CP0St_EXL)) && |
@@ -2107,6 +2117,8 @@ void op_deret (void) | @@ -2107,6 +2117,8 @@ void op_deret (void) | ||
2107 | !(env->hflags & MIPS_HFLAG_DM) && | 2117 | !(env->hflags & MIPS_HFLAG_DM) && |
2108 | (env->CP0_Status & (1 << CP0St_UM))) | 2118 | (env->CP0_Status & (1 << CP0St_UM))) |
2109 | env->hflags |= MIPS_HFLAG_UM; | 2119 | env->hflags |= MIPS_HFLAG_UM; |
2120 | + if (loglevel & CPU_LOG_EXEC) | ||
2121 | + CALL_FROM_TB0(debug_post_eret); | ||
2110 | env->CP0_LLAddr = 1; | 2122 | env->CP0_LLAddr = 1; |
2111 | RETURN(); | 2123 | RETURN(); |
2112 | } | 2124 | } |
target-mips/op_helper.c
@@ -329,10 +329,12 @@ void do_mfc0_count (void) | @@ -329,10 +329,12 @@ void do_mfc0_count (void) | ||
329 | 329 | ||
330 | void do_mtc0_status_debug(uint32_t old, uint32_t val) | 330 | void do_mtc0_status_debug(uint32_t old, uint32_t val) |
331 | { | 331 | { |
332 | - const uint32_t mask = 0x0000FF00; | ||
333 | - fprintf(logfile, "Status %08x => %08x Cause %08x (%08x %08x %08x)\n", | ||
334 | - old, val, env->CP0_Cause, old & mask, val & mask, | ||
335 | - env->CP0_Cause & mask); | 332 | + fprintf(logfile, "Status %08x (%08x) => %08x (%08x) Cause %08x", |
333 | + old, old & env->CP0_Cause & CP0Ca_IP_mask, | ||
334 | + val, val & env->CP0_Cause & CP0Ca_IP_mask, | ||
335 | + env->CP0_Cause); | ||
336 | + (env->hflags & MIPS_HFLAG_UM) ? fputs(", UM\n", logfile) | ||
337 | + : fputs("\n", logfile); | ||
336 | } | 338 | } |
337 | 339 | ||
338 | void do_mtc0_status_irqraise_debug(void) | 340 | void do_mtc0_status_irqraise_debug(void) |
@@ -508,15 +510,29 @@ void dump_sc (void) | @@ -508,15 +510,29 @@ void dump_sc (void) | ||
508 | } | 510 | } |
509 | } | 511 | } |
510 | 512 | ||
511 | -void debug_eret (void) | 513 | +void debug_pre_eret (void) |
512 | { | 514 | { |
513 | - if (loglevel) { | ||
514 | - fprintf(logfile, "ERET: pc " TARGET_FMT_lx " EPC " TARGET_FMT_lx, | ||
515 | - env->PC, env->CP0_EPC); | ||
516 | - if (env->CP0_Status & (1 << CP0St_ERL)) | ||
517 | - fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); | 515 | + fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, |
516 | + env->PC, env->CP0_EPC); | ||
517 | + if (env->CP0_Status & (1 << CP0St_ERL)) | ||
518 | + fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); | ||
519 | + if (env->hflags & MIPS_HFLAG_DM) | ||
520 | + fprintf(logfile, " DEPC " TARGET_FMT_lx, env->CP0_DEPC); | ||
521 | + fputs("\n", logfile); | ||
522 | +} | ||
523 | + | ||
524 | +void debug_post_eret (void) | ||
525 | +{ | ||
526 | + fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, | ||
527 | + env->PC, env->CP0_EPC); | ||
528 | + if (env->CP0_Status & (1 << CP0St_ERL)) | ||
529 | + fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); | ||
530 | + if (env->hflags & MIPS_HFLAG_DM) | ||
531 | + fprintf(logfile, " DEPC " TARGET_FMT_lx, env->CP0_DEPC); | ||
532 | + if (env->hflags & MIPS_HFLAG_UM) | ||
533 | + fputs(", UM\n", logfile); | ||
534 | + else | ||
518 | fputs("\n", logfile); | 535 | fputs("\n", logfile); |
519 | - } | ||
520 | } | 536 | } |
521 | 537 | ||
522 | void do_pmon (int function) | 538 | void do_pmon (int function) |
target-mips/translate.c
@@ -4880,6 +4880,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4880,6 +4880,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
4880 | } | 4880 | } |
4881 | break; | 4881 | break; |
4882 | case OPC_CP0: | 4882 | case OPC_CP0: |
4883 | + save_cpu_state(ctx, 1); | ||
4883 | gen_op_cp0_enabled(); | 4884 | gen_op_cp0_enabled(); |
4884 | op1 = MASK_CP0(ctx->opcode); | 4885 | op1 = MASK_CP0(ctx->opcode); |
4885 | switch (op1) { | 4886 | switch (op1) { |