Commit df1561e22df42643d769aacdcc7d6d239f243366
1 parent
6963d7af
The previous patch to make breakpoints work was a performance
disaster, use a similiar hack as ARM does instead. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2848 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
7 additions
and
32 deletions
target-mips/op.c
| ... | ... | @@ -1002,16 +1002,6 @@ void op_jnz_T2 (void) |
| 1002 | 1002 | RETURN(); |
| 1003 | 1003 | } |
| 1004 | 1004 | |
| 1005 | -void op_flush_icache_range(void) { | |
| 1006 | - CALL_FROM_TB2(tlb_flush_page, env, T0 + T1); | |
| 1007 | - RETURN(); | |
| 1008 | -} | |
| 1009 | - | |
| 1010 | -void op_flush_icache_all(void) { | |
| 1011 | - CALL_FROM_TB1(tb_flush, env); | |
| 1012 | - RETURN(); | |
| 1013 | -} | |
| 1014 | - | |
| 1015 | 1005 | /* CP0 functions */ |
| 1016 | 1006 | void op_mfc0_index (void) |
| 1017 | 1007 | { | ... | ... |
target-mips/translate.c
| ... | ... | @@ -4236,7 +4236,6 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int |
| 4236 | 4236 | break; |
| 4237 | 4237 | case OPC_ERET: |
| 4238 | 4238 | opn = "eret"; |
| 4239 | - save_cpu_state(ctx, 0); | |
| 4240 | 4239 | gen_op_eret(); |
| 4241 | 4240 | ctx->bstate = BS_EXCP; |
| 4242 | 4241 | break; |
| ... | ... | @@ -4246,7 +4245,6 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int |
| 4246 | 4245 | MIPS_INVAL(opn); |
| 4247 | 4246 | generate_exception(ctx, EXCP_RI); |
| 4248 | 4247 | } else { |
| 4249 | - save_cpu_state(ctx, 0); | |
| 4250 | 4248 | gen_op_deret(); |
| 4251 | 4249 | ctx->bstate = BS_EXCP; |
| 4252 | 4250 | } |
| ... | ... | @@ -5526,6 +5524,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 5526 | 5524 | generate_exception(ctx, EXCP_SYSCALL); |
| 5527 | 5525 | break; |
| 5528 | 5526 | case OPC_BREAK: |
| 5527 | + /* XXX: Hack to work around wrong handling of self-modifying code. */ | |
| 5528 | + ctx->pc += 4; | |
| 5529 | + save_cpu_state(ctx, 1); | |
| 5530 | + ctx->pc -= 4; | |
| 5529 | 5531 | generate_exception(ctx, EXCP_BREAK); |
| 5530 | 5532 | break; |
| 5531 | 5533 | case OPC_SPIM: |
| ... | ... | @@ -5791,25 +5793,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 5791 | 5793 | gen_ldst(ctx, op, rt, rs, imm); |
| 5792 | 5794 | break; |
| 5793 | 5795 | case OPC_CACHE: |
| 5794 | - /* FIXME: This works around self-modifying code, but only | |
| 5795 | - if the guest OS handles it properly, and if there's no | |
| 5796 | - such code executed in uncached space. */ | |
| 5797 | - if (!(rt & 0x3)) | |
| 5798 | - switch ((rt >> 2) & 0x7) { | |
| 5799 | - case 4: | |
| 5800 | - GEN_LOAD_REG_TN(T0, rs); | |
| 5801 | - GEN_LOAD_IMM_TN(T1, imm); | |
| 5802 | - gen_op_flush_icache_range(); | |
| 5803 | - break; | |
| 5804 | - case 2: | |
| 5805 | - case 1: | |
| 5806 | - case 0: | |
| 5807 | - /* Can be very inefficient. */ | |
| 5808 | - gen_op_flush_icache_all(); | |
| 5809 | - break; | |
| 5810 | - default: | |
| 5811 | - break; | |
| 5812 | - } | |
| 5796 | + /* Treat as a noop */ | |
| 5813 | 5797 | break; |
| 5814 | 5798 | case OPC_PREF: |
| 5815 | 5799 | /* Treat as a noop */ |
| ... | ... | @@ -6079,7 +6063,8 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
| 6079 | 6063 | switch (ctx.bstate) { |
| 6080 | 6064 | case BS_STOP: |
| 6081 | 6065 | gen_op_interrupt_restart(); |
| 6082 | - /* Fall through. */ | |
| 6066 | + gen_goto_tb(&ctx, 0, ctx.pc); | |
| 6067 | + break; | |
| 6083 | 6068 | case BS_NONE: |
| 6084 | 6069 | save_cpu_state(ctxp, 0); |
| 6085 | 6070 | gen_goto_tb(&ctx, 0, ctx.pc); | ... | ... |