summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2011-01-04 21:11:42 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2011-01-04 21:11:42 +0000
commit0199e2060a0344e1d9ea19ae477ea339bccc9da4 (patch)
treed9ad1d9dda3dec2abeefe36412d6d81cfe9f69f3 /sys
parent1ab5407939e49091e05c7ab1e0cd967c4be743bf (diff)
Introduce pmap_uncache_page(), created from the guts of pmap_kenter_cache()
to make a page uncached and maintain this both at the pte and pv list level, and make pmap_kenter_cache() use it. ok drahn@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm/arm/pmap.c45
-rw-r--r--sys/arch/arm/include/pmap.h3
2 files changed, 28 insertions, 20 deletions
diff --git a/sys/arch/arm/arm/pmap.c b/sys/arch/arm/arm/pmap.c
index 2be1a0f025e..2145366c68d 100644
--- a/sys/arch/arm/arm/pmap.c
+++ b/sys/arch/arm/arm/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.29 2010/12/06 20:57:13 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.30 2011/01/04 21:11:39 miod Exp $ */
/* $NetBSD: pmap.c,v 1.147 2004/01/18 13:03:50 scw Exp $ */
/*
@@ -1496,6 +1496,29 @@ pmap_vac_me_user(struct vm_page *pg, pmap_t pm, vaddr_t va)
}
/*
+ * Make a pmap_kernel() mapping uncached. Used by bus_dma for coherent pages.
+ */
+void
+pmap_uncache_page(paddr_t va, vaddr_t pa)
+{
+ struct vm_page *pg;
+ struct pv_entry *pv;
+ pt_entry_t *pte;
+
+ if ((pg = PHYS_TO_VM_PAGE(pa)) != NULL) {
+ simple_lock(&pg->mdpage.pvh_slock);
+ pv = pmap_find_pv(pg, pmap_kernel(), va);
+ if (pv != NULL)
+ pv->pv_flags |= PVF_NC;
+ simple_unlock(&pg->mdpage.pvh_slock);
+ }
+
+ pte = vtopte(va);
+ *pte &= ~L2_S_CACHE_MASK;
+ PTE_SYNC(pte);
+}
+
+/*
* Modify pte bits for all ptes corresponding to the given physical address.
* We use `maskbits' rather than `clearbits' because we're always passing
* constants and the latter would require an extra inversion at run-time.
@@ -2438,25 +2461,9 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
void
pmap_kenter_cache(vaddr_t va, paddr_t pa, vm_prot_t prot, int cacheable)
{
- struct vm_page *pg;
- struct pv_entry *pv;
- pt_entry_t *pte;
-
pmap_kenter_pa(va, pa, prot);
-
- if (cacheable == 0) {
- if ((pg = PHYS_TO_VM_PAGE(pa)) != NULL) {
- simple_lock(&pg->mdpage.pvh_slock);
- pv = pmap_find_pv(pg, pmap_kernel(), va);
- if (pv != NULL)
- pv->pv_flags |= PVF_NC;
- simple_unlock(&pg->mdpage.pvh_slock);
- }
-
- pte = vtopte(va);
- *pte &= ~L2_S_CACHE_MASK;
- PTE_SYNC(pte);
- }
+ if (cacheable == 0)
+ pmap_uncache_page(va, pa);
}
void
diff --git a/sys/arch/arm/include/pmap.h b/sys/arch/arm/include/pmap.h
index d06496bb188..51c2a23816f 100644
--- a/sys/arch/arm/include/pmap.h
+++ b/sys/arch/arm/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.15 2010/12/26 15:40:59 miod Exp $ */
+/* $OpenBSD: pmap.h,v 1.16 2011/01/04 21:11:41 miod Exp $ */
/* $NetBSD: pmap.h,v 1.76 2003/09/06 09:10:46 rearnsha Exp $ */
/*
@@ -253,6 +253,7 @@ extern int pmap_debug_level; /* Only exists if PMAP_DEBUG */
void pmap_procwr(struct proc *, vaddr_t, int);
void pmap_remove_all(pmap_t);
boolean_t pmap_extract(pmap_t, vaddr_t, paddr_t *);
+void pmap_uncache_page(paddr_t, vaddr_t);
#define PMAP_NEED_PROCWR
#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */