Commit 34ae7b51f54a5d58d30e31a92f8ece02973de50b
1 parent
f96f4c9d
Work around the lack of proper handling for self-modifying code.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2827 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
30 additions
and
2 deletions
target-mips/op.c
| @@ -1001,6 +1001,16 @@ void op_jnz_T2 (void) | @@ -1001,6 +1001,16 @@ void op_jnz_T2 (void) | ||
| 1001 | RETURN(); | 1001 | RETURN(); |
| 1002 | } | 1002 | } |
| 1003 | 1003 | ||
| 1004 | +void op_flush_icache_range(void) { | ||
| 1005 | + CALL_FROM_TB2(tlb_flush_page, env, T0 + T1); | ||
| 1006 | + RETURN(); | ||
| 1007 | +} | ||
| 1008 | + | ||
| 1009 | +void op_flush_icache_all(void) { | ||
| 1010 | + CALL_FROM_TB1(tb_flush, env); | ||
| 1011 | + RETURN(); | ||
| 1012 | +} | ||
| 1013 | + | ||
| 1004 | /* CP0 functions */ | 1014 | /* CP0 functions */ |
| 1005 | void op_mfc0_index (void) | 1015 | void op_mfc0_index (void) |
| 1006 | { | 1016 | { |
target-mips/translate.c
| @@ -5648,8 +5648,26 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -5648,8 +5648,26 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
| 5648 | gen_ldst(ctx, op, rt, rs, imm); | 5648 | gen_ldst(ctx, op, rt, rs, imm); |
| 5649 | break; | 5649 | break; |
| 5650 | case OPC_CACHE: | 5650 | case OPC_CACHE: |
| 5651 | - /* Treat as a noop */ | ||
| 5652 | - break; | 5651 | + /* FIXME: This works around self-modifying code, but only |
| 5652 | + if the guest OS handles it properly, and if there's no | ||
| 5653 | + such code executed in uncached space. */ | ||
| 5654 | + if (!(rt & 0x3)) | ||
| 5655 | + switch ((rt >> 2) & 0x7) { | ||
| 5656 | + case 4: | ||
| 5657 | + GEN_LOAD_REG_TN(T0, rs); | ||
| 5658 | + GEN_LOAD_IMM_TN(T1, imm); | ||
| 5659 | + gen_op_flush_icache_range(); | ||
| 5660 | + break; | ||
| 5661 | + case 2: | ||
| 5662 | + case 1: | ||
| 5663 | + case 0: | ||
| 5664 | + /* Can be very inefficient. */ | ||
| 5665 | + gen_op_flush_icache_all(); | ||
| 5666 | + break; | ||
| 5667 | + default: | ||
| 5668 | + break; | ||
| 5669 | + } | ||
| 5670 | + break; | ||
| 5653 | case OPC_PREF: | 5671 | case OPC_PREF: |
| 5654 | /* Treat as a noop */ | 5672 | /* Treat as a noop */ |
| 5655 | break; | 5673 | break; |