Module Name:    src
Committed By:   thorpej
Date:           Wed Aug 26 00:30:03 UTC 2009

Modified Files:
        src/sys/arch/amiga/amiga: pmap.c
        src/sys/arch/amiga/include: vmparam.h
        src/sys/arch/atari/atari: pmap.c
        src/sys/arch/atari/include: vmparam.h
        src/sys/arch/cesfic/include: vmparam.h
        src/sys/arch/hp300/include: vmparam.h
        src/sys/arch/luna68k/include: vmparam.h
        src/sys/arch/m68k/include: pmap_motorola.h
        src/sys/arch/m68k/m68k: pmap_motorola.c
        src/sys/arch/mac68k/include: vmparam.h
        src/sys/arch/mvme68k/include: vmparam.h
        src/sys/arch/news68k/include: vmparam.h
        src/sys/arch/next68k/include: vmparam.h
        src/sys/arch/x68k/include: vmparam.h

Log Message:
Minor tweak to the pv_table management in the Hibler-derived m68k pmaps:
The head of the list is now a pv_header, which contains the first pv_entry
as well as a 16-bit attributes field (replaces the pmap_attributes array
plus the pv_entry::pv_flags field) as a 16-bit count of caller-specified
cache-inhibited mappings.

Tested on hp300 (shared pmap_motorola.c), changes to atari and amiga copies
are purely mechanical.


To generate a diff of this commit:
cvs rdiff -u -r1.153 -r1.154 src/sys/arch/amiga/amiga/pmap.c
cvs rdiff -u -r1.37 -r1.38 src/sys/arch/amiga/include/vmparam.h
cvs rdiff -u -r1.119 -r1.120 src/sys/arch/atari/atari/pmap.c
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/atari/include/vmparam.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/cesfic/include/vmparam.h
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/hp300/include/vmparam.h
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/luna68k/include/vmparam.h
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/m68k/include/pmap_motorola.h
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/m68k/m68k/pmap_motorola.c
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/mac68k/include/vmparam.h
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/mvme68k/include/vmparam.h
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/news68k/include/vmparam.h
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/next68k/include/vmparam.h
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/x68k/include/vmparam.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amiga/amiga/pmap.c
diff -u src/sys/arch/amiga/amiga/pmap.c:1.153 src/sys/arch/amiga/amiga/pmap.c:1.154
--- src/sys/arch/amiga/amiga/pmap.c:1.153	Tue Aug 18 18:06:53 2009
+++ src/sys/arch/amiga/amiga/pmap.c	Wed Aug 26 00:30:01 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.153 2009/08/18 18:06:53 thorpej Exp $	*/
+/*	$NetBSD: pmap.c,v 1.154 2009/08/26 00:30:01 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -100,7 +100,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.153 2009/08/18 18:06:53 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.154 2009/08/26 00:30:01 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -273,7 +273,19 @@
 st_entry_t	*Segtabzero, *Segtabzeropa;
 vsize_t		Sysptsize = VM_KERNEL_PT_PAGES;
 
-struct pv_entry	*pv_table;	/* array of entries, one per page */
+struct pv_header {
+	struct pv_entry		pvh_first;	/* first PV entry */
+	uint16_t		pvh_attrs;	/* attributes:
+						   bits 0-7: PTE bits
+						   bits 8-15: flags */
+	uint16_t		pvh_cimappings;	/* # caller-specified CI
+						   mappings */
+};
+
+#define	PVH_CI		0x10	/* all entries are cache-inhibited */
+#define	PVH_PTPAGE	0x20	/* entry maps a page table page */
+
+struct pv_header *pv_table;	/* array of entries, one per page */
 
 static struct pmap kernel_pmap_store;
 struct pmap	*const kernel_pmap_ptr = &kernel_pmap_store;
@@ -287,7 +299,6 @@
 vaddr_t		virtual_end;	/* VA of last avail page (end of kernel AS) */
 int		page_cnt;	/* number of pages managed by the VM system */
 bool		pmap_initialized = false;	/* Has pmap_init completed? */
-char		*pmap_attributes;	/* reference and modify bits */
 TAILQ_HEAD(pv_page_list, pv_page) pv_page_freelist;
 int		pv_nfree;
 #if defined(M68040) || defined(M68060)
@@ -323,25 +334,13 @@
 
 #define	PAGE_IS_MANAGED(pa)	(pmap_initialized && uvm_pageismanaged(pa))
 
-static inline struct pv_entry *pa_to_pvh(paddr_t pa);
-static inline char *pa_to_attribute(paddr_t pa);
-
-static inline struct pv_entry *
+static inline struct pv_header *
 pa_to_pvh(paddr_t pa)
 {
 	int bank, pg = 0;	/* XXX gcc4 -Wuninitialized */
 
 	bank = vm_physseg_find(atop((pa)), &pg);
-	return &vm_physmem[bank].pmseg.pvent[pg];
-}
-
-static inline char *
-pa_to_attribute(paddr_t pa)
-{
-	int bank, pg = 0;	/* XXX gcc4 -Wuninitialized */
-
-	bank = vm_physseg_find(atop((pa)), &pg);
-	return &vm_physmem[bank].pmseg.attrs[pg];
+	return &vm_physmem[bank].pmseg.pvheader[pg];
 }
 
 /*
@@ -355,8 +354,7 @@
 	vaddr_t		addr, addr2;
 	vsize_t		s;
 	u_int		npg;
-	struct pv_entry *pv;
-	char            *attr;
+	struct pv_header *pvh;
 	int             rv, bank;
 #if defined(M68060)
 	struct kpt_page *kptp;
@@ -397,8 +395,7 @@
 #endif
 	}
 	s = M68K_STSIZE;				/* Segtabzero */
-	s += page_cnt * sizeof(struct pv_entry);	/* pv table */
-	s += page_cnt * sizeof(char);			/* attribute table */
+	s += page_cnt * sizeof(struct pv_header);	/* pv table */
 	s = round_page(s);
 
 	addr = uvm_km_alloc(kernel_map, s, 0, UVM_KMF_WIRED | UVM_KMF_ZERO);
@@ -408,30 +405,26 @@
 	(void) pmap_extract(pmap_kernel(), addr, (paddr_t *)(void *)&Segtabzeropa);
 	addr += M68K_STSIZE;
 
-	pv_table = (struct pv_entry *) addr;
-	addr += page_cnt * sizeof(struct pv_entry);
+	pv_table = (struct pv_header *) addr;
+	addr += page_cnt * sizeof(struct pv_header);
 
-	pmap_attributes = (char *) addr;
 #ifdef DEBUG
 	if (pmapdebug & PDB_INIT)
 		printf("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) "
-			"tbl %p atr %p\n",
+			"tbl %p\n",
 			s, page_cnt, Segtabzero, Segtabzeropa,
-			pv_table, pmap_attributes);
+			pv_table);
 #endif
 
 	/*
 	 * Now that the pv and attribute tables have been allocated,
 	 * assign them to the memory segments.
 	 */
-	pv = pv_table;
-	attr = pmap_attributes;
+	pvh = pv_table;
 	for (bank = 0; bank < vm_nphysseg; bank++) {
 		npg = vm_physmem[bank].end - vm_physmem[bank].start;
-		vm_physmem[bank].pmseg.pvent = pv;
-		vm_physmem[bank].pmseg.attrs = attr;
-		pv += npg;
-		attr += npg;
+		vm_physmem[bank].pmseg.pvheader = pvh;
+		pvh += npg;
 	}
 
 	/*
@@ -796,6 +789,7 @@
 void
 pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	int s;
 	paddr_t	pa = VM_PAGE_TO_PHYS(pg);
@@ -815,7 +809,8 @@
 		break;
 	/* remove_all */
 	default:
-		pv = pa_to_pvh(pa);
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
 		s = splvm();
 		while (pv->pv_pmap != NULL) {
 			pt_entry_t  *pte;
@@ -1030,13 +1025,15 @@
 	 * since pmap_enter can be called at interrupt time.
 	 */
 	if (PAGE_IS_MANAGED(pa)) {
+		struct pv_header *pvh;
 		struct pv_entry *pv, *npv;
 		int s;
 
 #ifdef DEBUG
 		enter_stats.managed++;
 #endif
-		pv = pa_to_pvh(pa);
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
 		s = splvm();
 #ifdef DEBUG
 		if (pmapdebug & PDB_ENTER)
@@ -1055,7 +1052,6 @@
 			pv->pv_next = NULL;
 			pv->pv_ptste = NULL;
 			pv->pv_ptpmap = NULL;
-			pv->pv_flags = 0;
 		}
 		/*
 		 * There is at least one other VA mapping this page.
@@ -1278,10 +1274,12 @@
 		while (sva < nssva) {
 			if (pmap_pte_v(pte)) {
 #ifdef DEBUG
+				struct pv_header *pvh;
 				struct pv_entry *pv;
 				int s;
 
-				pv = pa_to_pvh(pmap_pte_pa(pte));
+				pvh = pa_to_pvh(pmap_pte_pa(pte));
+				pv = &pvh->pvh_first;
 				s = splvm();
 				while (pv->pv_pmap != NULL) {
 					KASSERT(pv->pv_pmap != pmap_kernel() ||
@@ -1472,6 +1470,7 @@
 pmap_collect1(pmap_t pmap, paddr_t startpa, paddr_t endpa)
 {
 	paddr_t pa;
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	pt_entry_t *pte;
 	paddr_t kpa;
@@ -1487,8 +1486,10 @@
 		 * Locate physical pages which are being used as kernel
 		 * page table pages.
 		 */
-		pv = pa_to_pvh(pa);
-		if (pv->pv_pmap != pmap_kernel() || !(pv->pv_flags & PV_PTPAGE))
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
+		if (pv->pv_pmap != pmap_kernel() ||
+		    !(pvh->pvh_attrs & PVH_PTPAGE))
 			continue;
 		do {
 			if (pv->pv_ptste && pv->pv_ptpmap == pmap_kernel())
@@ -1812,6 +1813,7 @@
 pmap_remove_mapping(pmap_t pmap, vaddr_t va, pt_entry_t *pte, int flags)
 {
 	paddr_t pa;
+	struct pv_header *pvh;
 	struct pv_entry *pv, *npv;
 	pmap_t ptpmap;
 	st_entry_t *ste;
@@ -1878,6 +1880,7 @@
 		 */
 		if (refs == 0 && (flags & PRM_KEEPPTPAGE) == 0) {
 #ifdef DIAGNOSTIC
+			struct pv_header *_pvh;
 			struct pv_entry *_pv;
 #endif
 			paddr_t _pa;
@@ -1886,7 +1889,8 @@
 #ifdef DIAGNOSTIC
 			if (PAGE_IS_MANAGED(_pa) == 0)
 				panic("pmap_remove_mapping: unmanaged PT page");
-			_pv = pa_to_pvh(_pa);
+			_pvh = pa_to_pvh(_pa);
+			_pv = &_pvh->pvh_first;
 			if (_pv->pv_ptste == NULL)
 				panic("pmap_remove_mapping: ptste == NULL");
 			if (_pv->pv_pmap != pmap_kernel() ||
@@ -1918,7 +1922,8 @@
 	 * Otherwise remove it from the PV table
 	 * (raise IPL since we may be called at interrupt time).
 	 */
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	ste = ST_ENTRY_NULL;
 	s = splvm();
 	/*
@@ -1932,7 +1937,6 @@
 		ptpmap = pv->pv_ptpmap;
 		npv = pv->pv_next;
 		if (npv) {
-			npv->pv_flags = pv->pv_flags;
 			*pv = *npv;
 			pmap_free_pv(npv);
 		} else
@@ -1957,7 +1961,8 @@
 		ptpmap = npv->pv_ptpmap;
 		pv->pv_next = npv->pv_next;
 		pmap_free_pv(npv);
-		pv = pa_to_pvh(pa);
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
 	}
 
 	/*
@@ -2040,13 +2045,13 @@
 		else
 			TBIAU();
 #endif
-		pv->pv_flags &= ~PV_PTPAGE;
+		pvh->pvh_attrs &= ~PVH_PTPAGE;
 		ptpmap->pm_ptpages--;
 	}
 	/*
 	 * Update saved attributes for managed page
 	 */
-	*pa_to_attribute(pa) |= bits;
+	pvh->pvh_attrs |= bits;
 	splx(s);
 }
 
@@ -2088,18 +2093,20 @@
 bool
 pmap_testbit(paddr_t pa, int bit)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	int *pte;
 	int s;
 
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	s = splvm();
 
 	/*
 	 * Check saved info first
 	 */
 
-	if (*pa_to_attribute(pa) & bit) {
+	if (pvh->pvh_attrs & bit) {
 		splx(s);
 		return(true);
 	}
@@ -2125,6 +2132,7 @@
 static void
 pmap_changebit(paddr_t pa, int bit, bool setem)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	int *pte, npte;
 	vaddr_t va;
@@ -2139,7 +2147,8 @@
 		    pa, bit, setem ? "set" : "clear");
 #endif
 
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	s = splvm();
 
 	/*
@@ -2147,7 +2156,7 @@
 	 */
 
 	if (!setem)
-		*pa_to_attribute(pa) &= ~bit;
+		pvh->pvh_attrs &= ~bit;
 
 	/*
 	 * Loop over all current mappings setting/clearing as appropos
@@ -2195,6 +2204,7 @@
 {
 	paddr_t ptpa;
 	struct vm_page *pg;
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 #ifdef M68060
 	u_int stpa;
@@ -2398,14 +2408,17 @@
 	 * record the STE address.  This is so that we can invalidate
 	 * the STE when we remove the mapping for the page.
 	 */
-	pv = pa_to_pvh(ptpa);
+	pvh = pa_to_pvh(ptpa);
 	s = splvm();
-	if (pv) {
-		pv->pv_flags |= PV_PTPAGE;
+	if (pvh) {
+		pv = &pvh->pvh_first;
+		pvh->pvh_attrs |= PVH_PTPAGE;
 		do {
 			if (pv->pv_pmap == pmap_kernel() && pv->pv_va == va)
 				break;
 		} while ((pv = pv->pv_next) > 0);
+	} else {
+		pv = NULL;
 	}
 #ifdef DEBUG
 	if (pv == NULL) {
@@ -2464,13 +2477,13 @@
 void
 pmap_pvdump(paddr_t pa)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 
 	printf("pa %lx", pa);
-	for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next)
-		printf(" -> pmap %p, va %lx, ptste %p, ptpmap %p, flags %x",
-		       pv->pv_pmap, pv->pv_va, pv->pv_ptste, pv->pv_ptpmap,
-		       pv->pv_flags);
+	for (pvh = pa_to_pvh(pa), pv = &pvh->pvh_first; pv; pv = pv->pv_next)
+		printf(" -> pmap %p, va %lx, ptste %p, ptpmap %p",
+		       pv->pv_pmap, pv->pv_va, pv->pv_ptste, pv->pv_ptpmap);
 	printf("\n");
 }
 

Index: src/sys/arch/amiga/include/vmparam.h
diff -u src/sys/arch/amiga/include/vmparam.h:1.37 src/sys/arch/amiga/include/vmparam.h:1.38
--- src/sys/arch/amiga/include/vmparam.h:1.37	Fri Mar  6 20:31:47 2009
+++ src/sys/arch/amiga/include/vmparam.h	Wed Aug 26 00:30:01 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.37 2009/03/06 20:31:47 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.38 2009/08/26 00:30:01 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
@@ -178,8 +178,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */   
 struct pmap_physseg { 
-	struct pv_entry *pvent;         /* pv table for this seg */
-	char *attrs;                    /* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 }; 
 
 /*

Index: src/sys/arch/atari/atari/pmap.c
diff -u src/sys/arch/atari/atari/pmap.c:1.119 src/sys/arch/atari/atari/pmap.c:1.120
--- src/sys/arch/atari/atari/pmap.c:1.119	Tue Aug 18 18:06:53 2009
+++ src/sys/arch/atari/atari/pmap.c	Wed Aug 26 00:30:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.119 2009/08/18 18:06:53 thorpej Exp $	*/
+/*	$NetBSD: pmap.c,v 1.120 2009/08/26 00:30:02 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -100,7 +100,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.119 2009/08/18 18:06:53 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.120 2009/08/26 00:30:02 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -272,7 +272,19 @@
 st_entry_t	*Segtabzero, *Segtabzeropa;
 vsize_t		Sysptsize = VM_KERNEL_PT_PAGES;
 
-struct pv_entry	*pv_table;	/* array of entries, one per page */
+struct pv_header {
+	struct pv_entry		pvh_first;	/* first PV entry */
+	uint16_t		pvh_attrs;	/* attributes:
+						   bits 0-7: PTE bits
+						   bits 8-15: flags */
+	uint16_t		pvh_cimappings;	/* # caller-specified CI
+						   mappings */
+};
+
+#define	PVH_CI		0x10	/* all entries are cache-inhibited */
+#define	PVH_PTPAGE	0x20	/* entry maps a page table page */
+
+struct pv_header *pv_table;	/* array of entries, one per page */
 
 static struct pmap kernel_pmap_store;
 struct pmap	*const kernel_pmap_ptr = &kernel_pmap_store;
@@ -286,7 +298,6 @@
 vaddr_t		virtual_end;	/* VA of last avail page (end of kernel AS) */
 int		page_cnt;	/* number of pages managed by the VM system */
 bool		pmap_initialized = false;	/* Has pmap_init completed? */
-char		*pmap_attributes;	/* reference and modify bits */
 TAILQ_HEAD(pv_page_list, pv_page) pv_page_freelist;
 int		pv_nfree;
 #if defined(M68040) || defined(M68060)
@@ -318,25 +329,13 @@
 
 #define	PAGE_IS_MANAGED(pa)	(pmap_initialized && uvm_pageismanaged(pa))
 
-static inline struct pv_entry *pa_to_pvh(paddr_t pa);
-static inline char *pa_to_attribute(paddr_t pa);
-
-static inline struct pv_entry *
+static inline struct pv_header *
 pa_to_pvh(paddr_t pa)
 {
 	int bank, pg = 0;	/* XXX gcc4 -Wuninitialized */
 
 	bank = vm_physseg_find(atop((pa)), &pg);
-	return &vm_physmem[bank].pmseg.pvent[pg];
-}
-
-static inline char *
-pa_to_attribute(paddr_t pa)
-{
-	int bank, pg = 0;	/* XXX gcc4 -Wuninitialized */
-
-	bank = vm_physseg_find(atop((pa)), &pg);
-	return &vm_physmem[bank].pmseg.attrs[pg];
+	return &vm_physmem[bank].pmseg.pvheader[pg];
 }
 
 /*
@@ -350,8 +349,7 @@
 	vaddr_t		addr, addr2;
 	vsize_t		s;
 	u_int		npg;
-	struct pv_entry *pv;
-	char            *attr;
+	struct pv_header *pvh;
 	int             rv, bank;
 #if defined(M68060)
 	struct kpt_page *kptp;
@@ -392,8 +390,7 @@
 #endif
 	}
 	s = M68K_STSIZE;				/* Segtabzero */
-	s += page_cnt * sizeof(struct pv_entry);	/* pv table */
-	s += page_cnt * sizeof(char);			/* attribute table */
+	s += page_cnt * sizeof(struct pv_header);	/* pv table */
 	s = round_page(s);
 
 	addr = uvm_km_alloc(kernel_map, s, 0, UVM_KMF_WIRED | UVM_KMF_ZERO);
@@ -403,30 +400,26 @@
 	(void) pmap_extract(pmap_kernel(), addr, (paddr_t *)(void *)&Segtabzeropa);
 	addr += M68K_STSIZE;
 
-	pv_table = (struct pv_entry *) addr;
-	addr += page_cnt * sizeof(struct pv_entry);
+	pv_table = (struct pv_header *) addr;
+	addr += page_cnt * sizeof(struct pv_header);
 
-	pmap_attributes = (char *) addr;
 #ifdef DEBUG
 	if (pmapdebug & PDB_INIT)
 		printf("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) "
-			"tbl %p atr %p\n",
+			"tbl %p\n",
 			s, page_cnt, Segtabzero, Segtabzeropa,
-			pv_table, pmap_attributes);
+			pv_table);
 #endif
 
 	/*
 	 * Now that the pv and attribute tables have been allocated,
 	 * assign them to the memory segments.
 	 */
-	pv = pv_table;
-	attr = pmap_attributes;
+	pvh = pv_table;
 	for (bank = 0; bank < vm_nphysseg; bank++) {
 		npg = vm_physmem[bank].end - vm_physmem[bank].start;
-		vm_physmem[bank].pmseg.pvent = pv;
-		vm_physmem[bank].pmseg.attrs = attr;
-		pv += npg;
-		attr += npg;
+		vm_physmem[bank].pmseg.pvheader = pvh;
+		pvh += npg;
 	}
 
 	/*
@@ -791,6 +784,7 @@
 void
 pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	int s;
 	paddr_t	pa = VM_PAGE_TO_PHYS(pg);
@@ -810,7 +804,8 @@
 		break;
 	/* remove_all */
 	default:
-		pv = pa_to_pvh(pa);
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
 		s = splvm();
 		while (pv->pv_pmap != NULL) {
 			pt_entry_t  *pte;
@@ -1025,13 +1020,15 @@
 	 * since pmap_enter can be called at interrupt time.
 	 */
 	if (PAGE_IS_MANAGED(pa)) {
+		struct pv_header *pvh;
 		struct pv_entry *pv, *npv;
 		int s;
 
 #ifdef DEBUG
 		enter_stats.managed++;
 #endif
-		pv = pa_to_pvh(pa);
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
 		s = splvm();
 #ifdef DEBUG
 		if (pmapdebug & PDB_ENTER)
@@ -1050,7 +1047,6 @@
 			pv->pv_next = NULL;
 			pv->pv_ptste = NULL;
 			pv->pv_ptpmap = NULL;
-			pv->pv_flags = 0;
 		}
 		/*
 		 * There is at least one other VA mapping this page.
@@ -1273,10 +1269,12 @@
 		while (sva < nssva) {
 			if (pmap_pte_v(pte)) {
 #ifdef DEBUG
+				struct pv_header *pvh;
 				struct pv_entry *pv;
 				int s;
 
-				pv = pa_to_pvh(pmap_pte_pa(pte));
+				pvh = pa_to_pvh(pmap_pte_pa(pte));
+				pv = &pvh->pvh_first;
 				s = splvm();
 				while (pv->pv_pmap != NULL) {
 					KASSERT(pv->pv_pmap != pmap_kernel() ||
@@ -1467,6 +1465,7 @@
 pmap_collect1(pmap_t pmap, paddr_t startpa, paddr_t endpa)
 {
 	paddr_t pa;
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	pt_entry_t *pte;
 	paddr_t kpa;
@@ -1482,8 +1481,10 @@
 		 * Locate physical pages which are being used as kernel
 		 * page table pages.
 		 */
-		pv = pa_to_pvh(pa);
-		if (pv->pv_pmap != pmap_kernel() || !(pv->pv_flags & PV_PTPAGE))
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
+		if (pv->pv_pmap != pmap_kernel() ||
+		    !(pvh->pvh_attrs & PVH_PTPAGE))
 			continue;
 		do {
 			if (pv->pv_ptste && pv->pv_ptpmap == pmap_kernel())
@@ -1807,6 +1808,7 @@
 pmap_remove_mapping(pmap_t pmap, vaddr_t va, pt_entry_t *pte, int flags)
 {
 	paddr_t pa;
+	struct pv_header *pvh;
 	struct pv_entry *pv, *npv;
 	pmap_t ptpmap;
 	st_entry_t *ste;
@@ -1873,6 +1875,7 @@
 		 */
 		if (refs == 0 && (flags & PRM_KEEPPTPAGE) == 0) {
 #ifdef DIAGNOSTIC
+			struct pv_header *_pvh;
 			struct pv_entry *_pv;
 #endif
 			paddr_t _pa;
@@ -1881,7 +1884,8 @@
 #ifdef DIAGNOSTIC
 			if (PAGE_IS_MANAGED(_pa) == 0)
 				panic("pmap_remove_mapping: unmanaged PT page");
-			_pv = pa_to_pvh(_pa);
+			_pvh = pa_to_pvh(_pa);
+			_pv = &_pvh->pvh_first;
 			if (_pv->pv_ptste == NULL)
 				panic("pmap_remove_mapping: ptste == NULL");
 			if (_pv->pv_pmap != pmap_kernel() ||
@@ -1913,7 +1917,8 @@
 	 * Otherwise remove it from the PV table
 	 * (raise IPL since we may be called at interrupt time).
 	 */
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	ste = ST_ENTRY_NULL;
 	s = splvm();
 	/*
@@ -1927,7 +1932,6 @@
 		ptpmap = pv->pv_ptpmap;
 		npv = pv->pv_next;
 		if (npv) {
-			npv->pv_flags = pv->pv_flags;
 			*pv = *npv;
 			pmap_free_pv(npv);
 		} else
@@ -1952,7 +1956,8 @@
 		ptpmap = npv->pv_ptpmap;
 		pv->pv_next = npv->pv_next;
 		pmap_free_pv(npv);
-		pv = pa_to_pvh(pa);
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
 	}
 
 	/*
@@ -2035,13 +2040,13 @@
 		else
 			TBIAU();
 #endif
-		pv->pv_flags &= ~PV_PTPAGE;
+		pvh->pvh_attrs &= ~PVH_PTPAGE;
 		ptpmap->pm_ptpages--;
 	}
 	/*
 	 * Update saved attributes for managed page
 	 */
-	*pa_to_attribute(pa) |= bits;
+	pvh->pvh_attrs |= bits;
 	splx(s);
 }
 
@@ -2083,18 +2088,20 @@
 bool
 pmap_testbit(paddr_t pa, int bit)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	int *pte;
 	int s;
 
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	s = splvm();
 
 	/*
 	 * Check saved info first
 	 */
 
-	if (*pa_to_attribute(pa) & bit) {
+	if (pvh->pvh_attrs & bit) {
 		splx(s);
 		return(true);
 	}
@@ -2120,6 +2127,7 @@
 static void
 pmap_changebit(paddr_t pa, int bit, bool setem)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	int *pte, npte;
 	vaddr_t va;
@@ -2134,7 +2142,8 @@
 		    pa, bit, setem ? "set" : "clear");
 #endif
 
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	s = splvm();
 
 	/*
@@ -2142,7 +2151,7 @@
 	 */
 
 	if (!setem)
-		*pa_to_attribute(pa) &= ~bit;
+		pvh->pvh_attrs &= ~bit;
 
 	/*
 	 * Loop over all current mappings setting/clearing as appropos
@@ -2190,6 +2199,7 @@
 {
 	paddr_t ptpa;
 	struct vm_page *pg;
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 #ifdef M68060
 	u_int stpa;
@@ -2393,14 +2403,17 @@
 	 * record the STE address.  This is so that we can invalidate
 	 * the STE when we remove the mapping for the page.
 	 */
-	pv = pa_to_pvh(ptpa);
+	pvh = pa_to_pvh(ptpa);
 	s = splvm();
-	if (pv) {
-		pv->pv_flags |= PV_PTPAGE;
+	if (pvh) {
+		pv = &pvh->pvh_first;
+		pvh->pvh_attrs |= PVH_PTPAGE;
 		do {
 			if (pv->pv_pmap == pmap_kernel() && pv->pv_va == va)
 				break;
 		} while ((pv = pv->pv_next) > 0);
+	} else {
+		pv = NULL;
 	}
 #ifdef DEBUG
 	if (pv == NULL) {
@@ -2459,10 +2472,11 @@
 void
 pmap_pvdump(paddr_t pa)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 
 	printf("pa %lx", pa);
-	for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next)
+	for (pvh = pa_to_pvh(pa), pv = &pvh->pvh_first; pv; pv = pv->pv_next)
 		printf(" -> pmap %p, va %lx, ptste %p, ptpmap %p, flags %x",
 		       pv->pv_pmap, pv->pv_va, pv->pv_ptste, pv->pv_ptpmap,
 		       pv->pv_flags);

Index: src/sys/arch/atari/include/vmparam.h
diff -u src/sys/arch/atari/include/vmparam.h:1.24 src/sys/arch/atari/include/vmparam.h:1.25
--- src/sys/arch/atari/include/vmparam.h:1.24	Fri Mar 13 19:08:20 2009
+++ src/sys/arch/atari/include/vmparam.h	Wed Aug 26 00:30:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.24 2009/03/13 19:08:20 abs Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.25 2009/08/26 00:30:02 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
@@ -169,8 +169,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */   
 struct pmap_physseg { 
-	struct pv_entry *pvent;         /* pv table for this seg */
-	char *attrs;                    /* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 }; 
 
 

Index: src/sys/arch/cesfic/include/vmparam.h
diff -u src/sys/arch/cesfic/include/vmparam.h:1.10 src/sys/arch/cesfic/include/vmparam.h:1.11
--- src/sys/arch/cesfic/include/vmparam.h:1.10	Fri Mar  6 20:31:47 2009
+++ src/sys/arch/cesfic/include/vmparam.h	Wed Aug 26 00:30:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.10 2009/03/06 20:31:47 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.11 2009/08/26 00:30:02 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -188,8 +188,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */
 struct pmap_physseg {
-	struct pv_entry *pvent;		/* pv table for this seg */
-	char *attrs;			/* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 };
 
 #endif /* _MACHINE_VMPARAM_H_ */

Index: src/sys/arch/hp300/include/vmparam.h
diff -u src/sys/arch/hp300/include/vmparam.h:1.33 src/sys/arch/hp300/include/vmparam.h:1.34
--- src/sys/arch/hp300/include/vmparam.h:1.33	Fri Mar  6 20:31:49 2009
+++ src/sys/arch/hp300/include/vmparam.h	Wed Aug 26 00:30:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.33 2009/03/06 20:31:49 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.34 2009/08/26 00:30:02 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -182,8 +182,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */
 struct pmap_physseg {
-	struct pv_entry *pvent;		/* pv table for this seg */
-	char *attrs;			/* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 };
 
 #endif /* _HP300_VMPARAM_H_ */

Index: src/sys/arch/luna68k/include/vmparam.h
diff -u src/sys/arch/luna68k/include/vmparam.h:1.12 src/sys/arch/luna68k/include/vmparam.h:1.13
--- src/sys/arch/luna68k/include/vmparam.h:1.12	Fri Mar  6 20:31:49 2009
+++ src/sys/arch/luna68k/include/vmparam.h	Wed Aug 26 00:30:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.12 2009/03/06 20:31:49 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.13 2009/08/26 00:30:02 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -162,8 +162,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */
 struct pmap_physseg {
-	struct pv_entry *pvent;		/* pv table for this seg */
-	char *attrs;			/* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 };
 
 #endif /* _MACHINE_VMPARAM_H_ */

Index: src/sys/arch/m68k/include/pmap_motorola.h
diff -u src/sys/arch/m68k/include/pmap_motorola.h:1.20 src/sys/arch/m68k/include/pmap_motorola.h:1.21
--- src/sys/arch/m68k/include/pmap_motorola.h:1.20	Sat Jan 17 07:17:36 2009
+++ src/sys/arch/m68k/include/pmap_motorola.h	Wed Aug 26 00:30:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap_motorola.h,v 1.20 2009/01/17 07:17:36 tsutsui Exp $	*/
+/*	$NetBSD: pmap_motorola.h,v 1.21 2009/08/26 00:30:02 thorpej Exp $	*/
 
 /* 
  * Copyright (c) 1991, 1993
@@ -136,12 +136,8 @@
 	vaddr_t		pv_va;		/* virtual address for mapping */
 	st_entry_t	*pv_ptste;	/* non-zero if VA maps a PT page */
 	struct pmap	*pv_ptpmap;	/* if pv_ptste, pmap for PT page */
-	int		pv_flags;	/* flags */
 };
 
-#define PV_CI		0x01	/* header: all entries are cache inhibited */
-#define PV_PTPAGE	0x02	/* header: entry maps a page table page */
-
 struct pv_page;
 
 struct pv_page_info {
@@ -171,7 +167,7 @@
 	(curproc && \
 	 (pm) != pmap_kernel() && (pm) == curproc->p_vmspace->vm_map.pmap)
 
-extern struct pv_entry	*pv_table;	/* array of entries, one per page */
+extern struct pv_header	*pv_table;	/* array of entries, one per page */
 
 #define	pmap_resident_count(pmap)	((pmap)->pm_stats.resident_count)
 #define	pmap_wired_count(pmap)		((pmap)->pm_stats.wired_count)

Index: src/sys/arch/m68k/m68k/pmap_motorola.c
diff -u src/sys/arch/m68k/m68k/pmap_motorola.c:1.45 src/sys/arch/m68k/m68k/pmap_motorola.c:1.46
--- src/sys/arch/m68k/m68k/pmap_motorola.c:1.45	Tue Aug 18 18:06:53 2009
+++ src/sys/arch/m68k/m68k/pmap_motorola.c	Wed Aug 26 00:30:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap_motorola.c,v 1.45 2009/08/18 18:06:53 thorpej Exp $        */
+/*	$NetBSD: pmap_motorola.c,v 1.46 2009/08/26 00:30:02 thorpej Exp $        */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -117,7 +117,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap_motorola.c,v 1.45 2009/08/18 18:06:53 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap_motorola.c,v 1.46 2009/08/26 00:30:02 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -249,8 +249,20 @@
 int		page_cnt;	/* number of pages managed by VM system */
 
 bool		pmap_initialized = false;	/* Has pmap_init completed? */
-struct pv_entry	*pv_table;
-char		*pmap_attributes;	/* reference and modify bits */
+
+struct pv_header {
+	struct pv_entry		pvh_first;	/* first PV entry */
+	uint16_t		pvh_attrs;	/* attributes:
+						   bits 0-7: PTE bits
+						   bits 8-15: flags */
+	uint16_t		pvh_cimappings;	/* # caller-specified CI
+						   mappings */
+};
+
+#define	PVH_CI		0x10	/* all entries are cache-inhibited */
+#define	PVH_PTPAGE	0x20	/* entry maps a page table page */
+
+struct pv_header *pv_table;
 TAILQ_HEAD(pv_page_list, pv_page) pv_page_freelist;
 int		pv_nfree;
 
@@ -272,25 +284,13 @@
 
 #define	PAGE_IS_MANAGED(pa)	(pmap_initialized && uvm_pageismanaged(pa))
 
-static inline struct pv_entry *pa_to_pvh(paddr_t pa);
-static inline char *pa_to_attribute(paddr_t pa);
-
-static inline struct pv_entry *
+static inline struct pv_header *
 pa_to_pvh(paddr_t pa)
 {
 	int bank, pg = 0;	/* XXX gcc4 -Wuninitialized */
 
 	bank = vm_physseg_find(atop((pa)), &pg);
-	return &vm_physmem[bank].pmseg.pvent[pg];
-}
-
-static inline char *
-pa_to_attribute(paddr_t pa)
-{
-	int bank, pg = 0;	/* XXX gcc4 -Wuninitialized */
-
-	bank = vm_physseg_find(atop((pa)), &pg);
-	return &vm_physmem[bank].pmseg.attrs[pg];
+	return &vm_physmem[bank].pmseg.pvheader[pg];
 }
 
 /*
@@ -349,8 +349,7 @@
 {
 	vaddr_t		addr, addr2;
 	vsize_t		s;
-	struct pv_entry	*pv;
-	char		*attr;
+	struct pv_header *pvh;
 	int		rv;
 	int		npages;
 	int		bank;
@@ -378,8 +377,7 @@
 	for (page_cnt = 0, bank = 0; bank < vm_nphysseg; bank++)
 		page_cnt += vm_physmem[bank].end - vm_physmem[bank].start;
 	s = M68K_STSIZE;					/* Segtabzero */
-	s += page_cnt * sizeof(struct pv_entry);	/* pv table */
-	s += page_cnt * sizeof(char);			/* attribute table */
+	s += page_cnt * sizeof(struct pv_header);	/* pv table */
 	s = round_page(s);
 	addr = uvm_km_alloc(kernel_map, s, 0, UVM_KMF_WIRED | UVM_KMF_ZERO);
 	if (addr == 0)
@@ -390,28 +388,23 @@
 	    (paddr_t *)(void *)&Segtabzeropa);
 	addr += M68K_STSIZE;
 
-	pv_table = (struct pv_entry *) addr;
-	addr += page_cnt * sizeof(struct pv_entry);
-
-	pmap_attributes = (char *)addr;
+	pv_table = (struct pv_header *) addr;
+	addr += page_cnt * sizeof(struct pv_header);
 
 	PMAP_DPRINTF(PDB_INIT, ("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) "
-	    "tbl %p atr %p\n",
+	    "tbl %p\n",
 	    s, page_cnt, Segtabzero, Segtabzeropa,
-	    pv_table, pmap_attributes));
+	    pv_table));
 
 	/*
 	 * Now that the pv and attribute tables have been allocated,
 	 * assign them to the memory segments.
 	 */
-	pv = pv_table;
-	attr = pmap_attributes;
+	pvh = pv_table;
 	for (bank = 0; bank < vm_nphysseg; bank++) {
 		npages = vm_physmem[bank].end - vm_physmem[bank].start;
-		vm_physmem[bank].pmseg.pvent = pv;
-		vm_physmem[bank].pmseg.attrs = attr;
-		pv += npages;
-		attr += npages;
+		vm_physmem[bank].pmseg.pvheader = pvh;
+		pvh += npages;
 	}
 
 	/*
@@ -606,6 +599,7 @@
 	struct pv_page_list pv_page_collectlist;
 	struct pv_page *pvp, *npvp;
 	struct pv_entry *ph, *ppv, *pv, *npv;
+	struct pv_header *pvh;
 	int s;
 
 	TAILQ_INIT(&pv_page_collectlist);
@@ -626,7 +620,8 @@
 	if (TAILQ_FIRST(&pv_page_collectlist) == NULL)
 		return;
 
-	for (ph = &pv_table[page_cnt - 1]; ph >= &pv_table[0]; ph--) {
+	for (pvh = &pv_table[page_cnt - 1]; pvh >= &pv_table[0]; pvh--) {
+		ph = &pvh->pvh_first;
 		if (ph->pv_pmap == NULL)
 			continue;
 		s = splvm();
@@ -974,6 +969,7 @@
 pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
 {
 	paddr_t pa = VM_PAGE_TO_PHYS(pg);
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	pt_entry_t *pte;
 	int s;
@@ -1000,7 +996,8 @@
 		break;
 	}
 
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	s = splvm();
 	while (pv->pv_pmap != NULL) {
 
@@ -1229,10 +1226,12 @@
 	 * since pmap_enter can be called at interrupt time.
 	 */
 	if (PAGE_IS_MANAGED(pa)) {
+		struct pv_header *pvh;
 		struct pv_entry *pv, *npv;
 		int s;
 
-		pv = pa_to_pvh(pa);
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
 		s = splvm();
 
 		PMAP_DPRINTF(PDB_ENTER,
@@ -1247,7 +1246,7 @@
 			pv->pv_next = NULL;
 			pv->pv_ptste = NULL;
 			pv->pv_ptpmap = NULL;
-			pv->pv_flags = 0;
+			pvh->pvh_attrs = 0;
 		}
 		/*
 		 * There is at least one other VA mapping this page.
@@ -1265,7 +1264,6 @@
 			npv->pv_next = pv->pv_next;
 			npv->pv_ptste = NULL;
 			npv->pv_ptpmap = NULL;
-			npv->pv_flags = 0;
 			pv->pv_next = npv;
 
 #ifdef M68K_MMU_HP
@@ -1294,7 +1292,7 @@
 			 */
 
 			if (pmap_aliasmask) {
-				if (pv->pv_flags & PV_CI) {
+				if (pvh->pvh_attrs & PVH_CI) {
 					PMAP_DPRINTF(PDB_CACHE,
 					    ("enter: pa %lx already CI'ed\n",
 					    pa));
@@ -1309,7 +1307,7 @@
 					    ("enter: pa %lx CI'ing all\n",
 					    pa));
 					cacheable = false;
-					pv->pv_flags |= PV_CI;
+					pvh->pvh_attrs |= PVH_CI;
 				}
 			}
 #endif
@@ -1324,9 +1322,9 @@
 			panic("pmap_enter: access_type exceeds prot");
 #endif
 		if (flags & VM_PROT_WRITE)
-			*pa_to_attribute(pa) |= (PG_U|PG_M);
+			pvh->pvh_attrs |= (PG_U|PG_M);
 		else if (flags & VM_PROT_ALL)
-			*pa_to_attribute(pa) |= PG_U;
+			pvh->pvh_attrs |= PG_U;
 
 		splx(s);
 	}
@@ -1725,6 +1723,7 @@
 pmap_collect1(pmap_t pmap, paddr_t startpa, paddr_t endpa)
 {
 	paddr_t pa;
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	pt_entry_t *pte;
 	paddr_t kpa;
@@ -1741,8 +1740,10 @@
 		 * page table pages.
 		 */
 
-		pv = pa_to_pvh(pa);
-		if (pv->pv_pmap != pmap_kernel() || !(pv->pv_flags & PV_PTPAGE))
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
+		if (pv->pv_pmap != pmap_kernel() ||
+		    !(pvh->pvh_attrs & PVH_PTPAGE))
 			continue;
 		do {
 			if (pv->pv_ptste && pv->pv_ptpmap == pmap_kernel())
@@ -2065,6 +2066,7 @@
 pmap_remove_mapping(pmap_t pmap, vaddr_t va, pt_entry_t *pte, int flags)
 {
 	paddr_t pa;
+	struct pv_header *pvh;
 	struct pv_entry *pv, *npv;
 	struct pmap *ptpmap;
 	st_entry_t *ste;
@@ -2162,6 +2164,7 @@
 
 		if (refs == 0 && (flags & PRM_KEEPPTPAGE) == 0) {
 #ifdef DIAGNOSTIC
+			struct pv_header *ptppvh;
 			struct pv_entry *ptppv;
 #endif
 			paddr_t ptppa;
@@ -2170,7 +2173,8 @@
 #ifdef DIAGNOSTIC
 			if (PAGE_IS_MANAGED(ptppa) == 0)
 				panic("pmap_remove_mapping: unmanaged PT page");
-			ptppv = pa_to_pvh(ptppa);
+			ptppvh = pa_to_pvh(ptppa);
+			ptppv = &ptppvh->pvh_first;
 			if (ptppv->pv_ptste == NULL)
 				panic("pmap_remove_mapping: ptste == NULL");
 			if (ptppv->pv_pmap != pmap_kernel() ||
@@ -2204,7 +2208,8 @@
 	 * (raise IPL since we may be called at interrupt time).
 	 */
 
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	ste = NULL;
 	s = splvm();
 
@@ -2220,7 +2225,6 @@
 		ptpmap = pv->pv_ptpmap;
 		npv = pv->pv_next;
 		if (npv) {
-			npv->pv_flags = pv->pv_flags;
 			*pv = *npv;
 			pmap_free_pv(npv);
 		} else
@@ -2239,7 +2243,8 @@
 		ptpmap = npv->pv_ptpmap;
 		pv->pv_next = npv->pv_next;
 		pmap_free_pv(npv);
-		pv = pa_to_pvh(pa);
+		pvh = pa_to_pvh(pa);
+		pv = &pvh->pvh_first;
 	}
 
 #ifdef M68K_MMU_HP
@@ -2249,10 +2254,10 @@
 	 */
 
 	if (pmap_aliasmask &&
-	    pv->pv_pmap && pv->pv_next == NULL && (pv->pv_flags & PV_CI)) {
+	    pv->pv_pmap && pv->pv_next == NULL && (pvh->pvh_attrs & PVH_CI)) {
 		PMAP_DPRINTF(PDB_CACHE,
 		    ("remove: clearing CI for pa %lx\n", pa));
-		pv->pv_flags &= ~PV_CI;
+		pvh->pvh_attrs &= ~PVH_CI;
 		pmap_changebit(pa, 0, ~PG_CI);
 #ifdef DEBUG
 		if ((pmapdebug & (PDB_CACHE|PDB_PVDUMP)) ==
@@ -2333,7 +2338,7 @@
 					PMAP_ACTIVATE(ptpmap, 1);
 			}
 		}
-		pv->pv_flags &= ~PV_PTPAGE;
+		pvh->pvh_attrs &= ~PVH_PTPAGE;
 		ptpmap->pm_ptpages--;
 	}
 
@@ -2341,7 +2346,7 @@
 	 * Update saved attributes for managed page
 	 */
 
-	*pa_to_attribute(pa) |= bits;
+	pvh->pvh_attrs |= bits;
 	splx(s);
 }
 
@@ -2354,18 +2359,20 @@
 bool
 pmap_testbit(paddr_t pa, int bit)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	pt_entry_t *pte;
 	int s;
 
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	s = splvm();
 
 	/*
 	 * Check saved info first
 	 */
 
-	if (*pa_to_attribute(pa) & bit) {
+	if (pvh->pvh_attrs & bit) {
 		splx(s);
 		return true;
 	}
@@ -2389,7 +2396,7 @@
 		for (; pv; pv = pv->pv_next) {
 			pte = pmap_pte(pv->pv_pmap, pv->pv_va);
 			if (*pte & bit) {
-				*pa_to_attribute(pa) |= bit;
+				pvh->pvh_attrs |= bit;
 				splx(s);
 				return true;
 			}
@@ -2409,10 +2416,10 @@
 bool
 pmap_changebit(paddr_t pa, int set, int mask)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	pt_entry_t *pte, npte;
 	vaddr_t va;
-	char *attrp;
 	int s;
 #if defined(M68K_MMU_HP) || defined(M68040) || defined(M68060)
 	bool firstpage = true;
@@ -2422,16 +2429,16 @@
 	PMAP_DPRINTF(PDB_BITS,
 	    ("pmap_changebit(%lx, %x, %x)\n", pa, set, mask));
 
-	pv = pa_to_pvh(pa);
+	pvh = pa_to_pvh(pa);
+	pv = &pvh->pvh_first;
 	s = splvm();
 
 	/*
 	 * Clear saved attributes (modify, reference)
 	 */
 
-	attrp = pa_to_attribute(pa);
-	r = *attrp & ~mask;
-	*attrp &= mask;
+	r = (pvh->pvh_attrs & ~mask) != 0;
+	pvh->pvh_attrs &= mask;
 
 	/*
 	 * Loop over all current mappings setting/clearing as appropos
@@ -2502,6 +2509,7 @@
 {
 	paddr_t ptpa;
 	struct vm_page *pg;
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 	st_entry_t *ste;
 	int s;
@@ -2687,14 +2695,17 @@
 	 * record the STE address.  This is so that we can invalidate
 	 * the STE when we remove the mapping for the page.
 	 */
-	pv = pa_to_pvh(ptpa);
+	pvh = pa_to_pvh(ptpa);
 	s = splvm();
-	if (pv) {
-		pv->pv_flags |= PV_PTPAGE;
+	if (pvh) {
+		pv = &pvh->pvh_first;
+		pvh->pvh_attrs |= PVH_PTPAGE;
 		do {
 			if (pv->pv_pmap == pmap_kernel() && pv->pv_va == va)
 				break;
 		} while ((pv = pv->pv_next));
+	} else {
+		pv = NULL;
 	}
 #ifdef DEBUG
 	if (pv == NULL)
@@ -2868,10 +2879,12 @@
 void
 pmap_pvdump(paddr_t pa)
 {
+	struct pv_header *pvh;
 	struct pv_entry *pv;
 
 	printf("pa %lx", pa);
-	for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next)
+	pvh = pa_to_pvh(pa);
+	for (pv = &pvh->pvh_first; pv; pv = pv->pv_next)
 		printf(" -> pmap %p, va %lx, ptste %p, ptpmap %p, flags %x",
 		    pv->pv_pmap, pv->pv_va, pv->pv_ptste, pv->pv_ptpmap,
 		    pv->pv_flags);

Index: src/sys/arch/mac68k/include/vmparam.h
diff -u src/sys/arch/mac68k/include/vmparam.h:1.38 src/sys/arch/mac68k/include/vmparam.h:1.39
--- src/sys/arch/mac68k/include/vmparam.h:1.38	Fri Mar  6 20:31:50 2009
+++ src/sys/arch/mac68k/include/vmparam.h	Wed Aug 26 00:30:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.38 2009/03/06 20:31:50 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.39 2009/08/26 00:30:02 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1990 The Regents of the University of California.
@@ -208,8 +208,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */
 struct pmap_physseg {
-	struct pv_entry *pvent;		/* pv table for this seg */
-	char *attrs;			/* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 };
 
 #endif /* _MAC68K_VMPARAM_H_ */

Index: src/sys/arch/mvme68k/include/vmparam.h
diff -u src/sys/arch/mvme68k/include/vmparam.h:1.29 src/sys/arch/mvme68k/include/vmparam.h:1.30
--- src/sys/arch/mvme68k/include/vmparam.h:1.29	Fri Mar  6 20:31:50 2009
+++ src/sys/arch/mvme68k/include/vmparam.h	Wed Aug 26 00:30:03 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.29 2009/03/06 20:31:50 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.30 2009/08/26 00:30:03 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -174,8 +174,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */
 struct pmap_physseg {
-	struct pv_entry *pvent;		/* pv table for this seg */
-	char *attrs;			/* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 };
 
 #endif /* _MVME68K_VMPARAM_H_ */

Index: src/sys/arch/news68k/include/vmparam.h
diff -u src/sys/arch/news68k/include/vmparam.h:1.14 src/sys/arch/news68k/include/vmparam.h:1.15
--- src/sys/arch/news68k/include/vmparam.h:1.14	Fri Mar  6 20:31:51 2009
+++ src/sys/arch/news68k/include/vmparam.h	Wed Aug 26 00:30:03 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.14 2009/03/06 20:31:51 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.15 2009/08/26 00:30:03 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -172,8 +172,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */
 struct pmap_physseg {
-	struct pv_entry *pvent;		/* pv table for this seg */
-	char *attrs;			/* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 };
 
 #endif /* _NEWS68K_VMPARAM_H_ */

Index: src/sys/arch/next68k/include/vmparam.h
diff -u src/sys/arch/next68k/include/vmparam.h:1.19 src/sys/arch/next68k/include/vmparam.h:1.20
--- src/sys/arch/next68k/include/vmparam.h:1.19	Fri Mar  6 20:31:51 2009
+++ src/sys/arch/next68k/include/vmparam.h	Wed Aug 26 00:30:03 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.19 2009/03/06 20:31:51 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.20 2009/08/26 00:30:03 thorpej Exp $	*/
 
 /*
  * This file was taken from from mvme68k/include/vmparam.h and
@@ -177,8 +177,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */
 struct pmap_physseg {
-	struct pv_entry *pvent;		/* pv table for this seg */
-	char *attrs;			/* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 };
 
 #endif /* _MVME68K_VMPARAM_H_ */

Index: src/sys/arch/x68k/include/vmparam.h
diff -u src/sys/arch/x68k/include/vmparam.h:1.29 src/sys/arch/x68k/include/vmparam.h:1.30
--- src/sys/arch/x68k/include/vmparam.h:1.29	Fri Mar  6 20:31:54 2009
+++ src/sys/arch/x68k/include/vmparam.h	Wed Aug 26 00:30:03 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.29 2009/03/06 20:31:54 joerg Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.30 2009/08/26 00:30:03 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -164,8 +164,7 @@
  * pmap-specific data stored in the vm_physmem[] array.
  */
 struct pmap_physseg {
-	struct pv_entry *pvent;		/* pv table for this seg */
-	char *attrs;			/* page attributes for this seg */
+	struct pv_header *pvheader;	/* pv table for this seg */
 };
 
 #endif /* _X68K_VMPARAM_H_ */

Reply via email to