]> xenbits.xensource.com Git - qemu-xen-4.2-testing.git/commitdiff
Avoid op helpers that would just call helpers for TLB & SLB management:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 1 Oct 2007 01:51:12 +0000 (01:51 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 1 Oct 2007 01:51:12 +0000 (01:51 +0000)
  call the helpers directly from the micro-ops.
Avoid duplicated code for tlbsx. implementation.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3302 c046a42c-6fe2-441c-8c8c-71466251a162

target-ppc/cpu.h
target-ppc/exec.h
target-ppc/helper.c
target-ppc/op.c
target-ppc/op_helper.c
target-ppc/translate.c

index 5d0a86be2cef2ac477d0d93e315f6fc8ff5c17d2..c4ae414413c80bdbc6b94b02c4b592b9d1656713 100644 (file)
@@ -656,6 +656,11 @@ void store_40x_sler (CPUPPCState *env, uint32_t val);
 void store_booke_tcr (CPUPPCState *env, target_ulong val);
 void store_booke_tsr (CPUPPCState *env, target_ulong val);
 void ppc_tlb_invalidate_all (CPUPPCState *env);
+void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr);
+#if defined(TARGET_PPC64)
+void ppc_slb_invalidate_all (CPUPPCState *env);
+void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0);
+#endif
 int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid);
 #endif
 #endif
index 10a51e93cb976672c9ade902363d7b51716534fe..8a5425827166339044041cbc02403b4892c2c5b4 100644 (file)
@@ -100,14 +100,8 @@ void do_raise_exception (uint32_t exception);
 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
                           int rw, int access_type, int check_BATs);
 
-void ppc6xx_tlb_invalidate_all (CPUState *env);
-void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
-                                 int is_code);
 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
                        target_ulong pte0, target_ulong pte1);
-void ppc4xx_tlb_invalidate_all (CPUState *env);
-void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
-                                 uint32_t pid);
 
 static inline void env_to_regs (void)
 {
index 3e6fb48cd6d69483dcc9f58a0d95ab3344bec5cf..66dc7b22a8b72a94e1b741ffb5758defb75509ce 100644 (file)
@@ -237,7 +237,7 @@ static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
     return nr;
 }
 
-void ppc6xx_tlb_invalidate_all (CPUState *env)
+static void ppc6xx_tlb_invalidate_all (CPUState *env)
 {
     ppc6xx_tlb_t *tlb;
     int nr, max;
@@ -253,14 +253,9 @@ void ppc6xx_tlb_invalidate_all (CPUState *env)
         max *= 2;
     for (nr = 0; nr < max; nr++) {
         tlb = &env->tlb[nr].tlb6;
-#if !defined(FLUSH_ALL_TLBS)
-        tlb_flush_page(env, tlb->EPN);
-#endif
         pte_invalidate(&tlb->pte0);
     }
-#if defined(FLUSH_ALL_TLBS)
     tlb_flush(env, 1);
-#endif
 }
 
 static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
@@ -292,8 +287,8 @@ static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
 #endif
 }
 
-void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
-                                 int is_code)
+static void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
+                                        int is_code)
 {
     __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
 }
@@ -834,11 +829,13 @@ static int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb,
         return -1;
     }
     mask = ~(tlb->size - 1);
+#if defined (DEBUG_SOFTWARE_TLB)
     if (loglevel != 0) {
         fprintf(logfile, "%s: TLB %d address " ADDRX " PID %d <=> "
                 ADDRX " " ADDRX " %d\n",
                 __func__, i, address, pid, tlb->EPN, mask, (int)tlb->PID);
     }
+#endif
     /* Check PID */
     if (tlb->PID != 0 && tlb->PID != pid)
         return -1;
@@ -876,44 +873,41 @@ int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
     return ret;
 }
 
-void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
-                                 uint32_t pid)
+/* Helpers specific to PowerPC 40x implementations */
+static void ppc4xx_tlb_invalidate_all (CPUState *env)
 {
     ppcemb_tlb_t *tlb;
-    target_phys_addr_t raddr;
-    target_ulong page, end;
     int i;
 
     for (i = 0; i < env->nb_tlb; i++) {
         tlb = &env->tlb[i].tlbe;
-        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
-            end = tlb->EPN + tlb->size;
-            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
-                tlb_flush_page(env, page);
-            tlb->prot &= ~PAGE_VALID;
-            break;
-        }
+        tlb->prot &= ~PAGE_VALID;
     }
+    tlb_flush(env, 1);
 }
 
-/* Helpers specific to PowerPC 40x implementations */
-void ppc4xx_tlb_invalidate_all (CPUState *env)
+static void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
+                                        uint32_t pid)
 {
+#if !defined(FLUSH_ALL_TLBS)
     ppcemb_tlb_t *tlb;
+    target_phys_addr_t raddr;
+    target_ulong page, end;
     int i;
 
     for (i = 0; i < env->nb_tlb; i++) {
         tlb = &env->tlb[i].tlbe;
-        if (tlb->prot & PAGE_VALID) {
-#if 0 // XXX: TLB have variable sizes then we flush all Qemu TLB.
+        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
             end = tlb->EPN + tlb->size;
             for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
                 tlb_flush_page(env, page);
-#endif
             tlb->prot &= ~PAGE_VALID;
+            break;
         }
     }
-    tlb_flush(env, 1);
+#else
+    ppc4xx_tlb_invalidate_all(env);
+#endif
 }
 
 int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
@@ -932,10 +926,12 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
             continue;
         zsel = (tlb->attr >> 4) & 0xF;
         zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
+#if defined (DEBUG_SOFTWARE_TLB)
         if (loglevel != 0) {
             fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
                     __func__, i, zsel, zpr, rw, tlb->attr);
         }
+#endif
         if (access_type == ACCESS_CODE) {
             /* Check execute enable bit */
             switch (zpr) {
@@ -1009,19 +1005,23 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
         }
         if (ret >= 0) {
             ctx->raddr = raddr;
+#if defined (DEBUG_SOFTWARE_TLB)
             if (loglevel != 0) {
                 fprintf(logfile, "%s: access granted " ADDRX " => " REGX
                         " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
                         ret);
             }
+#endif
             return 0;
         }
     }
+#if defined (DEBUG_SOFTWARE_TLB)
     if (loglevel != 0) {
         fprintf(logfile, "%s: access refused " ADDRX " => " REGX
                 " %d %d\n", __func__, address, raddr, ctx->prot,
                 ret);
     }
+#endif
 
     return ret;
 }
@@ -1569,15 +1569,77 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
 /* TLB management */
 void ppc_tlb_invalidate_all (CPUPPCState *env)
 {
-    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
+    switch (env->mmu_model) {
+    case POWERPC_MMU_SOFT_6xx:
         ppc6xx_tlb_invalidate_all(env);
-    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
+        break;
+    case POWERPC_MMU_SOFT_4xx:
+    case POWERPC_MMU_SOFT_4xx_Z:
         ppc4xx_tlb_invalidate_all(env);
-    } else {
+        break;
+    default:
         tlb_flush(env, 1);
+        break;
+    }
+}
+
+void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
+{
+#if !defined(FLUSH_ALL_TLBS)
+    addr &= TARGET_PAGE_MASK;
+    switch (env->mmu_model) {
+    case POWERPC_MMU_SOFT_6xx:
+        ppc6xx_tlb_invalidate_virt(env, addr, 0);
+        if (env->id_tlbs == 1)
+            ppc6xx_tlb_invalidate_virt(env, addr, 1);
+        break;
+    case POWERPC_MMU_SOFT_4xx:
+    case POWERPC_MMU_SOFT_4xx_Z:
+        ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
+        break;
+    default:
+        /* tlbie invalidate TLBs for all segments */
+        addr &= ~((target_ulong)-1 << 28);
+        /* XXX: this case should be optimized,
+         * giving a mask to tlb_flush_page
+         */
+        tlb_flush_page(env, addr | (0x0 << 28));
+        tlb_flush_page(env, addr | (0x1 << 28));
+        tlb_flush_page(env, addr | (0x2 << 28));
+        tlb_flush_page(env, addr | (0x3 << 28));
+        tlb_flush_page(env, addr | (0x4 << 28));
+        tlb_flush_page(env, addr | (0x5 << 28));
+        tlb_flush_page(env, addr | (0x6 << 28));
+        tlb_flush_page(env, addr | (0x7 << 28));
+        tlb_flush_page(env, addr | (0x8 << 28));
+        tlb_flush_page(env, addr | (0x9 << 28));
+        tlb_flush_page(env, addr | (0xA << 28));
+        tlb_flush_page(env, addr | (0xB << 28));
+        tlb_flush_page(env, addr | (0xC << 28));
+        tlb_flush_page(env, addr | (0xD << 28));
+        tlb_flush_page(env, addr | (0xE << 28));
+        tlb_flush_page(env, addr | (0xF << 28));
     }
+#else
+    ppc_tlb_invalidate_all(env);
+#endif
 }
 
+#if defined(TARGET_PPC64)
+void ppc_slb_invalidate_all (CPUPPCState *env)
+{
+    /* XXX: TODO */
+    tlb_flush(env, 1);
+}
+
+void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
+{
+    /* XXX: TODO */
+    tlb_flush(env, 1);
+}
+#endif
+
+
 /*****************************************************************************/
 /* Special registers manipulation */
 #if defined(TARGET_PPC64)
index 8f0f11a66f50ac49237f969046f052e523104861..6ad68eabaabc63d930239072fcce998a5f0290d9 100644 (file)
@@ -1985,21 +1985,21 @@ void OPPROTO op_td (void)
 /* tlbia */
 void OPPROTO op_tlbia (void)
 {
-    do_tlbia();
+    ppc_tlb_invalidate_all(env);
     RETURN();
 }
 
 /* tlbie */
 void OPPROTO op_tlbie (void)
 {
-    do_tlbie();
+    ppc_tlb_invalidate_one(env, (uint32_t)T0);
     RETURN();
 }
 
 #if defined(TARGET_PPC64)
 void OPPROTO op_tlbie_64 (void)
 {
-    do_tlbie_64();
+    ppc_tlb_invalidate_one(env, T0);
     RETURN();
 }
 #endif
@@ -2007,13 +2007,19 @@ void OPPROTO op_tlbie_64 (void)
 #if defined(TARGET_PPC64)
 void OPPROTO op_slbia (void)
 {
-    do_slbia();
+    ppc_slb_invalidate_all(env);
     RETURN();
 }
 
 void OPPROTO op_slbie (void)
 {
-    do_slbie();
+    ppc_slb_invalidate_one(env, (uint32_t)T0);
+    RETURN();
+}
+
+void OPPROTO op_slbie_64 (void)
+{
+    ppc_slb_invalidate_one(env, T0);
     RETURN();
 }
 #endif
@@ -2487,13 +2493,18 @@ void OPPROTO op_440_tlbre (void)
 
 void OPPROTO op_440_tlbsx (void)
 {
-    do_440_tlbsx();
+    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
     RETURN();
 }
 
-void OPPROTO op_440_tlbsx_ (void)
+void OPPROTO op_4xx_tlbsx_check (void)
 {
-    do_440_tlbsx_();
+    int tmp;
+
+    tmp = xer_so;
+    if (T0 != -1)
+        tmp |= 0x02;
+    env->crf[0] = tmp;
     RETURN();
 }
 
@@ -2517,13 +2528,7 @@ void OPPROTO op_4xx_tlbre_hi (void)
 
 void OPPROTO op_4xx_tlbsx (void)
 {
-    do_4xx_tlbsx();
-    RETURN();
-}
-
-void OPPROTO op_4xx_tlbsx_ (void)
-{
-    do_4xx_tlbsx_();
+    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
     RETURN();
 }
 
index 5223b1543ffea4b4c0150e858853f83dbdfb7259..a7c81776fdfc7733043768658872b8eafceefdda 100644 (file)
@@ -36,7 +36,6 @@
 //#define DEBUG_OP
 //#define DEBUG_EXCEPTIONS
 //#define DEBUG_SOFTWARE_TLB
-//#define FLUSH_ALL_TLBS
 
 /*****************************************************************************/
 /* Exceptions processing helpers */
@@ -2336,118 +2335,6 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
     env = saved_env;
 }
 
-/* TLB invalidation helpers */
-void do_tlbia (void)
-{
-    ppc_tlb_invalidate_all(env);
-}
-
-void do_tlbie (void)
-{
-    T0 = (uint32_t)T0;
-#if !defined(FLUSH_ALL_TLBS)
-    /* XXX: Remove thoses tests */
-    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
-        ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
-        if (env->id_tlbs == 1)
-            ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
-    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
-        ppc4xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
-                                   env->spr[SPR_40x_PID]);
-    } else {
-        /* tlbie invalidate TLBs for all segments */
-        T0 &= TARGET_PAGE_MASK;
-        T0 &= ~((target_ulong)-1 << 28);
-        /* XXX: this case should be optimized,
-         * giving a mask to tlb_flush_page
-         */
-        tlb_flush_page(env, T0 | (0x0 << 28));
-        tlb_flush_page(env, T0 | (0x1 << 28));
-        tlb_flush_page(env, T0 | (0x2 << 28));
-        tlb_flush_page(env, T0 | (0x3 << 28));
-        tlb_flush_page(env, T0 | (0x4 << 28));
-        tlb_flush_page(env, T0 | (0x5 << 28));
-        tlb_flush_page(env, T0 | (0x6 << 28));
-        tlb_flush_page(env, T0 | (0x7 << 28));
-        tlb_flush_page(env, T0 | (0x8 << 28));
-        tlb_flush_page(env, T0 | (0x9 << 28));
-        tlb_flush_page(env, T0 | (0xA << 28));
-        tlb_flush_page(env, T0 | (0xB << 28));
-        tlb_flush_page(env, T0 | (0xC << 28));
-        tlb_flush_page(env, T0 | (0xD << 28));
-        tlb_flush_page(env, T0 | (0xE << 28));
-        tlb_flush_page(env, T0 | (0xF << 28));
-    }
-#else
-    do_tlbia();
-#endif
-}
-
-#if defined(TARGET_PPC64)
-void do_tlbie_64 (void)
-{
-    T0 = (uint64_t)T0;
-#if !defined(FLUSH_ALL_TLBS)
-    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
-        ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
-        if (env->id_tlbs == 1)
-            ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
-    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
-        /* XXX: TODO */
-#if 0
-        ppcbooke_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
-                                     env->spr[SPR_BOOKE_PID]);
-#endif
-    } else {
-        /* tlbie invalidate TLBs for all segments
-         * As we have 2^36 segments, invalidate all qemu TLBs
-         */
-#if 0
-        T0 &= TARGET_PAGE_MASK;
-        T0 &= ~((target_ulong)-1 << 28);
-        /* XXX: this case should be optimized,
-         * giving a mask to tlb_flush_page
-         */
-        tlb_flush_page(env, T0 | (0x0 << 28));
-        tlb_flush_page(env, T0 | (0x1 << 28));
-        tlb_flush_page(env, T0 | (0x2 << 28));
-        tlb_flush_page(env, T0 | (0x3 << 28));
-        tlb_flush_page(env, T0 | (0x4 << 28));
-        tlb_flush_page(env, T0 | (0x5 << 28));
-        tlb_flush_page(env, T0 | (0x6 << 28));
-        tlb_flush_page(env, T0 | (0x7 << 28));
-        tlb_flush_page(env, T0 | (0x8 << 28));
-        tlb_flush_page(env, T0 | (0x9 << 28));
-        tlb_flush_page(env, T0 | (0xA << 28));
-        tlb_flush_page(env, T0 | (0xB << 28));
-        tlb_flush_page(env, T0 | (0xC << 28));
-        tlb_flush_page(env, T0 | (0xD << 28));
-        tlb_flush_page(env, T0 | (0xE << 28));
-        tlb_flush_page(env, T0 | (0xF << 28));
-#else
-        tlb_flush(env, 1);
-#endif
-    }
-#else
-    do_tlbia();
-#endif
-}
-#endif
-
-#if defined(TARGET_PPC64)
-void do_slbia (void)
-{
-    /* XXX: TODO */
-    tlb_flush(env, 1);
-}
-
-void do_slbie (void)
-{
-    /* XXX: TODO */
-    tlb_flush(env, 1);
-}
-#endif
-
 /* Software driven TLBs management */
 /* PowerPC 602/603 software TLB load instructions helpers */
 void do_load_6xx_tlb (int is_code)
@@ -2575,21 +2462,6 @@ void do_4xx_tlbre_hi (void)
         T0 |= 0x100;
 }
 
-void do_4xx_tlbsx (void)
-{
-    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
-}
-
-void do_4xx_tlbsx_ (void)
-{
-    int tmp = xer_so;
-
-    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
-    if (T0 != -1)
-        tmp |= 0x02;
-    env->crf[0] = tmp;
-}
-
 void do_4xx_tlbwe_hi (void)
 {
     ppcemb_tlb_t *tlb;
@@ -2757,21 +2629,6 @@ void do_440_tlbwe (int word)
     }
 }
 
-void do_440_tlbsx (void)
-{
-    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
-}
-
-void do_440_tlbsx_ (void)
-{
-    int tmp = xer_so;
-
-    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
-    if (T0 != -1)
-        tmp |= 0x02;
-    env->crf[0] = tmp;
-}
-
 void do_440_tlbre (int word)
 {
     ppcemb_tlb_t *tlb;
index 6faf0b671774a167afe80ba78b22f94f4fdd5931..d76a92a65d65a85c443d4fc7745fabe22248975c 100644 (file)
@@ -4991,10 +4991,9 @@ GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
         return;
     }
     gen_addr_reg_index(ctx);
+    gen_op_4xx_tlbsx();
     if (Rc(ctx->opcode))
-        gen_op_4xx_tlbsx_();
-    else
-        gen_op_4xx_tlbsx();
+        gen_op_4xx_tlbsx_check();
     gen_op_store_T0_gpr(rD(ctx->opcode));
 #endif
 }
@@ -5064,10 +5063,9 @@ GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
         return;
     }
     gen_addr_reg_index(ctx);
+    gen_op_440_tlbsx();
     if (Rc(ctx->opcode))
-        gen_op_440_tlbsx_();
-    else
-        gen_op_440_tlbsx();
+        gen_op_4xx_tlbsx_check();
     gen_op_store_T0_gpr(rD(ctx->opcode));
 #endif
 }