qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Aurelien Jarno <aurelien@aurel32.net>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH][MIPS] MMU code improvements
Date: Sat, 12 May 2007 16:45:02 +0200	[thread overview]
Message-ID: <20070512144502.GA19249@amd64.aurel32.net> (raw)

Hi all,

Please find below a patch to improve the MMU code on the MIPS target.

It fixes map_address() invalidate_tlb() and do_tlbp() for page sizes 
greater than 4kB. The VPN contained in a TLB should be masked with the
page mask of the same TLB as the VPN value may not be aligned. This is
explicitely required at least for tlbp in the MIPS64 PRA manual.

It also replace a few hardcoded values corresponding to the minimum
page size of 4kB by the size of a QEMU page (using TARGET_PAGE_MASK).
It should help to add 1kB pages support.

The other parts are cosmetic fixes.

Cheers,
Aurelien


Index: target-mips/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.37
diff -u -d -p -r1.37 helper.c
--- target-mips/helper.c	9 May 2007 09:34:30 -0000	1.37
+++ target-mips/helper.c	12 May 2007 13:46:50 -0000
@@ -47,15 +47,14 @@ static int map_address (CPUState *env, t
     for (i = 0; i < env->tlb_in_use; i++) {
         tlb_t *tlb = &env->tlb[i];
         /* 1k pages are not supported. */
-        target_ulong mask = tlb->PageMask | 0x1FFF;
+        target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
         target_ulong tag = address & ~mask;
-        int n;
+        target_ulong VPN = tlb->VPN & ~mask;
 
         /* Check ASID, virtual page number & size */
-        if ((tlb->G == 1 || tlb->ASID == ASID) &&
-            tlb->VPN == tag) {
+        if ((tlb->G == 1 || tlb->ASID == ASID) && VPN == tag) {
             /* TLB match */
-            n = !!(address & mask & ~(mask >> 1));
+            int n = !!(address & mask & ~(mask >> 1));
             /* Check access rights */
            if (!(n ? tlb->V1 : tlb->V0))
                 return TLBRET_INVALID;
@@ -492,7 +491,7 @@ void invalidate_tlb (CPUState *env, int 
     target_ulong mask;
 
     tlb = &env->tlb[idx];
-    /* The qemu TLB is flushed then the ASID changes, so no need to
+    /* The qemu TLB is flushed when the ASID changes, so no need to
        flush these entries again.  */
     if (tlb->G == 0 && tlb->ASID != ASID) {
         return;
@@ -508,9 +507,9 @@ void invalidate_tlb (CPUState *env, int 
     }
 
     /* 1k pages are not supported. */
-    mask = tlb->PageMask | 0x1FFF;
+    mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
     if (tlb->V0) {
-        addr = tlb->VPN;
+        addr = tlb->VPN & ~mask;
         end = addr | (mask >> 1);
         while (addr < end) {
             tlb_flush_page (env, addr);
@@ -518,8 +517,7 @@ void invalidate_tlb (CPUState *env, int 
         }
     }
     if (tlb->V1) {
-        addr = tlb->VPN | ((mask >> 1) + 1);
-        addr = tlb->VPN + TARGET_PAGE_SIZE;
+        addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
         end = addr | mask;
         while (addr < end) {
             tlb_flush_page (env, addr);
Index: target-mips/op.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op.c,v
retrieving revision 1.49
diff -u -d -p -r1.49 op.c
--- target-mips/op.c	11 May 2007 17:08:26 -0000	1.49
+++ target-mips/op.c	12 May 2007 13:46:50 -0000
@@ -1283,7 +1283,7 @@ void op_mtc0_context (void)
 void op_mtc0_pagemask (void)
 {
     /* 1k pages not implemented */
-    env->CP0_PageMask = T0 & 0x1FFFE000;
+    env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
     RETURN();
 }
 
Index: target-mips/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op_helper.c,v
retrieving revision 1.42
diff -u -d -p -r1.42 op_helper.c
--- target-mips/op_helper.c	17 Apr 2007 15:26:47 -0000	1.42
+++ target-mips/op_helper.c	12 May 2007 13:46:50 -0000
@@ -411,7 +411,7 @@ static void fill_tlb (int idx)
 
     /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
     tlb = &env->tlb[idx];
-    tlb->VPN = env->CP0_EntryHi & ~(target_ulong)0x1FFF;
+    tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
     tlb->ASID = env->CP0_EntryHi & 0xFF;
     tlb->PageMask = env->CP0_PageMask;
     tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
@@ -447,16 +447,18 @@ void do_tlbwr (void)
 void do_tlbp (void)
 {
     tlb_t *tlb;
-    target_ulong tag;
     uint8_t ASID;
     int i;
 
-    tag = env->CP0_EntryHi & (int32_t)0xFFFFE000;
     ASID = env->CP0_EntryHi & 0xFF;
     for (i = 0; i < env->nb_tlb; i++) {
         tlb = &env->tlb[i];
+        /* 1k pages are not supported. */
+        target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
+        target_ulong tag = env->CP0_EntryHi & ~mask;
+        target_ulong VPN = tlb->VPN & ~mask;
         /* Check ASID, virtual page number & size */
-        if ((tlb->G == 1 || tlb->ASID == ASID) && tlb->VPN == tag) {
+        if ((tlb->G == 1 || tlb->ASID == ASID) && VPN == tag) {
             /* TLB match */
             env->CP0_Index = i;
             break;
@@ -467,8 +469,12 @@ void do_tlbp (void)
         for (i = env->nb_tlb; i < env->tlb_in_use; i++) {
 	    tlb = &env->tlb[i];
 
+	    /* 1k pages are not supported. */
+	    target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
+	    target_ulong tag = env->CP0_EntryHi & ~mask;
+	    target_ulong VPN = tlb->VPN & ~mask;
 	    /* Check ASID, virtual page number & size */
-	    if ((tlb->G == 1 || tlb->ASID == ASID) && tlb->VPN == tag) {
+	    if ((tlb->G == 1 || tlb->ASID == ASID) && VPN == tag) {
                 mips_tlb_flush_extra (env, i);
 	        break;
 	    }

-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net

                 reply	other threads:[~2007-05-12 14:52 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070512144502.GA19249@amd64.aurel32.net \
    --to=aurelien@aurel32.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).