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; |