Commit 16c00cb2c2017aaa04f2849903210761825145e7
1 parent
dcb5b19a
Restart interrupts after an exception.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2664 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
33 additions
and
9 deletions
target-mips/op.c
... | ... | @@ -1365,7 +1365,7 @@ void op_mtc0_status (void) |
1365 | 1365 | !(env->hflags & MIPS_HFLAG_DM) && |
1366 | 1366 | (val & (1 << CP0St_UM))) |
1367 | 1367 | env->hflags |= MIPS_HFLAG_UM; |
1368 | - env->CP0_Status = val; | |
1368 | + env->CP0_Status = (env->CP0_Status & ~0xF878FF17) | val; | |
1369 | 1369 | if (loglevel & CPU_LOG_EXEC) |
1370 | 1370 | CALL_FROM_TB2(do_mtc0_status_debug, old, val); |
1371 | 1371 | CALL_FROM_TB1(cpu_mips_update_irq, env); |
... | ... | @@ -2181,6 +2181,19 @@ void op_save_pc (void) |
2181 | 2181 | RETURN(); |
2182 | 2182 | } |
2183 | 2183 | |
2184 | +void op_interrupt_restart (void) | |
2185 | +{ | |
2186 | + if (!(env->CP0_Status & (1 << CP0St_EXL)) && | |
2187 | + !(env->CP0_Status & (1 << CP0St_ERL)) && | |
2188 | + !(env->hflags & MIPS_HFLAG_DM) && | |
2189 | + (env->CP0_Status & (1 << CP0St_IE)) && | |
2190 | + (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) { | |
2191 | + env->CP0_Cause &= ~(0x1f << CP0Ca_EC); | |
2192 | + CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT); | |
2193 | + } | |
2194 | + RETURN(); | |
2195 | +} | |
2196 | + | |
2184 | 2197 | void op_raise_exception (void) |
2185 | 2198 | { |
2186 | 2199 | CALL_FROM_TB1(do_raise_exception, PARAM1); | ... | ... |
target-mips/translate.c
... | ... | @@ -5234,15 +5234,26 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
5234 | 5234 | if (env->singlestep_enabled) { |
5235 | 5235 | save_cpu_state(ctxp, ctx.bstate == BS_NONE); |
5236 | 5236 | gen_op_debug(); |
5237 | - goto done_generating; | |
5238 | - } | |
5239 | - else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) { | |
5240 | - save_cpu_state(ctxp, 0); | |
5241 | - gen_goto_tb(&ctx, 0, ctx.pc); | |
5237 | + } else { | |
5238 | + switch (ctx.bstate) { | |
5239 | + case BS_EXCP: | |
5240 | + gen_op_interrupt_restart(); | |
5241 | + break; | |
5242 | + case BS_STOP: | |
5243 | + gen_op_interrupt_restart(); | |
5244 | + /* Fall through. */ | |
5245 | + case BS_NONE: | |
5246 | + save_cpu_state(ctxp, 0); | |
5247 | + gen_goto_tb(&ctx, 0, ctx.pc); | |
5248 | + break; | |
5249 | + case BS_BRANCH: | |
5250 | + default: | |
5251 | + break; | |
5252 | + } | |
5253 | + gen_op_reset_T0(); | |
5254 | + /* Generate the return instruction. */ | |
5255 | + gen_op_exit_tb(); | |
5242 | 5256 | } |
5243 | - gen_op_reset_T0(); | |
5244 | - /* Generate the return instruction */ | |
5245 | - gen_op_exit_tb(); | |
5246 | 5257 | done_generating: |
5247 | 5258 | *gen_opc_ptr = INDEX_op_end; |
5248 | 5259 | if (search_pc) { | ... | ... |