Commit 16c00cb2c2017aaa04f2849903210761825145e7

Authored by ths
1 parent dcb5b19a

Restart interrupts after an exception.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2664 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/op.c
@@ -1365,7 +1365,7 @@ void op_mtc0_status (void) @@ -1365,7 +1365,7 @@ void op_mtc0_status (void)
1365 !(env->hflags & MIPS_HFLAG_DM) && 1365 !(env->hflags & MIPS_HFLAG_DM) &&
1366 (val & (1 << CP0St_UM))) 1366 (val & (1 << CP0St_UM)))
1367 env->hflags |= MIPS_HFLAG_UM; 1367 env->hflags |= MIPS_HFLAG_UM;
1368 - env->CP0_Status = val; 1368 + env->CP0_Status = (env->CP0_Status & ~0xF878FF17) | val;
1369 if (loglevel & CPU_LOG_EXEC) 1369 if (loglevel & CPU_LOG_EXEC)
1370 CALL_FROM_TB2(do_mtc0_status_debug, old, val); 1370 CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1371 CALL_FROM_TB1(cpu_mips_update_irq, env); 1371 CALL_FROM_TB1(cpu_mips_update_irq, env);
@@ -2181,6 +2181,19 @@ void op_save_pc (void) @@ -2181,6 +2181,19 @@ void op_save_pc (void)
2181 RETURN(); 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 void op_raise_exception (void) 2197 void op_raise_exception (void)
2185 { 2198 {
2186 CALL_FROM_TB1(do_raise_exception, PARAM1); 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,15 +5234,26 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5234 if (env->singlestep_enabled) { 5234 if (env->singlestep_enabled) {
5235 save_cpu_state(ctxp, ctx.bstate == BS_NONE); 5235 save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5236 gen_op_debug(); 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 done_generating: 5257 done_generating:
5247 *gen_opc_ptr = INDEX_op_end; 5258 *gen_opc_ptr = INDEX_op_end;
5248 if (search_pc) { 5259 if (search_pc) {