qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 8/8] Mips improvements


From: Thiemo Seufer
Subject: [Qemu-devel] [PATCH 8/8] Mips improvements
Date: Mon, 15 May 2006 02:53:50 +0100
User-agent: Mutt/1.5.11+cvs20060403

Hello All,

this patch uses symbolic constants instead of magic numbers for the
TLB handling.


Thiemo


Index: qemu-work/target-mips/cpu.h
===================================================================
--- qemu-work.orig/target-mips/cpu.h    2006-05-15 01:32:21.000000000 +0100
+++ qemu-work/target-mips/cpu.h 2006-05-15 01:32:33.000000000 +0100
@@ -52,7 +52,7 @@
     uint32_t fcsr;
 #endif
 #if defined(MIPS_USES_R4K_TLB)
-    tlb_t tlb[16];
+    tlb_t tlb[MIPS_TLB_NB];
 #endif
     uint32_t CP0_index;
     uint32_t CP0_random;
Index: qemu-work/target-mips/helper.c
===================================================================
--- qemu-work.orig/target-mips/helper.c 2006-05-15 01:32:21.000000000 +0100
+++ qemu-work/target-mips/helper.c      2006-05-15 01:34:23.000000000 +0100
@@ -28,53 +28,56 @@
 #include "cpu.h"
 #include "exec-all.h"
 
+enum {
+    TLBRET_DIRTY = -4,
+    TLBRET_INVALID = -3,
+    TLBRET_NOMATCH = -2,
+    TLBRET_BADADDR = -1,
+    TLBRET_MATCH = 0
+};
+
 /* MIPS32 4K MMU emulation */
 #ifdef MIPS_USES_R4K_TLB
 static int map_address (CPUState *env, target_ulong *physical, int *prot,
                         target_ulong address, int rw, int access_type)
 {
+    target_ulong tag = address & (TARGET_PAGE_MASK << 1);
+    uint8_t ASID = env->CP0_EntryHi & 0xFF;
     tlb_t *tlb;
-    target_ulong tag;
-    uint8_t ASID;
     int i, n;
-    int ret;
 
-    ret = -2;
-    tag = address & 0xFFFFE000;
-    ASID = env->CP0_EntryHi & 0xFF;
     for (i = 0; i < MIPS_TLB_NB; i++) {
         tlb = &env->tlb[i];
         /* Check ASID, virtual page number & size */
         if ((tlb->G == 1 || tlb->ASID == ASID) &&
             tlb->VPN == tag && address < tlb->end2) {
             /* TLB match */
-            n = (address >> 12) & 1;
+            n = (address >> TARGET_PAGE_BITS) & 1;
             /* Check access rights */
-           if (!(n ? tlb->V1 : tlb->V0))
-                return -3;
-           if (rw == 0 || (n ? tlb->D1 : tlb->D0)) {
-                *physical = tlb->PFN[n] | (address & 0xFFF);
+           if (!(n ? tlb->V1 : tlb->V0))
+                return TLBRET_INVALID;
+           if (rw == 0 || (n ? tlb->D1 : tlb->D0)) {
+                *physical = tlb->PFN[n] | (address & ~TARGET_PAGE_MASK);
                 *prot = PAGE_READ;
                 if (n ? tlb->D1 : tlb->D0)
                     *prot |= PAGE_WRITE;
-                return 0;
+                return TLBRET_MATCH;
             }
-            return -4;
+            return TLBRET_DIRTY;
         }
     }
-
-    return ret;
+    return TLBRET_NOMATCH;
 }
 #endif
 
-int get_physical_address (CPUState *env, target_ulong *physical, int *prot,
-                          target_ulong address, int rw, int access_type)
+static int get_physical_address (CPUState *env, target_ulong *physical,
+                                int *prot, target_ulong address,
+                                int rw, int access_type)
 {
-    int user_mode;
-    int ret;
-
     /* User mode can only access useg */
-    user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
+    int user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
+    int ret = TLBRET_MATCH;
+
 #if 0
     if (logfile) {
         fprintf(logfile, "user mode %d h %08x\n",
@@ -82,8 +85,7 @@
     }
 #endif
     if (user_mode && address > 0x7FFFFFFFUL)
-        return -1;
-    ret = 0;
+        return TLBRET_BADADDR;
     if (address < 0x80000000UL) {
         if (!(env->hflags & MIPS_HFLAG_ERL)) {
 #ifdef MIPS_USES_R4K_TLB
@@ -181,7 +183,7 @@
     access_type = ACCESS_INT;
     if (env->user_mode_only) {
         /* user mode only emulation */
-        ret = -2;
+        ret = TLBRET_NOMATCH;
         goto do_fault;
     }
     ret = get_physical_address(env, &physical, &prot,
@@ -190,14 +192,15 @@
         fprintf(logfile, "%s address=%08x ret %d physical %08x prot %d\n",
                 __func__, address, ret, physical, prot);
     }
-    if (ret == 0) {
-       ret = tlb_set_page(env, address & ~0xFFF, physical & ~0xFFF, prot,
-                          is_user, is_softmmu);
+    if (ret == TLBRET_MATCH) {
+       ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
+                          physical & TARGET_PAGE_MASK, prot,
+                          is_user, is_softmmu);
     } else if (ret < 0) {
     do_fault:
         switch (ret) {
         default:
-        case -1:
+        case TLBRET_BADADDR:
             /* Reference to kernel address from user mode or supervisor mode */
             /* Reference to supervisor address from user mode */
             if (rw)
@@ -205,7 +208,7 @@
             else
                 exception = EXCP_AdEL;
             break;
-        case -2:
+        case TLBRET_NOMATCH:
             /* No TLB match for a mapped address */
             if (rw)
                 exception = EXCP_TLBS;
@@ -213,14 +216,14 @@
                 exception = EXCP_TLBL;
             error_code = 1;
             break;
-        case -3:
+        case TLBRET_INVALID:
             /* TLB match with no valid bit */
             if (rw)
                 exception = EXCP_TLBS;
             else
                 exception = EXCP_TLBL;
             break;
-        case -4:
+        case TLBRET_DIRTY:
             /* TLB match but 'D' bit is cleared */
             exception = EXCP_LTLBL;
             break;
@@ -231,7 +234,7 @@
         env->CP0_Context = (env->CP0_Context & 0xff800000) |
                           ((address >> 9) &   0x007ffff0);
         env->CP0_EntryHi =
-            (env->CP0_EntryHi & 0xFF) | (address & 0xFFFFE000);
+            (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
         env->exception_index = exception;
         env->error_code = error_code;
         ret = 1;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]