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