Patchwork [5/8] target-sh4: MMU: optimize UTLB accesses

login
register
mail settings
Submitter Aurelien Jarno
Date Feb. 6, 2010, 4:43 p.m.
Message ID <1265474623-23367-6-git-send-email-aurelien@aurel32.net>
Download mbox | patch
Permalink /patch/44714/
State New
Headers show

Comments

Aurelien Jarno - Feb. 6, 2010, 4:43 p.m.
With the current code, the QEMU TLB is setup to match the read/write
mode of the MMU fault. This means when read access is done, the page
is setup in read-only mode. When the page is later accessed in write
mode, an MMU fault happened, and the page is switch in write-only
mode. This flip-flop causes a lot of calls to the MMU code and slow
down the emulation.

This patch changes the MMU emulation, so that the QEMU TLB is setup
to match the UTLB protection key. This impressively increase the
speed of the emulation.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-sh4/helper.c |   38 ++++++++++++++------------------------
 1 files changed, 14 insertions(+), 24 deletions(-)

Patch

diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 589efe4..2d00dfa 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -386,38 +386,28 @@  static int get_mmu_address(CPUState * env, target_ulong * physical,
 	n = find_utlb_entry(env, address, use_asid);
 	if (n >= 0) {
 	    matching = &env->utlb[n];
-	    switch ((matching->pr << 1) | ((env->sr & SR_MD) ? 1 : 0)) {
-	    case 0:		/* 000 */
-	    case 2:		/* 010 */
-		n = (rw == 1) ? MMU_DTLB_VIOLATION_WRITE :
-		    MMU_DTLB_VIOLATION_READ;
-		break;
-	    case 1:		/* 001 */
-	    case 4:		/* 100 */
-	    case 5:		/* 101 */
-		if (rw == 1)
-		    n = MMU_DTLB_VIOLATION_WRITE;
-		else
-		    *prot = PAGE_READ;
-		break;
-	    case 3:		/* 011 */
-	    case 6:		/* 110 */
-	    case 7:		/* 111 */
-		*prot = (rw == 1)? PAGE_WRITE : PAGE_READ;
-		break;
-	    }
+            if (!(env->sr & SR_MD) && !(matching->pr & 2)) {
+                n = (rw == 1) ? MMU_DTLB_VIOLATION_WRITE :
+                    MMU_DTLB_VIOLATION_READ;
+            } else if ((rw == 1) && !(matching->pr & 1)) {
+                n = MMU_DTLB_VIOLATION_WRITE;
+            } else if ((rw == 1) & !matching->d) {
+                n = MMU_DTLB_INITIAL_WRITE;
+            } else {
+                *prot = PAGE_READ;
+                if ((matching->pr & 1) && matching->d) {
+                    *prot |= PAGE_WRITE;
+                }
+            }
 	} else if (n == MMU_DTLB_MISS) {
 	    n = (rw == 1) ? MMU_DTLB_MISS_WRITE :
 		MMU_DTLB_MISS_READ;
 	}
     }
     if (n >= 0) {
+	n = MMU_OK;
 	*physical = ((matching->ppn << 10) & ~(matching->size - 1)) |
 	    (address & (matching->size - 1));
-	if ((rw == 1) & !matching->d)
-	    n = MMU_DTLB_INITIAL_WRITE;
-	else
-	    n = MMU_OK;
     }
     return n;
 }