Module Name: src
Committed By: matt
Date: Mon Jun 20 20:24:29 UTC 2011
Modified Files:
src/sys/arch/powerpc/booke: booke_pmap.c trap.c
src/sys/arch/powerpc/include: intr.h pmap.h vmparam.h
src/sys/arch/powerpc/include/booke: pmap.h pte.h vmparam.h
src/sys/arch/powerpc/include/ibm4xx: pmap.h vmparam.h
src/sys/arch/powerpc/include/oea: pmap.h vmparam.h
src/sys/common/pmap/tlb: pmap.c pmap.h
Log Message:
PowerPC now exports a common view of cpu.h, vmparam.h and pmap.h
when building a MODULAR kernel or compiling _MODULE.
It should be noted that MODULAR or _MODULE export a view of the kernel
as being MULTIPROCESSOR (even if isn't).
The shared pmap TLB uses mdpg in places where it used mdpg to avoid
deadly embrance inclusion problems.
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/powerpc/booke/booke_pmap.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/powerpc/booke/trap.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/powerpc/include/intr.h
cvs rdiff -u -r1.36 -r1.37 src/sys/arch/powerpc/include/pmap.h
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/powerpc/include/vmparam.h
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/powerpc/include/booke/pmap.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/powerpc/include/booke/pte.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/powerpc/include/booke/vmparam.h
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/powerpc/include/ibm4xx/pmap.h
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/powerpc/include/ibm4xx/vmparam.h
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/powerpc/include/oea/pmap.h
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/powerpc/include/oea/vmparam.h
cvs rdiff -u -r1.5 -r1.6 src/sys/common/pmap/tlb/pmap.c
cvs rdiff -u -r1.4 -r1.5 src/sys/common/pmap/tlb/pmap.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/powerpc/booke/booke_pmap.c
diff -u src/sys/arch/powerpc/booke/booke_pmap.c:1.5 src/sys/arch/powerpc/booke/booke_pmap.c:1.6
--- src/sys/arch/powerpc/booke/booke_pmap.c:1.5 Sun Jun 12 05:32:38 2011
+++ src/sys/arch/powerpc/booke/booke_pmap.c Mon Jun 20 20:24:28 2011
@@ -37,13 +37,13 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: booke_pmap.c,v 1.5 2011/06/12 05:32:38 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: booke_pmap.c,v 1.6 2011/06/20 20:24:28 matt Exp $");
#include <sys/param.h>
#include <sys/kcore.h>
#include <sys/buf.h>
-#include <uvm/uvm_extern.h>
+#include <uvm/uvm.h>
#include <machine/pmap.h>
@@ -265,7 +265,7 @@
{
dcache_zero_page(pa);
- KASSERT(!VM_PAGE_MD_EXECPAGE_P(PHYS_TO_VM_PAGE(pa)));
+ KASSERT(!VM_PAGEMD_EXECPAGE_P(VM_PAGE_TO_MD(PHYS_TO_VM_PAGE(pa))));
}
void
@@ -291,7 +291,7 @@
}
}
- KASSERT(!VM_PAGE_MD_EXECPAGE_P(PHYS_TO_VM_PAGE(dst - PAGE_SIZE)));
+ KASSERT(!VM_PAGEMD_EXECPAGE_P(VM_PAGE_TO_MD(PHYS_TO_VM_PAGE(dst - PAGE_SIZE))));
}
void
Index: src/sys/arch/powerpc/booke/trap.c
diff -u src/sys/arch/powerpc/booke/trap.c:1.10 src/sys/arch/powerpc/booke/trap.c:1.11
--- src/sys/arch/powerpc/booke/trap.c:1.10 Tue Jun 14 05:50:24 2011
+++ src/sys/arch/powerpc/booke/trap.c Mon Jun 20 20:24:28 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.10 2011/06/14 05:50:24 matt Exp $ */
+/* $NetBSD: trap.c,v 1.11 2011/06/20 20:24:28 matt Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.10 2011/06/14 05:50:24 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.11 2011/06/20 20:24:28 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -233,9 +233,10 @@
const paddr_t pa = pte_to_paddr(pte);
struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
KASSERT(pg);
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
- if (!VM_PAGE_MD_MODIFIED_P(pg)) {
- pmap_page_set_attributes(pg, VM_PAGE_MD_MODIFIED);
+ if (!VM_PAGEMD_MODIFIED_P(mdpg)) {
+ pmap_page_set_attributes(mdpg, VM_PAGEMD_MODIFIED);
}
pte &= ~PTE_UNMODIFIED;
*ptep = pte;
@@ -294,19 +295,20 @@
const paddr_t pa = pte_to_paddr(pte);
struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
KASSERT(pg);
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
UVMHIST_LOG(pmapexechist,
"srr0=%#x pg=%p (pa %#"PRIxPADDR"): %s",
tf->tf_srr0, pg, pa,
- (VM_PAGE_MD_EXECPAGE_P(pg)
+ (VM_PAGEMD_EXECPAGE_P(mdpg)
? "no syncicache (already execpage)"
: "performed syncicache (now execpage)"));
- if (!VM_PAGE_MD_EXECPAGE_P(pg)) {
+ if (!VM_PAGEMD_EXECPAGE_P(mdpg)) {
ci->ci_softc->cpu_ev_exec_trap_sync.ev_count++;
dcache_wb_page(pa);
icache_inv_page(pa);
- pmap_page_set_attributes(pg, VM_PAGE_MD_EXECPAGE);
+ pmap_page_set_attributes(mdpg, VM_PAGEMD_EXECPAGE);
}
pte &= ~PTE_UNSYNCED;
pte |= PTE_xX;
Index: src/sys/arch/powerpc/include/intr.h
diff -u src/sys/arch/powerpc/include/intr.h:1.8 src/sys/arch/powerpc/include/intr.h:1.9
--- src/sys/arch/powerpc/include/intr.h:1.8 Fri Jun 17 23:36:17 2011
+++ src/sys/arch/powerpc/include/intr.h Mon Jun 20 20:24:28 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.8 2011/06/17 23:36:17 matt Exp $ */
+/* $NetBSD: intr.h,v 1.9 2011/06/20 20:24:28 matt Exp $ */
/*-
* Copyright (c) 2007 Michael Lorenz
@@ -28,7 +28,7 @@
#ifndef _LOCORE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.h,v 1.8 2011/06/17 23:36:17 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.h,v 1.9 2011/06/20 20:24:28 matt Exp $");
#endif
#ifndef POWERPC_INTR_MACHDEP_H
@@ -36,12 +36,6 @@
#define __HAVE_FAST_SOFTINTS 1
-#ifndef _LOCORE
-void *intr_establish(int, int, int, int (*)(void *), void *);
-void intr_disestablish(void *);
-const char *intr_typename(int);
-void genppc_cpu_configure(void);
-#endif
/* Interrupt priority `levels'. */
#define IPL_NONE 0 /* nothing */
@@ -60,7 +54,20 @@
#define IST_EDGE 2 /* edge-triggered */
#define IST_LEVEL 3 /* level-triggered */
-#ifndef _LOCORE
+#if !defined(_LOCORE)
+void * intr_establish(int, int, int, int (*)(void *), void *);
+void intr_disestablish(void *);
+const char *
+ intr_typename(int);
+
+int splraise(int);
+int spllower(int);
+void splx(int);
+
+#if !defined(_MODULE)
+
+void genppc_cpu_configure(void);
+
/*
* Interrupt handler chains. intr_establish() inserts a handler into
* the list. The handler is called with its (single) argument.
@@ -73,13 +80,9 @@
int ih_virq;
};
-int splraise(int);
-int spllower(int);
-void splx(int);
-
void softint_fast_dispatch(struct lwp *, int);
-#define softint_init_md powerpc_softint_init_md
+#define softint_init_md powerpc_softint_init_md
#define softint_trigger powerpc_softint_trigger
#ifdef __IMASK_T
@@ -101,6 +104,8 @@
#define PIC_VIRQ_TO_MASK(v) __BIT(HWIRQ_MAX - (v))
#define PIC_VIRQ_MS_PENDING(p) __builtin_clz(p)
+#endif /* !_MODULE */
+
#define spl0() spllower(0)
typedef int ipl_t;
Index: src/sys/arch/powerpc/include/pmap.h
diff -u src/sys/arch/powerpc/include/pmap.h:1.36 src/sys/arch/powerpc/include/pmap.h:1.37
--- src/sys/arch/powerpc/include/pmap.h:1.36 Mon Jun 20 08:07:03 2011
+++ src/sys/arch/powerpc/include/pmap.h Mon Jun 20 20:24:28 2011
@@ -1,15 +1,43 @@
-/* $NetBSD: pmap.h,v 1.36 2011/06/20 08:07:03 matt Exp $ */
+/* $NetBSD: pmap.h,v 1.37 2011/06/20 20:24:28 matt Exp $ */
+
+#ifndef _POWERPC_PMAP_H_
+#define _POWERPC_PMAP_H_
#ifdef _KERNEL_OPT
#include "opt_ppcarch.h"
+#include "opt_modular.h"
#endif
-#ifdef PPC_IBM4XX
-#include <powerpc/ibm4xx/pmap.h>
-#elif defined(PPC_BOOKE)
+#if !defined(_MODULE)
+
+#if defined(PPC_BOOKE)
#include <powerpc/booke/pmap.h>
+#elif defined(PPC_IBM4XX)
+#include <powerpc/ibm4xx/pmap.h>
#elif defined(PPC_OEA) || defined (PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
#include <powerpc/oea/pmap.h>
#else
#error unknown PPC variant
#endif
+
+#endif /* !_MODULE */
+
+#if !defined(_LOCORE) && (defined(MODULAR) || defined(_MODULE))
+/*
+ * Both BOOKE and OEA use __HAVE_VM_PAGE_MD but IBM4XX doesn't so define
+ * a compatible vm_page_md so that struct vm_page is the same size for all
+ * PPC variants.
+ */
+#ifndef __HAVE_VM_PAGE_MD
+#define __HAVE_VM_PAGE_MD
+
+struct vm_page_md {
+ uintptr_t mdpg_dummy[5];
+};
+#endif /* !__HVE_VM_PAGE_MD */
+
+__CTASSERT(sizeof(struct vm_page_md) == sizeof(uintptr_t)*5);
+
+#endif /* !LOCORE && (MODULAR || _MODULE) */
+
+#endif /* !_POWERPC_PMAP_H_ */
Index: src/sys/arch/powerpc/include/vmparam.h
diff -u src/sys/arch/powerpc/include/vmparam.h:1.14 src/sys/arch/powerpc/include/vmparam.h:1.15
--- src/sys/arch/powerpc/include/vmparam.h:1.14 Mon Jun 20 08:01:14 2011
+++ src/sys/arch/powerpc/include/vmparam.h Mon Jun 20 20:24:28 2011
@@ -1,9 +1,52 @@
-/* $NetBSD: vmparam.h,v 1.14 2011/06/20 08:01:14 matt Exp $ */
+/* $NetBSD: vmparam.h,v 1.15 2011/06/20 20:24:28 matt Exp $ */
+
+#ifndef _POWERPC_VMPARAM_H_
+#define _POWERPC_VMPARAM_H_
#ifdef _KERNEL_OPT
+#include "opt_modular.h"
#include "opt_ppcarch.h"
+#include "opt_uvm.h"
#endif
+/*
+ * These are common for BOOKE, IBM4XX, and OEA
+ */
+#define VM_FREELIST_DEFAULT 0
+#define VM_FREELIST_FIRST256 1
+#define VM_FREELIST_FIRST16 2
+#define VM_NFREELIST 3
+
+#define VM_PHYSSEG_MAX 16
+
+/*
+ * The address to which unspecified mapping requests default
+ * Put the stack in it's own segment and start mmaping at the
+ * top of the next lower segment.
+ */
+#define __USE_TOPDOWN_VM
+#define VM_DEFAULT_ADDRESS(da, sz) \
+ ((VM_MAXUSER_ADDRESS - MAXSSIZ) - round_page(sz))
+
+#if defined(_MODULE)
+/*
+ * If we are a module, then we need with varible page sizes since BOOKE and OEA
+ * use 4KB pages while IBM4XX use 16KB pages.
+ */
+#define MIN_PAGE_SIZE 4096 /* BOOKE/OEA */
+#define MAX_PAGE_SIZE 16384 /* IBM4XX */
+
+/*
+ * Some modules need some of the constants but those vary between the variants
+ * so those constants are exported as linker symbols so they don't take up any
+ * space but also avoid an extra load to put into a register.
+ */
+extern const char __USRSTACK; /* let the linker resolve it */
+
+#define USRSTACK ((vaddr_t)(uintptr_t)&__USRSTACK)
+
+#else /* !_MODULE */
+
#if defined(PPC_BOOKE)
#include <powerpc/booke/vmparam.h>
#elif defined(PPC_IBM4XX)
@@ -13,3 +56,23 @@
#else
#error unknown PPC variant
#endif
+
+#endif /* !_MODULE */
+
+#if defined(MODULAR) || defined(_MODULAR)
+/*
+ * If we are a module or support modules, we need to define a compatible
+ * pmap_physseg since IBM4XX uses one. This will waste a tiny of space
+ * but is needed for compatibility.
+ */
+#ifndef __HAVE_PMAP_PHYSSEG
+#define __HAVE_PMAP_PHYSSEG
+struct pmap_physseg {
+ uintptr_t pmseg_dummy[2];
+};
+#endif
+
+__CTASSERT(sizeof(struct pmap_physseg) == sizeof(uintptr_t) * 2);
+#endif /* MODULAR || _MODULE */
+
+#endif /* !_POWERPC_VMPARAM_H_ */
Index: src/sys/arch/powerpc/include/booke/pmap.h
diff -u src/sys/arch/powerpc/include/booke/pmap.h:1.5 src/sys/arch/powerpc/include/booke/pmap.h:1.6
--- src/sys/arch/powerpc/include/booke/pmap.h:1.5 Sun Jun 5 16:52:25 2011
+++ src/sys/arch/powerpc/include/booke/pmap.h Mon Jun 20 20:24:28 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.5 2011/06/05 16:52:25 matt Exp $ */
+/* $NetBSD: pmap.h,v 1.6 2011/06/20 20:24:28 matt Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -40,6 +40,10 @@
#error use assym.h instead
#endif
+#if defined(_MODULE)
+#error this file should not be included by loadable kernel modules
+#endif
+
#include <sys/cpu.h>
#include <sys/kcore.h>
#include <uvm/uvm_page.h>
@@ -51,6 +55,8 @@
#define PMAP_MD_NOCACHE 0x01000000
#define PMAP_NEED_PROCWR
+#include <common/pmap/tlb/vmpagemd.h>
+
#include <powerpc/booke/pte.h>
#define NBSEG (NBPG*NPTEPG)
@@ -64,7 +70,6 @@
#define PMAP_TLB_NUM_PIDS 256
#define PMAP_INVALID_SEGTAB_ADDRESS ((struct pmap_segtab *)0xfeeddead)
-#ifndef _LOCORE
#define pmap_phys_address(x) (x)
void pmap_procwr(struct proc *, vaddr_t, size_t);
@@ -120,6 +125,5 @@
#define POOL_PHYSTOV(pa) ((vaddr_t)(paddr_t)(pa))
#include <common/pmap/tlb/pmap.h>
-#endif /* _LOCORE */
#endif /* !_POWERPC_BOOKE_PMAP_H_ */
Index: src/sys/arch/powerpc/include/booke/pte.h
diff -u src/sys/arch/powerpc/include/booke/pte.h:1.2 src/sys/arch/powerpc/include/booke/pte.h:1.3
--- src/sys/arch/powerpc/include/booke/pte.h:1.2 Tue Jan 18 01:02:54 2011
+++ src/sys/arch/powerpc/include/booke/pte.h Mon Jun 20 20:24:28 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pte.h,v 1.2 2011/01/18 01:02:54 matt Exp $ */
+/* $NetBSD: pte.h,v 1.3 2011/06/20 20:24:28 matt Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -180,17 +180,17 @@
}
static inline pt_entry_t
-pte_prot_bits(struct vm_page *pg, vm_prot_t prot)
+pte_prot_bits(struct vm_page_md *mdpg, vm_prot_t prot)
{
KASSERT(prot & VM_PROT_READ);
pt_entry_t pt_entry = PTE_xR;
if (prot & VM_PROT_EXECUTE) {
#if 0
pt_entry |= PTE_xX;
- if (pg != NULL && !VM_PAGE_MD_EXECPAGE_P(pg))
+ if (mdpg != NULL && !VM_PAGEMD_EXECPAGE_P(mdpg))
pt_entry |= PTE_UNSYNCED;
#elif 1
- if (pg != NULL && !VM_PAGE_MD_EXECPAGE_P(pg))
+ if (mdpg != NULL && !VM_PAGEMD_EXECPAGE_P(mdpg))
pt_entry |= PTE_UNSYNCED;
else
pt_entry |= PTE_xX;
@@ -200,23 +200,23 @@
}
if (prot & VM_PROT_WRITE) {
pt_entry |= PTE_xW;
- if (pg != NULL && !VM_PAGE_MD_MODIFIED_P(pg))
+ if (mdpg != NULL && !VM_PAGEMD_MODIFIED_P(mdpg))
pt_entry |= PTE_UNMODIFIED;
}
return pt_entry;
}
static inline pt_entry_t
-pte_flag_bits(struct vm_page *pg, int flags)
+pte_flag_bits(struct vm_page_md *mdpg, int flags)
{
if (__predict_false(flags & PMAP_MD_NOCACHE)) {
- if (__predict_true(pg != NULL)) {
+ if (__predict_true(mdpg != NULL)) {
return pte_nocached_bits();
} else {
return pte_ionocached_bits();
}
} else {
- if (__predict_false(pg != NULL)) {
+ if (__predict_false(mdpg != NULL)) {
return pte_cached_bits();
} else {
return pte_iocached_bits();
@@ -225,24 +225,24 @@
}
static inline pt_entry_t
-pte_make_enter(paddr_t pa, struct vm_page *pg, vm_prot_t prot,
+pte_make_enter(paddr_t pa, struct vm_page_md *mdpg, vm_prot_t prot,
int flags, bool kernel)
{
pt_entry_t pt_entry = (pt_entry_t) pa & PTE_RPN_MASK;
- pt_entry |= pte_flag_bits(pg, flags);
- pt_entry |= pte_prot_bits(pg, prot);
+ pt_entry |= pte_flag_bits(mdpg, flags);
+ pt_entry |= pte_prot_bits(mdpg, prot);
return pt_entry;
}
static inline pt_entry_t
-pte_make_kenter_pa(paddr_t pa, struct vm_page *pg, vm_prot_t prot,
+pte_make_kenter_pa(paddr_t pa, struct vm_page_md *mdpg, vm_prot_t prot,
int flags)
{
pt_entry_t pt_entry = (pt_entry_t) pa & PTE_RPN_MASK;
- pt_entry |= pte_flag_bits(pg, flags);
+ pt_entry |= pte_flag_bits(mdpg, flags);
pt_entry |= pte_prot_bits(NULL, prot); /* pretend unmanaged */
return pt_entry;
Index: src/sys/arch/powerpc/include/booke/vmparam.h
diff -u src/sys/arch/powerpc/include/booke/vmparam.h:1.4 src/sys/arch/powerpc/include/booke/vmparam.h:1.5
--- src/sys/arch/powerpc/include/booke/vmparam.h:1.4 Sun Jun 5 16:52:25 2011
+++ src/sys/arch/powerpc/include/booke/vmparam.h Mon Jun 20 20:24:28 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: vmparam.h,v 1.4 2011/06/05 16:52:25 matt Exp $ */
+/* $NetBSD: vmparam.h,v 1.5 2011/06/20 20:24:28 matt Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -37,8 +37,6 @@
#ifndef _POWERPC_BOOKE_VMPARAM_H_
#define _POWERPC_BOOKE_VMPARAM_H_
-#include <sys/mutex.h>
-
/*
* Most of the definitions in this can be overriden by a machine-specific
* vmparam.h if required. Otherwise a port can just include this file
@@ -102,97 +100,12 @@
#define VM_MIN_KERNEL_ADDRESS ((vaddr_t) 0xe4000000)
#define VM_MAX_KERNEL_ADDRESS ((vaddr_t) 0xfefff000)
-/*
- * The address to which unspecified mapping requests default
- * Put the stack in it's own segment and start mmaping at the
- * top of the next lower segment.
- */
-#ifdef _KERNEL_OPT
-#include "opt_uvm.h"
-#endif
-#define __USE_TOPDOWN_VM
-#define VM_DEFAULT_ADDRESS(da, sz) \
- ((VM_MAXUSER_ADDRESS - MAXSSIZ) - round_page(sz))
-
-#ifndef VM_PHYSSEG_MAX
-#define VM_PHYSSEG_MAX 16
-#endif
#define VM_PHYSSEG_STRAT VM_PSTRAT_BIGFIRST
#ifndef VM_PHYS_SIZE
#define VM_PHYS_SIZE (USRIOSIZE * PAGE_SIZE)
#endif
-#define VM_NFREELIST 2 /* 16 distinct memory segments */
-#define VM_FREELIST_DEFAULT 0
-#define VM_FREELIST_FIRST16 1
-#define VM_FREELIST_MAX 2
-
-#ifndef VM_NFREELIST
-#define VM_NFREELIST 16 /* 16 distinct memory segments */
-#define VM_FREELIST_DEFAULT 0
-#define VM_FREELIST_MAX 1
-#endif
-
-#define __HAVE_VM_PAGE_MD
-#ifndef _LOCORE
-
-typedef struct pv_entry {
- struct pv_entry *pv_next;
- struct pmap *pv_pmap;
- vaddr_t pv_va;
-} *pv_entry_t;
-
-#define VM_PAGE_MD_REFERENCED 0x0001 /* page has been recently referenced */
-#define VM_PAGE_MD_MODIFIED 0x0002 /* page has been modified */
-#define VM_PAGE_MD_POOLPAGE 0x0004 /* page is used as a poolpage */
-#define VM_PAGE_MD_EXECPAGE 0x0008 /* page is exec mapped */
-#if 0
-#define VM_PAGE_MD_UNCACHED 0x0010 /* page is mapped uncached */
-#endif
-
-#ifdef VM_PAGE_MD_UNCACHED
-#define VM_PAGE_MD_CACHED_P(pg) (((pg)->mdpage.mdpg_attrs & VM_PAGE_MD_UNCACHED) == 0)
-#define VM_PAGE_MD_UNCACHED_P(pg) (((pg)->mdpage.mdpg_attrs & VM_PAGE_MD_UNCACHED) != 0)
-#endif
-#define VM_PAGE_MD_MODIFIED_P(pg) (((pg)->mdpage.mdpg_attrs & VM_PAGE_MD_MODIFIED) != 0)
-#define VM_PAGE_MD_REFERENCED_P(pg) (((pg)->mdpage.mdpg_attrs & VM_PAGE_MD_REFERENCED) != 0)
-#define VM_PAGE_MD_POOLPAGE_P(pg) (((pg)->mdpage.mdpg_attrs & VM_PAGE_MD_POOLPAGE) != 0)
-#define VM_PAGE_MD_EXECPAGE_P(pg) (((pg)->mdpage.mdpg_attrs & VM_PAGE_MD_EXECPAGE) != 0)
-
-struct vm_page_md {
- struct pv_entry mdpg_first; /* pv_entry first */
-#ifdef MULTIPROCESSOR
- volatile u_int mdpg_attrs; /* page attributes */
- kmutex_t *mdpg_lock; /* pv list lock */
-#define VM_PAGE_PVLIST_LOCK_INIT(pg) \
- (pg)->mdpage.mdpg_lock = NULL
-#define VM_PAGE_PVLIST_LOCKED_P(pg) \
- (mutex_owner((pg)->mdpage.mdpg_lock) != 0)
-#define VM_PAGE_PVLIST_LOCK(pg, list_change) \
- pmap_pvlist_lock(pg, list_change)
-#define VM_PAGE_PVLIST_UNLOCK(pg) \
- mutex_spin_exit((pg)->mdpage.mdpg_lock);
-#define VM_PAGE_PVLIST_GEN(pg) ((uint16_t)(pg->mdpage.mdpg_attrs >> 16))
-#else
- u_int mdpg_attrs; /* page attributes */
-#define VM_PAGE_PVLIST_LOCK_INIT(pg) do { } while (/*CONSTCOND*/ 0)
-#define VM_PAGE_PVLIST_LOCKED_P(pg) true
-#define VM_PAGE_PVLIST_LOCK(pg, lc) (mutex_spin_enter(&pmap_pvlist_mutex), 0)
-#define VM_PAGE_PVLIST_UNLOCK(pg) mutex_spin_exit(&pmap_pvlist_mutex)
-#define VM_PAGE_PVLIST_GEN(pg) (0)
-#endif
-};
-
-#define VM_MDPAGE_INIT(pg) \
-do { \
- (pg)->mdpage.mdpg_first.pv_next = NULL; \
- (pg)->mdpage.mdpg_first.pv_pmap = NULL; \
- (pg)->mdpage.mdpg_first.pv_va = (pg)->phys_addr; \
- VM_PAGE_PVLIST_LOCK_INIT(pg); \
- (pg)->mdpage.mdpg_attrs = 0; \
-} while (/* CONSTCOND */ 0)
-
-#endif /* _LOCORE */
+#include <common/pmap/tlb/vmpagemd.h>
#endif /* _POWERPC_BOOKE_VMPARAM_H_ */
Index: src/sys/arch/powerpc/include/ibm4xx/pmap.h
diff -u src/sys/arch/powerpc/include/ibm4xx/pmap.h:1.15 src/sys/arch/powerpc/include/ibm4xx/pmap.h:1.16
--- src/sys/arch/powerpc/include/ibm4xx/pmap.h:1.15 Tue Jan 18 01:02:54 2011
+++ src/sys/arch/powerpc/include/ibm4xx/pmap.h Mon Jun 20 20:24:28 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.15 2011/01/18 01:02:54 matt Exp $ */
+/* $NetBSD: pmap.h,v 1.16 2011/06/20 20:24:28 matt Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -69,6 +69,14 @@
#ifndef _IBM4XX_PMAP_H_
#define _IBM4XX_PMAP_H_
+#ifdef _LOCORE
+#error use assym.h instead
+#endif
+
+#if defined(_MODULE)
+#error this file should not be included by loadable kernel modules
+#endif
+
#include <powerpc/ibm4xx/tlb.h>
#define KERNEL_PID 1 /* TLB PID to use for kernel translation */
@@ -132,8 +140,6 @@
#define PME_WRITETHROUG 0x2000000
#define PMAP_MD_NOCACHE PME_NOCACHE /* XXX: OEA pmap compat. for bus_dma */
-#ifndef _LOCORE
-
/*
* Pmap stuff
*/
@@ -203,5 +209,4 @@
return va;
}
#endif /* _KERNEL */
-#endif /* _LOCORE */
#endif /* _IBM4XX_PMAP_H_ */
Index: src/sys/arch/powerpc/include/ibm4xx/vmparam.h
diff -u src/sys/arch/powerpc/include/ibm4xx/vmparam.h:1.8 src/sys/arch/powerpc/include/ibm4xx/vmparam.h:1.9
--- src/sys/arch/powerpc/include/ibm4xx/vmparam.h:1.8 Sat Nov 6 16:36:27 2010
+++ src/sys/arch/powerpc/include/ibm4xx/vmparam.h Mon Jun 20 20:24:28 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: vmparam.h,v 1.8 2010/11/06 16:36:27 uebayasi Exp $ */
+/* $NetBSD: vmparam.h,v 1.9 2011/06/20 20:24:28 matt Exp $ */
/*-
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -109,10 +109,6 @@
char *attrs;
};
-#define VM_PHYSSEG_MAX 16 /* 1? */
#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH
-#define VM_NFREELIST 1
-#define VM_FREELIST_DEFAULT 0
-
#endif /* _MACHINE_VMPARAM_H_ */
Index: src/sys/arch/powerpc/include/oea/pmap.h
diff -u src/sys/arch/powerpc/include/oea/pmap.h:1.23 src/sys/arch/powerpc/include/oea/pmap.h:1.24
--- src/sys/arch/powerpc/include/oea/pmap.h:1.23 Mon Jun 20 08:07:03 2011
+++ src/sys/arch/powerpc/include/oea/pmap.h Mon Jun 20 20:24:29 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.23 2011/06/20 08:07:03 matt Exp $ */
+/* $NetBSD: pmap.h,v 1.24 2011/06/20 20:24:29 matt Exp $ */
/*-
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -34,12 +34,19 @@
#ifndef _POWERPC_OEA_PMAP_H_
#define _POWERPC_OEA_PMAP_H_
+#ifdef _LOCORE
+#error use assym.h instead
+#endif
+
+#if defined(_LKM) || defined(_MODULE)
+#error this file should not be included by loadable kernel modules
+#endif
+
#ifdef _KERNEL_OPT
#include "opt_ppcarch.h"
#endif
#include <powerpc/oea/pte.h>
-#ifndef _LOCORE
/*
* Pmap stuff
*/
@@ -224,17 +231,19 @@
#define __HAVE_VM_PAGE_MD
struct vm_page_md {
- struct pvo_head mdpg_pvoh;
unsigned int mdpg_attrs;
+ struct pvo_head mdpg_pvoh;
+#ifdef MODULAR
+ uintptr_t mdpg_dummy[3];
+#endif
};
#define VM_MDPAGE_INIT(pg) do { \
- LIST_INIT(&(pg)->mdpage.mdpg_pvoh); \
(pg)->mdpage.mdpg_attrs = 0; \
+ LIST_INIT(&(pg)->mdpage.mdpg_pvoh); \
} while (/*CONSTCOND*/0)
__END_DECLS
#endif /* _KERNEL */
-#endif /* _LOCORE */
#endif /* _POWERPC_OEA_PMAP_H_ */
Index: src/sys/arch/powerpc/include/oea/vmparam.h
diff -u src/sys/arch/powerpc/include/oea/vmparam.h:1.16 src/sys/arch/powerpc/include/oea/vmparam.h:1.17
--- src/sys/arch/powerpc/include/oea/vmparam.h:1.16 Sun Nov 14 13:33:22 2010
+++ src/sys/arch/powerpc/include/oea/vmparam.h Mon Jun 20 20:24:29 2011
@@ -163,21 +163,6 @@
#define VM_MIN_KERNEL_ADDRESS ((vaddr_t) (KERNEL_SR << ADDR_SR_SHFT))
#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + 2*SEGMENT_LENGTH)
-/*
- * The address to which unspecified mapping requests default
- * Put the stack in it's own segment and start mmaping at the
- * top of the next lower segment.
- */
-#ifdef _KERNEL_OPT
-#include "opt_uvm.h"
-#endif
-#define __USE_TOPDOWN_VM
-#define VM_DEFAULT_ADDRESS(da, sz) \
- (((VM_MAXUSER_ADDRESS - MAXSSIZ) & SEGMENT_MASK) - round_page(sz))
-
-#ifndef VM_PHYSSEG_MAX
-#define VM_PHYSSEG_MAX 16
-#endif
#define VM_PHYSSEG_STRAT VM_PSTRAT_BIGFIRST
#ifndef VM_PHYS_SIZE
@@ -188,10 +173,4 @@
#define VM_MAX_KERNEL_BUF (SEGMENT_LENGTH * 3 / 4)
#endif
-#define VM_NFREELIST 16 /* 16 distinct memory segments */
-#define VM_FREELIST_DEFAULT 0
-#define VM_FREELIST_FIRST256 1
-#define VM_FREELIST_FIRST16 2
-#define VM_FREELIST_MAX 3
-
#endif /* _POWERPC_OEA_VMPARAM_H_ */
Index: src/sys/common/pmap/tlb/pmap.c
diff -u src/sys/common/pmap/tlb/pmap.c:1.5 src/sys/common/pmap/tlb/pmap.c:1.6
--- src/sys/common/pmap/tlb/pmap.c:1.5 Sun Jun 12 05:32:38 2011
+++ src/sys/common/pmap/tlb/pmap.c Mon Jun 20 20:24:29 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.5 2011/06/12 05:32:38 matt Exp $ */
+/* $NetBSD: pmap.c,v 1.6 2011/06/20 20:24:29 matt Exp $ */
/*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.5 2011/06/12 05:32:38 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.6 2011/06/20 20:24:29 matt Exp $");
/*
* Manages physical address maps.
@@ -95,8 +95,9 @@
* and to when physical maps must be made correct.
*/
-#include "opt_sysv.h"
+#include "opt_modular.h"
#include "opt_multiprocessor.h"
+#include "opt_sysv.h"
#define __PMAP_PRIVATE
@@ -278,9 +279,9 @@
*/
bool
-pmap_page_clear_attributes(struct vm_page *pg, u_int clear_attributes)
+pmap_page_clear_attributes(struct vm_page_md *mdpg, u_int clear_attributes)
{
- volatile u_int * const attrp = &VM_PAGE_TO_MD(pg)->mdpg_attrs;
+ volatile u_int * const attrp = &mdpg->mdpg_attrs;
#ifdef MULTIPROCESSOR
for (;;) {
u_int old_attr = *attrp;
@@ -300,12 +301,12 @@
}
void
-pmap_page_set_attributes(struct vm_page *pg, u_int set_attributes)
+pmap_page_set_attributes(struct vm_page_md *mdpg, u_int set_attributes)
{
#ifdef MULTIPROCESSOR
- atomic_or_uint(&VM_PAGE_TO_MD(pg)->mdpg_attrs, set_attributes);
+ atomic_or_uint(&mdpg->mdpg_attrs, set_attributes);
#else
- VM_PAGE_TO_MD(pg)->mdpg_attrs |= set_attributes;
+ mdpg->mdpg_attrs |= set_attributes;
#endif
}
@@ -315,9 +316,10 @@
#ifndef MULTIPROCESSOR
struct pmap * const curpmap = curcpu()->ci_curpm;
#endif
- pv_entry_t pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
+ pv_entry_t pv = &mdpg->mdpg_first;
__cpuset_t onproc = CPUSET_NULLSET;
- (void)VM_PAGE_PVLIST_LOCK(pg, false);
+ (void)VM_PAGEMD_PVLIST_LOCK(mdpg, false);
if (pv->pv_pmap != NULL) {
for (; pv != NULL; pv = pv->pv_next) {
#ifdef MULTIPROCESSOR
@@ -333,7 +335,7 @@
#endif
}
}
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
kpreempt_disable();
pmap_md_page_syncicache(pg, onproc);
kpreempt_enable();
@@ -695,6 +697,7 @@
void
pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
{
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
pv_entry_t pv;
vaddr_t va;
@@ -711,28 +714,28 @@
/* copy_on_write */
case VM_PROT_READ:
case VM_PROT_READ|VM_PROT_EXECUTE:
- (void)VM_PAGE_PVLIST_LOCK(pg, false);
- pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ (void)VM_PAGEMD_PVLIST_LOCK(mdpg, false);
+ pv = &mdpg->mdpg_first;
/*
* Loop over all current mappings setting/clearing as apropos.
*/
if (pv->pv_pmap != NULL) {
while (pv != NULL) {
const pmap_t pmap = pv->pv_pmap;
- const uint16_t gen = VM_PAGE_PVLIST_GEN(pg);
+ const uint16_t gen = VM_PAGEMD_PVLIST_GEN(mdpg);
va = pv->pv_va;
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
pmap_protect(pmap, va, va + PAGE_SIZE, prot);
KASSERT(pv->pv_pmap == pmap);
pmap_update(pmap);
- if (gen != VM_PAGE_PVLIST_LOCK(pg, false)) {
- pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ if (gen != VM_PAGEMD_PVLIST_LOCK(mdpg, false)) {
+ pv = &mdpg->mdpg_first;
} else {
pv = pv->pv_next;
}
}
}
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
break;
/* remove_all */
@@ -741,22 +744,22 @@
* Do this first so that for each unmapping, pmap_remove_pv
* won't try to sync the icache.
*/
- if (pmap_page_clear_attributes(pg, VM_PAGE_MD_EXECPAGE)) {
+ if (pmap_page_clear_attributes(mdpg, VM_PAGEMD_EXECPAGE)) {
UVMHIST_LOG(pmapexechist, "pg %p (pa %#"PRIxPADDR
"): execpage cleared", pg, VM_PAGE_TO_PHYS(pg),0,0);
PMAP_COUNT(exec_uncached_page_protect);
}
- (void)VM_PAGE_PVLIST_LOCK(pg, false);
- pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ (void)VM_PAGEMD_PVLIST_LOCK(mdpg, false);
+ pv = &mdpg->mdpg_first;
while (pv->pv_pmap != NULL) {
const pmap_t pmap = pv->pv_pmap;
va = pv->pv_va;
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
pmap_remove(pmap, va, va + PAGE_SIZE);
pmap_update(pmap);
- (void)VM_PAGE_PVLIST_LOCK(pg, false);
+ (void)VM_PAGEMD_PVLIST_LOCK(mdpg, false);
}
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
}
UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0);
@@ -785,9 +788,10 @@
struct vm_page * const pg =
PHYS_TO_VM_PAGE(pte_to_paddr(pt_entry));
if (pg != NULL && pte_modified_p(pt_entry)) {
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
pmap_md_vca_clean(pg, sva, PMAP_WBINV);
- if (VM_PAGE_MD_EXECPAGE_P(pg)) {
- KASSERT(VM_PAGE_TO_MD(pg)->mdpg_first.pv_pmap != NULL);
+ if (VM_PAGEMD_EXECPAGE_P(mdpg)) {
+ KASSERT(mdpg->mdpg_first.pv_pmap != NULL);
UVMHIST_LOG(pmapexechist,
"pg %p (pa %#"PRIxPADDR"): %s",
pg, VM_PAGE_TO_PHYS(pg),
@@ -855,7 +859,7 @@
UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0);
}
-#if defined(VM_PAGE_MD_CACHED)
+#if defined(__PMAP_VIRTUAL_CACHE_ALIASES)
/*
* pmap_page_cache:
*
@@ -864,22 +868,23 @@
static void
pmap_page_cache(struct vm_page *pg, bool cached)
{
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
UVMHIST_LOG(pmaphist, "(pg=%p (pa %#"PRIxPADDR") cached=%s)",
pg, VM_PAGE_TO_PHYS(pg), cached ? "true" : "false", 0);
KASSERT(kpreempt_disabled());
if (cached) {
- pmap_page_clear_attributes(pg, VM_PAGE_MD_UNCACHED);
+ pmap_page_clear_attributes(mdpg, VM_PAGEMD_UNCACHED);
PMAP_COUNT(page_cache_restorations);
} else {
- pmap_page_set_attributes(pg, VM_PAGE_MD_UNCACHED);
+ pmap_page_set_attributes(mdpg, VM_PAGEMD_UNCACHED);
PMAP_COUNT(page_cache_evictions);
}
- KASSERT(VM_PAGE_PVLIST_LOCKED_P(pg));
+ KASSERT(VM_PAGEMD_PVLIST_LOCKED_P(mdpg));
KASSERT(kpreempt_disabled());
- for (pv_entry_t pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ for (pv_entry_t pv = &mdpg->mdpg_first;
pv != NULL;
pv = pv->pv_next) {
pmap_t pmap = pv->pv_pmap;
@@ -900,7 +905,7 @@
}
UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0);
}
-#endif /* VM_PAGE_MD_CACHED */
+#endif /* __PMAP_VIRTUAL_CACHE_ALIASES */
/*
* Insert the given physical page (p) at
@@ -954,16 +959,18 @@
("%s: no READ (%#x) in prot %#x", __func__, VM_PROT_READ, prot));
struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
+ struct vm_page_md *mdpg;
if (pg) {
+ mdpg = VM_PAGE_TO_MD(pg);
/* Set page referenced/modified status based on flags */
if (flags & VM_PROT_WRITE)
- pmap_page_set_attributes(pg, VM_PAGE_MD_MODIFIED|VM_PAGE_MD_REFERENCED);
+ pmap_page_set_attributes(mdpg, VM_PAGEMD_MODIFIED|VM_PAGEMD_REFERENCED);
else if (flags & VM_PROT_ALL)
- pmap_page_set_attributes(pg, VM_PAGE_MD_REFERENCED);
+ pmap_page_set_attributes(mdpg, VM_PAGEMD_REFERENCED);
-#ifdef VM_PAGE_MD_CACHED
- if (!VM_PAGE_MD_CACHED(pg))
+#ifdef __PMAP_VIRTUAL_CACHE_ALIASES
+ if (!VM_PAGEMD_CACHED(pg))
flags |= PMAP_NOCACHE;
#endif
@@ -973,11 +980,12 @@
* Assumption: if it is not part of our managed memory
* then it must be device memory which may be volatile.
*/
+ mdpg = NULL;
flags |= PMAP_NOCACHE;
PMAP_COUNT(unmanaged_mappings);
}
- npte = pte_make_enter(pa, pg, prot, flags, is_kernel_pmap_p);
+ npte = pte_make_enter(pa, mdpg, prot, flags, is_kernel_pmap_p);
kpreempt_disable();
pt_entry_t * const ptep = pmap_pte_reserve(pmap, va, flags);
@@ -1021,15 +1029,16 @@
kpreempt_enable();
if (pg != NULL && (prot == (VM_PROT_READ | VM_PROT_EXECUTE))) {
+ KASSERT(mdpg != NULL);
PMAP_COUNT(exec_mappings);
- if (!VM_PAGE_MD_EXECPAGE_P(pg) && pte_cached_p(npte)) {
+ if (!VM_PAGEMD_EXECPAGE_P(mdpg) && pte_cached_p(npte)) {
if (!pte_deferred_exec_p(npte)) {
UVMHIST_LOG(*histp,
"va=%#"PRIxVADDR" pg %p: %s syncicache%s",
va, pg, "immediate", "");
pmap_page_syncicache(pg);
- pmap_page_set_attributes(pg,
- VM_PAGE_MD_EXECPAGE);
+ pmap_page_set_attributes(mdpg,
+ VM_PAGEMD_EXECPAGE);
PMAP_COUNT(exec_synced_mappings);
} else {
UVMHIST_LOG(*histp, "va=%#"PRIxVADDR
@@ -1045,10 +1054,11 @@
: " (uncached)"));
}
} else if (pg != NULL && (prot & VM_PROT_EXECUTE)) {
+ KASSERT(mdpg != NULL);
KASSERT(prot & VM_PROT_WRITE);
PMAP_COUNT(exec_mappings);
pmap_page_syncicache(pg);
- pmap_page_clear_attributes(pg, VM_PAGE_MD_EXECPAGE);
+ pmap_page_clear_attributes(mdpg, VM_PAGEMD_EXECPAGE);
UVMHIST_LOG(pmapexechist,
"va=%#"PRIxVADDR" pg %p: %s syncicache%s",
va, pg, "immediate", " (writeable)");
@@ -1066,21 +1076,25 @@
pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
{
struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
+ struct vm_page_md *mdpg;
UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
UVMHIST_LOG(pmaphist, "(va=%#"PRIxVADDR" pa=%#"PRIxPADDR
", prot=%#x, flags=%#x)", va, pa, prot, flags);
PMAP_COUNT(kenter_pa);
- if (!PMAP_PAGE_COLOROK_P(pa, va) && pg != NULL)
- PMAP_COUNT(kenter_pa_bad);
-
if (pg == NULL) {
+ mdpg = NULL;
PMAP_COUNT(kenter_pa_unmanaged);
flags |= PMAP_NOCACHE;
+ } else {
+ mdpg = VM_PAGE_TO_MD(pg);
}
- const pt_entry_t npte = pte_make_kenter_pa(pa, pg, prot, flags)
+ if ((flags & PMAP_NOCACHE) == 0 && !PMAP_PAGE_COLOROK_P(pa, va))
+ PMAP_COUNT(kenter_pa_bad);
+
+ const pt_entry_t npte = pte_make_kenter_pa(pa, mdpg, prot, flags)
| pte_wired_entry();
kpreempt_disable();
pt_entry_t * const ptep = pmap_pte_reserve(pmap_kernel(), va, 0);
@@ -1285,11 +1299,13 @@
bool
pmap_clear_reference(struct vm_page *pg)
{
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
+
UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
UVMHIST_LOG(pmaphist, "(pg=%p (pa %#"PRIxPADDR"))",
pg, VM_PAGE_TO_PHYS(pg), 0,0);
- bool rv = pmap_page_clear_attributes(pg, VM_PAGE_MD_REFERENCED);
+ bool rv = pmap_page_clear_attributes(mdpg, VM_PAGEMD_REFERENCED);
UVMHIST_LOG(pmaphist, "<- %s", rv ? "true" : "false", 0,0,0);
@@ -1306,7 +1322,7 @@
pmap_is_referenced(struct vm_page *pg)
{
- return VM_PAGE_MD_REFERENCED_P(pg);
+ return VM_PAGEMD_REFERENCED_P(VM_PAGE_TO_MD(pg));
}
/*
@@ -1315,7 +1331,8 @@
bool
pmap_clear_modify(struct vm_page *pg)
{
- pv_entry_t pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
+ pv_entry_t pv = &mdpg->mdpg_first;
pv_entry_t pv_next;
uint16_t gen;
@@ -1324,12 +1341,12 @@
pg, VM_PAGE_TO_PHYS(pg), 0,0);
PMAP_COUNT(clear_modify);
- if (VM_PAGE_MD_EXECPAGE_P(pg)) {
+ if (VM_PAGEMD_EXECPAGE_P(mdpg)) {
if (pv->pv_pmap == NULL) {
UVMHIST_LOG(pmapexechist,
"pg %p (pa %#"PRIxPADDR"): %s",
pg, VM_PAGE_TO_PHYS(pg), "execpage cleared", 0);
- pmap_page_clear_attributes(pg, VM_PAGE_MD_EXECPAGE);
+ pmap_page_clear_attributes(mdpg, VM_PAGEMD_EXECPAGE);
PMAP_COUNT(exec_uncached_clear_modify);
} else {
UVMHIST_LOG(pmapexechist,
@@ -1339,7 +1356,7 @@
PMAP_COUNT(exec_synced_clear_modify);
}
}
- if (!pmap_page_clear_attributes(pg, VM_PAGE_MD_MODIFIED)) {
+ if (!pmap_page_clear_attributes(mdpg, VM_PAGEMD_MODIFIED)) {
UVMHIST_LOG(pmaphist, "<- false", 0,0,0,0);
return false;
}
@@ -1354,7 +1371,7 @@
* flush the VAC first if there is one.
*/
kpreempt_disable();
- gen = VM_PAGE_PVLIST_LOCK(pg, false);
+ gen = VM_PAGEMD_PVLIST_LOCK(mdpg, false);
for (; pv != NULL; pv = pv_next) {
pmap_t pmap = pv->pv_pmap;
vaddr_t va = pv->pv_va;
@@ -1367,17 +1384,17 @@
}
pmap_md_vca_clean(pg, va, PMAP_WBINV);
*ptep = pt_entry;
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
pmap_tlb_invalidate_addr(pmap, va);
pmap_update(pmap);
- if (__predict_false(gen != VM_PAGE_PVLIST_LOCK(pg, false))) {
+ if (__predict_false(gen != VM_PAGEMD_PVLIST_LOCK(mdpg, false))) {
/*
* The list changed! So restart from the beginning.
*/
- pv_next = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ pv_next = &mdpg->mdpg_first;
}
}
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
kpreempt_enable();
UVMHIST_LOG(pmaphist, "<- true (mappings changed)", 0,0,0,0);
@@ -1394,7 +1411,7 @@
pmap_is_modified(struct vm_page *pg)
{
- return VM_PAGE_MD_MODIFIED_P(pg);
+ return VM_PAGEMD_MODIFIED_P(VM_PAGE_TO_MD(pg));
}
/*
@@ -1405,8 +1422,9 @@
void
pmap_set_modified(paddr_t pa)
{
- struct vm_page *pg = PHYS_TO_VM_PAGE(pa);
- pmap_page_set_attributes(pg, VM_PAGE_MD_MODIFIED | VM_PAGE_MD_REFERENCED);
+ struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
+ pmap_page_set_attributes(mdpg, VM_PAGEMD_MODIFIED|VM_PAGEMD_REFERENCED);
}
/******************** pv_entry management ********************/
@@ -1415,12 +1433,12 @@
pmap_check_pvlist(struct vm_page *pg)
{
#ifdef PARANOIADIAG
- pt_entry_t pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
+ pt_entry_t pv = &mdpg->mdpg_first;
if (pv->pv_pmap != NULL) {
for (; pv != NULL; pv = pv->pv_next) {
KASSERT(!pmap_md_direct_mapped_vaddr_p(pv->pv_va));
}
- pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
}
#endif /* PARANOIADIAG */
}
@@ -1432,6 +1450,7 @@
void
pmap_enter_pv(pmap_t pmap, vaddr_t va, struct vm_page *pg, u_int *npte)
{
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
pv_entry_t pv, npv, apv;
int16_t gen;
bool first = false;
@@ -1446,8 +1465,8 @@
KASSERT(pmap != pmap_kernel() || !pmap_md_direct_mapped_vaddr_p(va));
apv = NULL;
- pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
- gen = VM_PAGE_PVLIST_LOCK(pg, true);
+ pv = &mdpg->mdpg_first;
+ gen = VM_PAGEMD_PVLIST_LOCK(mdpg, true);
pmap_check_pvlist(pg);
again:
if (pv->pv_pmap == NULL) {
@@ -1458,8 +1477,8 @@
PMAP_COUNT(primary_mappings);
PMAP_COUNT(mappings);
first = true;
-#ifdef VM_PAGE_MD_UNCACHED
- pmap_page_clear_attributes(pg, VM_PAGE_MD_UNCACHED);
+#ifdef __PMAP_VIRTUAL_CACHE_ALIASES
+ pmap_page_clear_attributes(pg, VM_PAGEMD_UNCACHED);
#endif
pv->pv_pmap = pmap;
pv->pv_va = va;
@@ -1490,35 +1509,33 @@
va, pa, pt_entry);
#endif
PMAP_COUNT(remappings);
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
if (__predict_false(apv != NULL))
pmap_pv_free(apv);
return;
}
}
if (__predict_true(apv == NULL)) {
-#ifdef MULTIPROCESSOR
/*
* To allocate a PV, we have to release the PVLIST lock
* so get the page generation. We allocate the PV, and
* then reacquire the lock.
*/
- VM_PAGE_PVLIST_UNLOCK(pg);
-#endif
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
+
apv = (pv_entry_t)pmap_pv_alloc();
if (apv == NULL)
panic("pmap_enter_pv: pmap_pv_alloc() failed");
-#ifdef MULTIPROCESSOR
+
/*
* If the generation has changed, then someone else
* tinkered with this page so we should
* start over.
*/
uint16_t oldgen = gen;
- gen = VM_PAGE_PVLIST_LOCK(pg, true);
+ gen = VM_PAGEMD_PVLIST_LOCK(mdpg, true);
if (gen != oldgen)
goto again;
-#endif
}
npv = apv;
apv = NULL;
@@ -1529,7 +1546,7 @@
PMAP_COUNT(mappings);
}
pmap_check_pvlist(pg);
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
if (__predict_false(apv != NULL))
pmap_pv_free(apv);
@@ -1547,6 +1564,7 @@
void
pmap_remove_pv(pmap_t pmap, vaddr_t va, struct vm_page *pg, bool dirty)
{
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
pv_entry_t pv, npv;
bool last;
@@ -1557,9 +1575,9 @@
UVMHIST_LOG(pmaphist, "dirty=%s)", dirty ? "true" : "false", 0,0,0);
KASSERT(kpreempt_disabled());
- pv = &VM_PAGE_TO_MD(pg)->mdpg_first;
+ pv = &mdpg->mdpg_first;
- (void)VM_PAGE_PVLIST_LOCK(pg, true);
+ (void)VM_PAGEMD_PVLIST_LOCK(mdpg, true);
pmap_check_pvlist(pg);
/*
@@ -1576,8 +1594,8 @@
*pv = *npv;
KASSERT(pv->pv_pmap != NULL);
} else {
-#ifdef VM_PAGE_MD_UNCACHED
- pmap_page_clear_attributes(pg, VM_PAGE_MD_UNCACHED);
+#ifdef __PMAP_VIRTUAL_CACHE_ALIASES
+ pmap_page_clear_attributes(pg, VM_PAGEMD_UNCACHED);
#endif
pv->pv_pmap = NULL;
last = true; /* Last mapping removed */
@@ -1596,14 +1614,14 @@
pmap_md_vca_remove(pg, va);
pmap_check_pvlist(pg);
- VM_PAGE_PVLIST_UNLOCK(pg);
+ VM_PAGEMD_PVLIST_UNLOCK(mdpg);
/*
* Free the pv_entry if needed.
*/
if (npv)
pmap_pv_free(npv);
- if (VM_PAGE_MD_EXECPAGE_P(pg) && dirty) {
+ if (VM_PAGEMD_EXECPAGE_P(mdpg) && dirty) {
if (last) {
/*
* If this was the page's last mapping, we no longer
@@ -1614,7 +1632,7 @@
pg, VM_PAGE_TO_PHYS(pg),
last ? " [last mapping]" : "",
"execpage cleared");
- pmap_page_clear_attributes(pg, VM_PAGE_MD_EXECPAGE);
+ pmap_page_clear_attributes(mdpg, VM_PAGEMD_EXECPAGE);
PMAP_COUNT(exec_uncached_remove);
} else {
/*
@@ -1633,7 +1651,7 @@
UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0);
}
-#ifdef MULTIPROCESSOR
+#if defined(MULTIPROCESSOR)
struct pmap_pvlist_info {
kmutex_t *pli_locks[PAGE_SIZE / 32];
volatile u_int pli_lock_refs[PAGE_SIZE / 32];
@@ -1664,10 +1682,10 @@
}
uint16_t
-pmap_pvlist_lock(struct vm_page *pg, bool list_change)
+pmap_pvlist_lock(struct vm_page_md *mdpg, bool list_change)
{
struct pmap_pvlist_info * const pli = &pmap_pvlist_info;
- kmutex_t *lock = VM_PAGE_TO_MD(pg)->mdpg_lock;
+ kmutex_t *lock = mdpg->mdpg_lock;
int16_t gen;
/*
@@ -1682,7 +1700,7 @@
* Set the lock. If some other thread already did, just use
* the one they assigned.
*/
- lock = atomic_cas_ptr(&VM_PAGE_TO_MD(pg)->mdpg_lock, NULL, new_lock);
+ lock = atomic_cas_ptr(&mdpg->mdpg_lock, NULL, new_lock);
if (lock == NULL) {
lock = new_lock;
atomic_inc_uint(&pli->pli_lock_refs[lockid]);
@@ -1698,22 +1716,42 @@
* If the locker will be changing the list, increment the high 16 bits
* of attrs so we use that as a generation number.
*/
- gen = VM_PAGE_PVLIST_GEN(pg); /* get old value */
+ gen = VM_PAGEMD_PVLIST_GEN(mdpg); /* get old value */
if (list_change)
- atomic_add_int(&VM_PAGE_TO_MD(pg)->mdpg_attrs, 0x10000);
+ atomic_add_int(&mdpg->mdpg_attrs, 0x10000);
/*
* Return the generation number.
*/
return gen;
}
-#else
+#else /* !MULTIPROCESSOR */
void
pmap_pvlist_lock_init(size_t cache_line_size)
{
mutex_init(&pmap_pvlist_mutex, MUTEX_DEFAULT, IPL_VM);
}
-#endif /* MULTIPROCESSOR */
+
+#ifdef MODULAR
+uint16_t
+pmap_pvlist_lock(struct vm_page_md *mdpg, bool list_change)
+{
+ /*
+ * We just use a global lock.
+ */
+ if (__predict_false(mdpg->mdpg_lock == NULL)) {
+ mdpg->mdpg_lock = &pmap_pvlist_mutex;
+ }
+
+ /*
+ * Now finally lock the pvlists.
+ */
+ mutex_spin_enter(mdpg->mdpg_lock);
+
+ return 0;
+}
+#endif /* MODULAR */
+#endif /* !MULTIPROCESSOR */
/*
* pmap_pv_page_alloc:
@@ -1743,8 +1781,9 @@
KASSERT(pmap_md_direct_mapped_vaddr_p(va));
const paddr_t pa = pmap_md_direct_mapped_vaddr_to_paddr(va);
struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
pmap_md_vca_remove(pg, va);
- pmap_page_clear_attributes(pg, VM_PAGE_MD_POOLPAGE);
+ pmap_page_clear_attributes(mdpg, VM_PAGEMD_POOLPAGE);
uvm_pagefree(pg);
}
@@ -1787,7 +1826,8 @@
struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
KASSERT(pg);
- pmap_page_set_attributes(pg, VM_PAGE_MD_POOLPAGE);
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
+ pmap_page_set_attributes(mdpg, VM_PAGEMD_POOLPAGE);
const vaddr_t va = pmap_md_direct_map_paddr(pa);
pmap_md_vca_add(pg, va, NULL);
@@ -1803,7 +1843,8 @@
struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
KASSERT(pg);
- pmap_page_clear_attributes(pg, VM_PAGE_MD_POOLPAGE);
+ struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
+ pmap_page_clear_attributes(mdpg, VM_PAGEMD_POOLPAGE);
pmap_md_vca_remove(pg, va);
return pa;
Index: src/sys/common/pmap/tlb/pmap.h
diff -u src/sys/common/pmap/tlb/pmap.h:1.4 src/sys/common/pmap/tlb/pmap.h:1.5
--- src/sys/common/pmap/tlb/pmap.h:1.4 Sun Jun 12 05:32:38 2011
+++ src/sys/common/pmap/tlb/pmap.h Mon Jun 20 20:24:29 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.4 2011/06/12 05:32:38 matt Exp $ */
+/* $NetBSD: pmap.h,v 1.5 2011/06/20 20:24:29 matt Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -221,8 +221,8 @@
*/
void pmap_remove_all(pmap_t);
void pmap_set_modified(paddr_t);
-bool pmap_page_clear_attributes(struct vm_page *, u_int);
-void pmap_page_set_attributes(struct vm_page *, u_int);
+bool pmap_page_clear_attributes(struct vm_page_md *, u_int);
+void pmap_page_set_attributes(struct vm_page_md *, u_int);
void pmap_pvlist_lock_init(size_t);
#define PMAP_WB 0
@@ -247,7 +247,7 @@
void pmap_tlb_invalidate_addr(pmap_t, vaddr_t);
void pmap_tlb_check(pmap_t);
-uint16_t pmap_pvlist_lock(struct vm_page *, bool);
+uint16_t pmap_pvlist_lock(struct vm_page_md *, bool);
#define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */