summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/booke/pmap.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2014-07-13 16:27:57 +0000
committeralc <alc@FreeBSD.org>2014-07-13 16:27:57 +0000
commit1c51afe84c8e7ee057d192f3ac03b0de8decf044 (patch)
treed57be68e67c187f2012e95d62973db4981de9c70 /sys/powerpc/booke/pmap.c
parentc2307b7d217885f63b555772df5ea0c4e4ea2fe5 (diff)
downloadFreeBSD-src-1c51afe84c8e7ee057d192f3ac03b0de8decf044.zip
FreeBSD-src-1c51afe84c8e7ee057d192f3ac03b0de8decf044.tar.gz
Implement pmap_unwire(). See r268327 for the motivation behind this change.
Diffstat (limited to 'sys/powerpc/booke/pmap.c')
-rw-r--r--sys/powerpc/booke/pmap.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 57df896..d640d90 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -306,6 +306,7 @@ static void mmu_booke_release(mmu_t, pmap_t);
static void mmu_booke_remove(mmu_t, pmap_t, vm_offset_t, vm_offset_t);
static void mmu_booke_remove_all(mmu_t, vm_page_t);
static void mmu_booke_remove_write(mmu_t, vm_page_t);
+static void mmu_booke_unwire(mmu_t, pmap_t, vm_offset_t, vm_offset_t);
static void mmu_booke_zero_page(mmu_t, vm_page_t);
static void mmu_booke_zero_page_area(mmu_t, vm_page_t, int, int);
static void mmu_booke_zero_page_idle(mmu_t, vm_page_t);
@@ -361,6 +362,7 @@ static mmu_method_t mmu_booke_methods[] = {
MMUMETHOD(mmu_remove_all, mmu_booke_remove_all),
MMUMETHOD(mmu_remove_write, mmu_booke_remove_write),
MMUMETHOD(mmu_sync_icache, mmu_booke_sync_icache),
+ MMUMETHOD(mmu_unwire, mmu_booke_unwire),
MMUMETHOD(mmu_zero_page, mmu_booke_zero_page),
MMUMETHOD(mmu_zero_page_area, mmu_booke_zero_page_area),
MMUMETHOD(mmu_zero_page_idle, mmu_booke_zero_page_idle),
@@ -2435,6 +2437,36 @@ mmu_booke_change_wiring(mmu_t mmu, pmap_t pmap, vm_offset_t va, boolean_t wired)
}
/*
+ * Clear the wired attribute from the mappings for the specified range of
+ * addresses in the given pmap. Every valid mapping within that range must
+ * have the wired attribute set. In contrast, invalid mappings cannot have
+ * the wired attribute set, so they are ignored.
+ *
+ * The wired attribute of the page table entry is not a hardware feature, so
+ * there is no need to invalidate any TLB entries.
+ */
+static void
+mmu_booke_unwire(mmu_t mmu, pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
+{
+ vm_offset_t va;
+ pte_t *pte;
+
+ PMAP_LOCK(pmap);
+ for (va = sva; va < eva; va += PAGE_SIZE) {
+ if ((pte = pte_find(mmu, pmap, va)) != NULL &&
+ PTE_ISVALID(pte)) {
+ if (!PTE_ISWIRED(pte))
+ panic("mmu_booke_unwire: pte %p isn't wired",
+ pte);
+ pte->flags &= ~PTE_WIRED;
+ pmap->pm_stats.wired_count--;
+ }
+ }
+ PMAP_UNLOCK(pmap);
+
+}
+
+/*
* Return true if the pmap's pv is one of the first 16 pvs linked to from this
* page. This count may be changed upwards or downwards in the future; it is
* only necessary that true be returned for a small subset of pmaps for proper
OpenPOWER on IntegriCloud