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) { |