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
master
ths 2007-05-18 01:13:09 +00:00
parent f96f4c9d72
commit 34ae7b51f5
2 changed files with 30 additions and 2 deletions

View File

@ -1001,6 +1001,16 @@ void op_jnz_T2 (void)
RETURN();
}
void op_flush_icache_range(void) {
CALL_FROM_TB2(tlb_flush_page, env, T0 + T1);
RETURN();
}
void op_flush_icache_all(void) {
CALL_FROM_TB1(tb_flush, env);
RETURN();
}
/* CP0 functions */
void op_mfc0_index (void)
{

View File

@ -5648,8 +5648,26 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
gen_ldst(ctx, op, rt, rs, imm);
break;
case OPC_CACHE:
/* Treat as a noop */
break;
/* FIXME: This works around self-modifying code, but only
if the guest OS handles it properly, and if there's no
such code executed in uncached space. */
if (!(rt & 0x3))
switch ((rt >> 2) & 0x7) {
case 4:
GEN_LOAD_REG_TN(T0, rs);
GEN_LOAD_IMM_TN(T1, imm);
gen_op_flush_icache_range();
break;
case 2:
case 1:
case 0:
/* Can be very inefficient. */
gen_op_flush_icache_all();
break;
default:
break;
}
break;
case OPC_PREF:
/* Treat as a noop */
break;