Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc/sparc If TLB entries need to be flushed, make...



details:   https://anonhg.NetBSD.org/src/rev/644751c612f7
branches:  trunk
changeset: 473107:644751c612f7
user:      pk <pk%NetBSD.org@localhost>
date:      Thu May 20 10:03:12 1999 +0000

description:
If TLB entries need to be flushed, make sure to do this after any necessary
cache flushes, since on VIPT machines the cache flush may induce a TLB load.

diffstat:

 sys/arch/sparc/sparc/pmap.c |  112 ++++++++++++++++++++++++++-----------------
 1 files changed, 67 insertions(+), 45 deletions(-)

diffs (truncated from 332 to 300 lines):

diff -r 8eebbaca5fd2 -r 644751c612f7 sys/arch/sparc/sparc/pmap.c
--- a/sys/arch/sparc/sparc/pmap.c       Thu May 20 09:52:35 1999 +0000
+++ b/sys/arch/sparc/sparc/pmap.c       Thu May 20 10:03:12 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.144 1999/05/16 16:48:59 pk Exp $ */
+/*     $NetBSD: pmap.c,v 1.145 1999/05/20 10:03:12 pk Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -524,7 +524,7 @@
  * Macros which implement SRMMU TLB flushing/invalidation
  */
 #define tlb_flush_page(va)    \
-       sta(((va) & ~0xfff) | ASI_SRMMUFP_L3, ASI_SRMMUFP, 0)
+       sta(((vaddr_t)(va) & ~0xfff) | ASI_SRMMUFP_L3, ASI_SRMMUFP, 0)
 
 #define tlb_flush_segment(vr, vs) \
        sta(((vr)<<RGSHIFT) | ((vs)<<SGSHIFT) | ASI_SRMMUFP_L2, ASI_SRMMUFP,0)
@@ -628,6 +628,7 @@
 #endif
 }
 
+
 /*
  * Set the page table entry for va to pte. Only affects software MMU page-
  * tables (the in-core pagetables read by the MMU). Ignores TLB, and
@@ -1715,10 +1716,16 @@
 if (pm == pmap_kernel())
 printf("mmu_pagein: kernel wants map at va 0x%x, vr %d, vs %d\n", va, vr, vs);
 #endif
+#if 0
+#if defined(SUN4_MMU3L)
+printf("mmu_pagein: pm=%p, va 0x%x, vr %d, vs %d, rp=%p, segmap=%p\n", pm, va, vr, vs, rp, rp->rg_segmap);
+#endif
+#endif
 
        /* return 0 if we have no PMEGs to load */
        if (rp->rg_segmap == NULL)
                return (0);
+
 #if defined(SUN4_MMU3L)
        if (HASSUN4_MMU3L && rp->rg_smeg == reginval) {
                smeg_t smeg;
@@ -2472,8 +2479,13 @@
                        flags |= MR4M(tpte);
 
                        if (pm->pm_ctx && (tpte & SRMMU_PG_M)) {
-                               cache_flush_page(va); /* XXX: do we need this?*/
-                               tlb_flush_page(va); /* paranoid? */
+                               /* Only do this for write-back caches? */
+                               cache_flush_page(va);
+                               /*
+                                * VIPT caches might use the TLB when
+                                * flushing, so we flush the TLB again.
+                                */
+                               tlb_flush_page(va);
                        }
 
                        /* Clear mod/ref bits from PTE and write it back */
@@ -2641,6 +2653,10 @@
                        if (pm->pm_ctx) {
                                setcontext(pm->pm_ctxnum);
                                cache_flush_page(pv->pv_va);
+#if defined(SUN4M)
+                               if (CPU_ISSUN4M)
+                                       tlb_flush_page(pv->pv_va);
+#endif
                        }
                        pv = pv->pv_next;
                        if (pv == NULL)
@@ -4229,7 +4245,7 @@
        }
        /* if we're done with a region, leave it wired */
 }
-#endif /* sun4m */
+#endif /* SUN4M */
 /*
  * Just like pmap_rmk_magic, but we have a different threshold.
  * Note that this may well deserve further tuning work.
@@ -4459,9 +4475,6 @@
        for (; va < endva; va += NBPG) {
                int tpte;
 
-               if (pm->pm_ctx)
-                       tlb_flush_page(va);
-
                tpte = pte0[VA_SUN4M_VPG(va)];
 
                if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) {
@@ -4492,6 +4505,9 @@
                        panic("pmap_rmu: too many PTEs in segment; "
                              "va 0x%lx; endva 0x%lx", va, endva);
 #endif
+               if (pm->pm_ctx)
+                       tlb_flush_page(va);
+
                setpgt4m(&pte0[VA_SUN4M_VPG(va)], SRMMU_TEINVALID);
        }
 
@@ -5072,8 +5088,8 @@
        vaddr_t sva, eva;
        vm_prot_t prot;
 {
-       int va, nva, vr, vs;
-       int s, ctx;
+       vaddr_t va, nva;
+       int s, ctx, vr, vs;
        struct regmap *rp;
        struct segmap *sp;
 
@@ -5085,6 +5101,13 @@
                return;
        }
 
+#ifdef DEBUG
+       if (pmapdebug & PDB_CHANGEPROT)
+               printf("pmap_protect[curpid %d, ctx %d](%lx, %lx, %x)\n",
+                       curproc==NULL ? -1 : curproc->p_pid,
+                       pm->pm_ctx ? pm->pm_ctxnum : -1, sva, eva, prot);
+#endif
+
        write_user_windows();
        ctx = getcontext4m();
        s = splpmap();
@@ -5116,7 +5139,9 @@
                if (sp->sg_pte == NULL)
                        panic("pmap_protect: no pages");
 #endif
-               /* pages loaded: take away write bits from MMU PTEs */
+               /*
+                * pages loaded: take away write bits from MMU PTEs
+                */
                if (pm->pm_ctx)
                        setcontext4m(pm->pm_ctxnum);
 
@@ -5124,11 +5149,6 @@
                for (; va < nva; va += NBPG) {
                        int tpte;
 
-                       if (pm->pm_ctx) {
-                               /* Flush TLB entry */
-                               tlb_flush_page(va);
-                       }
-
                        tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
                        /*
                         * Flush cache so that any existing cache
@@ -5140,6 +5160,8 @@
                                pmap_stats.ps_npg_prot_actual++;
                                if (pm->pm_ctx) {
                                        cache_flush_page(va);
+                                       /* Flush TLB entry */
+                                       tlb_flush_page(va);
                                }
                                setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)],
                                         tpte & ~PPROT_WRITE);
@@ -5188,14 +5210,7 @@
        rp = &pm->pm_regmap[VA_VREG(va)];
        sp = &rp->rg_segmap[VA_VSEG(va)];
 
-       ctx = getcontext4m();
-       if (pm->pm_ctx) {
-               /* Flush TLB entry */
-               setcontext4m(pm->pm_ctxnum);
-               tlb_flush_page(va);
-       }
        pte = sp->sg_pte[VA_SUN4M_VPG(va)];
-
        if ((pte & SRMMU_PROT_MASK) == newprot) {
                /* only wiring changed, and we ignore wiring */
                pmap_stats.ps_useless_changeprots++;
@@ -5208,18 +5223,24 @@
                 * Flush cache if page has been referenced to
                 * avoid stale protection bits in the cache tags.
                 */
+
+               ctx = getcontext4m();
+               setcontext4m(pm->pm_ctxnum);
                if ((pte & (SRMMU_PG_C|SRMMU_PGTYPE)) ==
                    (SRMMU_PG_C|PG_SUN4M_OBMEM))
                        cache_flush_page(va);
+
+               tlb_flush_page(va);
+               setcontext4m(ctx);
        }
 
        setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)],
                 (pte & ~SRMMU_PROT_MASK) | newprot);
+
 out:
-       setcontext4m(ctx);
        splx(s);
 }
-#endif /* 4m */
+#endif /* SUN4M */
 
 /*
  * Insert (MI) physical page pa at virtual address va in the given pmap.
@@ -5473,6 +5494,7 @@
                rp->rg_nsegmap = 0;
                for (i = NSEGRG; --i >= 0;)
                        sp++->sg_pmeg = seginval;
+
 #if defined(SUN4_MMU3L)
 /*
  * XXX - preallocate the region MMU cookies.
@@ -5640,8 +5662,11 @@
 
 #ifdef DEBUG
        if (pmapdebug & PDB_ENTER)
-               printf("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
-                   pm, va, pa, prot, wired);
+               printf("pmap_enter[curpid %d, ctx %d]"
+                       "(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
+                       curproc==NULL ? -1 : curproc->p_pid,
+                       pm->pm_ctx==NULL ? -1 : pm->pm_ctxnum,
+                       pm, va, pa, prot, wired);
 #endif
 
        /* Initialise pteproto with cache bit */
@@ -5928,7 +5953,7 @@
 
        splx(s);
 }
-#endif /* sun4m */
+#endif /* SUN4M */
 
 /*
  * Change the wiring attribute for a map/virtual-address pair.
@@ -6045,7 +6070,7 @@
        if ((rm = pm->pm_regmap) == NULL) {
 #ifdef DEBUG
                if (pmapdebug & PDB_FOLLOW)
-                       printf("pmap_extract: no regmap entry");
+                       printf("pmap_extract: no regmap entry\n");
 #endif
                return (0);
        }
@@ -6054,7 +6079,7 @@
        if ((sm = rm->rg_segmap) == NULL) {
 #ifdef DEBUG
                if (pmapdebug & PDB_FOLLOW)
-                       panic("pmap_extract: no segmap");
+                       printf("pmap_extract: no segmap\n");
 #endif
                return (0);
        }
@@ -6063,7 +6088,7 @@
        if (sm->sg_pte == NULL) {
 #ifdef DEBUG
                if (pmapdebug & PDB_FOLLOW)
-                       panic("pmap_extract: no ptes");
+                       printf("pmap_extract: no ptes\n");
 #endif
                return (0);
        }
@@ -6410,7 +6435,7 @@
        setpte4(sva, spte);
        setpte4(dva, dpte);
        qcopy(sva, dva, NBPG);  /* loads cache, so we must ... */
-       cache_flush_page((int)sva);
+       cache_flush_page((vaddr_t)sva);
        setpte4(sva, 0);
        setpte4(dva, 0);
 }
@@ -6423,6 +6448,7 @@
  * We avoid stomping on the cache.
  * XXX might be faster to use destination's context and allow cache to fill?
  */
+int xxxdebug = 0;
 void
 pmap_zero_page4m(pa)
        paddr_t pa;
@@ -6439,18 +6465,15 @@
                if (CACHEINFO.c_vactype != VAC_NONE)
                        pv_flushcache(pvhead(pa));
        }
-       pte = (SRMMU_TEPTE | PPROT_S | PPROT_WRITE |
-              (atop(pa) << SRMMU_PPNSHIFT));
+       pte = SRMMU_TEPTE | PPROT_N_RWX | (atop(pa) << SRMMU_PPNSHIFT);
        if (cpuinfo.flags & CPUFLG_CACHE_MANDATORY)
                pte |= SRMMU_PG_C;
-       else
-               pte &= ~SRMMU_PG_C;
 
        va = vpage[0];
        setpgt4m(vpage_pte[0], pte);
        qzero(va, NBPG);
        /* Remove temporary mapping */
-       tlb_flush_page((int)va);
+       tlb_flush_page(va);
        setpgt4m(vpage_pte[0], SRMMU_TEINVALID);
 }
 
@@ -6474,7 +6497,8 @@
                if (CACHEINFO.c_vactype == VAC_WRITEBACK)
                        pv_flushcache(pvhead(src));
        }
-       spte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_S |
+



Home | Main Index | Thread Index | Old Index