aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/translate_init.c
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2014-01-19 17:49:11 +0100
committerAlexander Graf <agraf@suse.de>2014-06-16 13:24:35 +0200
commitea71258da4b8141d8a808d94518a0964c0f92810 (patch)
tree253b6f10663b08f0846bd40a08821501a15495dd /target-ppc/translate_init.c
parentd2ea2bf740c515de41f45e4d6f36683db3458881 (diff)
PPC: Properly emulate L1CSR0 and L1CSR1
There are 2 L1 cache control registers - one for data (L1CSR0) and one for instructions (L1CSR1). Emulate both of them well enough to give the guest the illusion that it could actually do anything about its caches. Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/translate_init.c')
-rw-r--r--target-ppc/translate_init.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index fc9d932268..0f9dec753b 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -1448,7 +1448,16 @@ static void spr_write_e500_l1csr0 (void *opaque, int sprn, int gprn)
{
TCGv t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[gprn], ~256);
+ tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE);
+ gen_store_spr(sprn, t0);
+ tcg_temp_free(t0);
+}
+
+static void spr_write_e500_l1csr1(void *opaque, int sprn, int gprn)
+{
+ TCGv t0 = tcg_temp_new();
+
+ tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE);
gen_store_spr(sprn, t0);
tcg_temp_free(t0);
}
@@ -4780,10 +4789,9 @@ static void init_proc_e500 (CPUPPCState *env, int version)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_e500_l1csr0,
0x00000000);
- /* XXX : not implemented */
spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_e500_l1csr1,
0x00000000);
spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
SPR_NOACCESS, SPR_NOACCESS,