OSDN Git Service

PPC: Properly emulate L1CSR0 and L1CSR1
authorAlexander Graf <agraf@suse.de>
Sun, 19 Jan 2014 16:49:11 +0000 (17:49 +0100)
committerAlexander Graf <agraf@suse.de>
Mon, 16 Jun 2014 11:24:35 +0000 (13:24 +0200)
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>
target-ppc/cpu.h
target-ppc/translate_init.c

index f36c90b..b035e91 100644 (file)
@@ -1716,6 +1716,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
 /* External Input Interrupt Directed to Guest State */
 #define EPCR_EXTGS            (1 << 31)
 
+#define   L1CSR0_CPE           0x00010000      /* Data Cache Parity Enable */
+#define   L1CSR0_CUL           0x00000400      /* (D-)Cache Unable to Lock */
+#define   L1CSR0_DCLFR         0x00000100      /* D-Cache Lock Flash Reset */
+#define   L1CSR0_DCFI          0x00000002      /* Data Cache Flash Invalidate */
+#define   L1CSR0_DCE           0x00000001      /* Data Cache Enable */
+
+#define   L1CSR1_CPE           0x00010000      /* Instruction Cache Parity Enable */
+#define   L1CSR1_ICUL          0x00000400      /* I-Cache Unable to Lock */
+#define   L1CSR1_ICLFR         0x00000100      /* I-Cache Lock Flash Reset */
+#define   L1CSR1_ICFI          0x00000002      /* Instruction Cache Flash Invalidate */
+#define   L1CSR1_ICE           0x00000001      /* Instruction Cache Enable */
+
 /*****************************************************************************/
 /* PowerPC Instructions types definitions                                    */
 enum {
index fc9d932..0f9dec7 100644 (file)
@@ -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,