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
This commit is contained in:
parent
f96f4c9d72
commit
34ae7b51f5
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user