summaryrefslogtreecommitdiff
path: root/sys/arch/mips64
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-04-27 18:14:14 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-04-27 18:14:14 +0000
commite71e5b9906e8bcad4ba22106a7629600d154ba59 (patch)
treec1d5f704c28a6041eac0906662795b26998152b8 /sys/arch/mips64
parent3a581d5e76c368bf4de0ee9c6188aa3f951dd1ef (diff)
More pmap changes from the potpourri pool:
- use wm_page pg_flags pmap-reserved flags to store attributes, instead of defining a vm_page_md field. - use atomic operations to touch the above mentioned flags. - never create ptes with PG_RO and PG_M set (this was harmless anyway). - in pmap_clear_modify(), do not flush cache if the page was mapped uncached. Tested on r5k, rm5200, r10k and r12k.
Diffstat (limited to 'sys/arch/mips64')
-rw-r--r--sys/arch/mips64/include/pmap.h10
-rw-r--r--sys/arch/mips64/include/pte.h3
-rw-r--r--sys/arch/mips64/include/vmparam.h12
-rw-r--r--sys/arch/mips64/mips64/pmap.c81
4 files changed, 41 insertions, 65 deletions
diff --git a/sys/arch/mips64/include/pmap.h b/sys/arch/mips64/include/pmap.h
index 1d133c58b85..88a2a5ec9bb 100644
--- a/sys/arch/mips64/include/pmap.h
+++ b/sys/arch/mips64/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.11 2007/04/14 14:52:37 miod Exp $ */
+/* $OpenBSD: pmap.h,v 1.12 2007/04/27 18:14:11 miod Exp $ */
/*
* Copyright (c) 1987 Carnegie-Mellon University
@@ -88,10 +88,10 @@ typedef struct pmap {
/* flags for pv_entry */
-#define PV_UNCACHED 0x0001 /* Page is mapped unchached */
-#define PV_CACHED 0x0002 /* Page has been cached */
-#define PV_ATTR_MOD 0x0004
-#define PV_ATTR_REF 0x0008
+#define PV_UNCACHED PG_PMAP0 /* Page is mapped unchached */
+#define PV_CACHED PG_PMAP1 /* Page has been cached */
+#define PV_ATTR_MOD PG_PMAP2
+#define PV_ATTR_REF PG_PMAP3
#define PV_PRESERVE (PV_ATTR_MOD | PV_ATTR_REF)
extern struct pmap kernel_pmap_store;
diff --git a/sys/arch/mips64/include/pte.h b/sys/arch/mips64/include/pte.h
index 8d1a5aeaa9b..18df5afd99f 100644
--- a/sys/arch/mips64/include/pte.h
+++ b/sys/arch/mips64/include/pte.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pte.h,v 1.3 2005/08/07 07:29:44 miod Exp $ */
+/* $OpenBSD: pte.h,v 1.4 2007/04/27 18:14:11 miod Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -89,7 +89,6 @@ typedef union pt_entry {
#define PG_IOPAGE (PG_G | PG_V | PG_M | PG_UNCACHED)
#define PG_FRAME 0x3fffffc0
#define PG_SHIFT 6
-#define pfn_is_ext(x) ((x) & 0x3c000000)
#define vad_to_pfn(x) (((unsigned)(x) >> PG_SHIFT) & PG_FRAME)
#define vad_to_pfn64(x) (((quad_t)(x) >> PG_SHIFT) & PG_FRAME)
#define vad_to_vpn(x) ((int)((unsigned)(x) & PG_SVPN))
diff --git a/sys/arch/mips64/include/vmparam.h b/sys/arch/mips64/include/vmparam.h
index 274951eec2d..767a8712cf5 100644
--- a/sys/arch/mips64/include/vmparam.h
+++ b/sys/arch/mips64/include/vmparam.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmparam.h,v 1.11 2007/04/14 14:54:28 miod Exp $ */
+/* $OpenBSD: vmparam.h,v 1.12 2007/04/27 18:14:11 miod Exp $ */
/* $NetBSD: vmparam.h,v 1.5 1994/10/26 21:10:10 cgd Exp $ */
/*
@@ -123,20 +123,18 @@ typedef struct pv_entry {
struct pv_entry *pv_next; /* next pv_entry */
struct pmap *pv_pmap; /* pmap where mapping lies */
vaddr_t pv_va; /* virtual address for mapping */
- int pv_flags; /* Some flags for the mapping */
} *pv_entry_t;
#define __HAVE_VM_PAGE_MD
struct vm_page_md {
- struct pv_entry pvent; /* pv list of this seg */
+ struct pv_entry pv_ent; /* pv list of this seg */
};
#define VM_MDPAGE_INIT(pg) \
do { \
- (pg)->mdpage.pvent.pv_next = NULL; \
- (pg)->mdpage.pvent.pv_pmap = NULL; \
- (pg)->mdpage.pvent.pv_va = 0; \
- (pg)->mdpage.pvent.pv_flags = 0; \
+ (pg)->mdpage.pv_ent.pv_next = NULL; \
+ (pg)->mdpage.pv_ent.pv_pmap = NULL; \
+ (pg)->mdpage.pv_ent.pv_va = 0; \
} while (0)
#endif /* _KERNEL && !_LOCORE */
diff --git a/sys/arch/mips64/mips64/pmap.c b/sys/arch/mips64/mips64/pmap.c
index ae60392c311..afac11565f0 100644
--- a/sys/arch/mips64/mips64/pmap.c
+++ b/sys/arch/mips64/mips64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.24 2007/04/24 16:48:45 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.25 2007/04/27 18:14:13 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -251,7 +251,7 @@ static pv_entry_t pg_to_pvh(struct vm_page *);
static __inline pv_entry_t
pg_to_pvh(struct vm_page *pg)
{
- return &pg->mdpage.pvent;
+ return &pg->mdpage.pv_ent;
}
/*
@@ -454,9 +454,7 @@ pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
if (!(entry & PG_V))
continue;
pmap->pm_stats.resident_count--;
- if (!pfn_is_ext(entry)) {/* padr > 32 bits */
- pmap_remove_pv(pmap, sva, pfn_to_pad(entry));
- }
+ pmap_remove_pv(pmap, sva, pfn_to_pad(entry));
pte->pt_entry = PG_NV;
/*
* Flush the TLB for the given address.
@@ -642,21 +640,17 @@ pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
pg = PHYS_TO_VM_PAGE(pa);
if (pg != NULL) {
- pv_entry_t pv;
-
- pv = pg_to_pvh(pg);
-
if (!(prot & VM_PROT_WRITE)) {
npte = PG_ROPAGE;
} else {
- if ((int64_t)va < 0) {
+ if (pmap == pmap_kernel()) {
/*
* Don't bother to trap on kernel writes,
* just record page as dirty.
*/
npte = PG_RWPAGE;
} else {
- if (pv->pv_flags & PV_ATTR_MOD) {
+ if (pg->pg_flags & PV_ATTR_MOD) {
npte = PG_RWPAGE;
} else {
npte = PG_CWPAGE;
@@ -666,9 +660,10 @@ pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
/* Set page referenced/modified status based on flags */
if (flags & VM_PROT_WRITE)
- pv->pv_flags |= PV_ATTR_MOD | PV_ATTR_REF;
+ atomic_setbits_int(&pg->pg_flags,
+ PV_ATTR_MOD | PV_ATTR_REF);
else if (flags & VM_PROT_ALL)
- pv->pv_flags |= PV_ATTR_REF;
+ atomic_setbits_int(&pg->pg_flags, PV_ATTR_REF);
stat_count(enter_stats.managed);
} else {
@@ -680,7 +675,7 @@ pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
if (prot & VM_PROT_WRITE) {
npte = PG_IOPAGE & ~PG_G;
} else {
- npte = PG_IOPAGE & ~(PG_G | PG_M);
+ npte = (PG_IOPAGE | PG_RO) & ~(PG_G | PG_M);
}
}
@@ -694,7 +689,7 @@ pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
}
pte = kvtopte(va);
- npte |= vad_to_pfn(pa) | PG_ROPAGE | PG_G;
+ npte |= vad_to_pfn(pa) | PG_G;
if (!(pte->pt_entry & PG_V)) {
pmap->pm_stats.resident_count++;
}
@@ -914,7 +909,7 @@ pmap_zero_page(struct vm_page *pg)
va = (vaddr_t)PHYS_TO_KSEG0(phys);
pv = pg_to_pvh(pg);
- if ((pv->pv_flags & PV_CACHED) &&
+ if ((pg->pg_flags & PV_CACHED) &&
((pv->pv_va ^ va) & CpuCacheAliasMask) != 0) {
Mips_SyncDCachePage(pv->pv_va);
}
@@ -946,12 +941,12 @@ pmap_copy_page(struct vm_page *srcpg, struct vm_page *dstpg)
DPRINTF(PDB_FOLLOW, ("pmap_copy_page(%p, %p)\n", src, dst));
pv = pg_to_pvh(srcpg);
- if ((pv->pv_flags & PV_CACHED) &&
+ if ((srcpg->pg_flags & PV_CACHED) &&
(sf = ((pv->pv_va ^ (long)s) & CpuCacheAliasMask) != 0)) {
Mips_SyncDCachePage(pv->pv_va);
}
pv = pg_to_pvh(dstpg);
- if ((pv->pv_flags & PV_CACHED) &&
+ if ((dstpg->pg_flags & PV_CACHED) &&
(df = ((pv->pv_va ^ (long)d) & CpuCacheAliasMask) != 0)) {
Mips_SyncDCachePage(pv->pv_va);
}
@@ -961,13 +956,7 @@ pmap_copy_page(struct vm_page *srcpg, struct vm_page *dstpg)
if (sf) {
Mips_HitSyncDCache(s, PAGE_SIZE);
}
-#if 0 /* XXX TODO: Why can't we trust the following? */
- if (df || (pv->pv_pmap == NULL) || (pv->pv_flags & PV_EXEC)) {
- Mips_SyncDCachePage(d);
- }
-#else
Mips_SyncDCachePage(d);
-#endif
}
/*
@@ -985,11 +974,12 @@ pmap_clear_modify(struct vm_page *pg)
DPRINTF(PDB_FOLLOW, ("pmap_clear_modify(%p)\n", VM_PAGE_TO_PHYS(pg)));
pv = pg_to_pvh(pg);
- if (pv->pv_flags & PV_ATTR_MOD) {
- pv->pv_flags &= ~PV_ATTR_MOD;
+ if (pg->pg_flags & PV_ATTR_MOD) {
+ atomic_clearbits_int(&pg->pg_flags, PV_ATTR_MOD);
rv = TRUE;
}
- Mips_SyncDCachePage(pv->pv_va);
+ if (pg->pg_flags & PV_CACHED)
+ Mips_SyncDCachePage(pv->pv_va);
for (; pv != NULL; pv = pv->pv_next) {
if (pv->pv_pmap == pmap_kernel()) {
@@ -1023,10 +1013,7 @@ pmap_clear_modify(struct vm_page *pg)
void
pmap_set_modify(struct vm_page *pg)
{
- pv_entry_t pv;
-
- pv = pg_to_pvh(pg);
- pv->pv_flags |= PV_ATTR_MOD | PV_ATTR_REF;
+ atomic_setbits_int(&pg->pg_flags, PV_ATTR_MOD | PV_ATTR_REF);
}
/*
@@ -1037,14 +1024,12 @@ pmap_set_modify(struct vm_page *pg)
boolean_t
pmap_clear_reference(struct vm_page *pg)
{
- pv_entry_t pv;
boolean_t rv;
DPRINTF(PDB_FOLLOW, ("pmap_clear_reference(%p)\n", VM_PAGE_TO_PHYS(pg)));
- pv = pg_to_pvh(pg);
- rv = (pv->pv_flags & PV_ATTR_REF) != 0;
- pv->pv_flags &= ~PV_ATTR_REF;
+ rv = (pg->pg_flags & PV_ATTR_REF) != 0;
+ atomic_clearbits_int(&pg->pg_flags, PV_ATTR_REF);
return rv;
}
@@ -1057,10 +1042,7 @@ pmap_clear_reference(struct vm_page *pg)
boolean_t
pmap_is_referenced(struct vm_page *pg)
{
- pv_entry_t pv;
-
- pv = pg_to_pvh(pg);
- return (pv->pv_flags & PV_ATTR_REF) != 0;
+ return (pg->pg_flags & PV_ATTR_REF) != 0;
}
/*
@@ -1072,10 +1054,7 @@ pmap_is_referenced(struct vm_page *pg)
boolean_t
pmap_is_modified(struct vm_page *pg)
{
- pv_entry_t pv;
-
- pv = pg_to_pvh(pg);
- return (pv->pv_flags & PV_ATTR_MOD) != 0;
+ return (pg->pg_flags & PV_ATTR_MOD) != 0;
}
/*
@@ -1108,7 +1087,8 @@ pmap_page_cache(vm_page_t pg, int mode)
newmode = mode & PV_UNCACHED ? PG_UNCACHED : PG_CACHED;
pv = pg_to_pvh(pg);
- pv->pv_flags = (pv->pv_flags & ~(PV_CACHED|PV_UNCACHED)) | mode;
+ atomic_clearbits_int(&pg->pg_flags, PV_CACHED | PV_UNCACHED);
+ atomic_setbits_int(&pg->pg_flags, mode);
for (; pv != NULL; pv = pv->pv_next) {
if (pv->pv_pmap == pmap_kernel()) {
@@ -1230,14 +1210,14 @@ pmap_enter_pv(pmap_t pmap, vaddr_t va, vm_page_t pg, u_int *npte)
stat_count(enter_stats.firstpv);
pv->pv_va = va;
- pv->pv_flags = PV_CACHED;
+ atomic_setbits_int(&pg->pg_flags, PV_CACHED);
pv->pv_pmap = pmap;
pv->pv_next = NULL;
} else {
- if (pv->pv_flags & PV_UNCACHED) {
+ if (pg->pg_flags & PV_UNCACHED) {
/*
* If page is mapped uncached it's either because
- * an uncached mapping was requested of we have a
+ * an uncached mapping was requested or we have a
* VAC situation. Map this page uncached as well.
*/
*npte = (*npte & ~PG_CACHEMODE) | PG_UNCACHED;
@@ -1279,14 +1259,12 @@ pmap_enter_pv(pmap_t pmap, vaddr_t va, vm_page_t pg, u_int *npte)
("pmap_enter: new pv: pmap %x va %x pg %p\n",
pmap, va, VM_PAGE_TO_PHYS(pg)));
- /* can this cause us to recurse forever? */
npv = pmap_pv_alloc();
if (npv == NULL)
return ENOMEM;
npv->pv_va = va;
npv->pv_pmap = pmap;
npv->pv_next = pv->pv_next;
- npv->pv_flags = pv->pv_flags;
pv->pv_next = npv;
if (!npv->pv_next)
@@ -1324,12 +1302,13 @@ pmap_remove_pv(pmap_t pmap, vaddr_t va, paddr_t pa)
if (pmap == pv->pv_pmap && va == pv->pv_va) {
npv = pv->pv_next;
if (npv) {
- npv->pv_flags = pv->pv_flags;
*pv = *npv;
pmap_pv_free(npv);
} else {
pv->pv_pmap = NULL;
- pv->pv_flags &= PV_PRESERVE;
+ atomic_clearbits_int(&pg->pg_flags,
+ (PG_PMAP0 | PG_PMAP1 | PG_PMAP2 | PG_PMAP3) &
+ ~PV_PRESERVE);
Mips_SyncDCachePage(pv->pv_va);
}
stat_count(remove_stats.pvfirst);