summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2011-10-09 17:08:23 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2011-10-09 17:08:23 +0000
commit9603ee675113a8054b9897b9580b4fda12921d86 (patch)
tree0e426ac1853b26fed6b4cbe0bba5b4eefb4cc4c1 /sys/arch
parent647dd25f73e043143b7399a54c7439ee7c3b3824 (diff)
Let BUS_DMA_COHERENT allocations return cache-inhibited pages.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/aviion/aviion/bus_dma.c4
-rw-r--r--sys/arch/m88k/include/pmap.h3
-rw-r--r--sys/arch/m88k/m88k/pmap.c51
-rw-r--r--sys/arch/mvme88k/mvme88k/bus_dma.c4
4 files changed, 58 insertions, 4 deletions
diff --git a/sys/arch/aviion/aviion/bus_dma.c b/sys/arch/aviion/aviion/bus_dma.c
index e6523c22818..9da9a61f9c1 100644
--- a/sys/arch/aviion/aviion/bus_dma.c
+++ b/sys/arch/aviion/aviion/bus_dma.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus_dma.c,v 1.4 2011/06/23 20:44:39 ariane Exp $ */
+/* $OpenBSD: bus_dma.c,v 1.5 2011/10/09 17:08:21 miod Exp $ */
/* $NetBSD: bus_dma.c,v 1.2 2001/06/10 02:31:25 briggs Exp $ */
/*-
@@ -548,6 +548,8 @@ bus_dmamem_map(t, segs, nsegs, size, kvap, flags)
uvm_km_free(kernel_map, sva, ssize);
return (error);
}
+ if (flags & BUS_DMA_COHERENT)
+ pmap_page_uncache(addr);
}
}
pmap_update(pmap_kernel());
diff --git a/sys/arch/m88k/include/pmap.h b/sys/arch/m88k/include/pmap.h
index 5f94e37bf9a..d2c89099c66 100644
--- a/sys/arch/m88k/include/pmap.h
+++ b/sys/arch/m88k/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.19 2011/01/05 22:20:22 miod Exp $ */
+/* $OpenBSD: pmap.h,v 1.20 2011/10/09 17:08:22 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1991 Carnegie Mellon University
@@ -62,6 +62,7 @@ extern apr_t default_apr;
void pmap_bootstrap(paddr_t, paddr_t);
void pmap_bootstrap_cpu(cpuid_t);
void pmap_cache_ctrl(vaddr_t, vaddr_t, u_int);
+void pmap_page_uncache(paddr_t);
#define pmap_unuse_final(p) /* nothing */
#define pmap_remove_holes(map) do { /* nothing */ } while (0)
int pmap_set_modify(pmap_t, vaddr_t);
diff --git a/sys/arch/m88k/m88k/pmap.c b/sys/arch/m88k/m88k/pmap.c
index 1ed8df971ef..26a14658bbf 100644
--- a/sys/arch/m88k/m88k/pmap.c
+++ b/sys/arch/m88k/m88k/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.66 2011/10/09 17:07:37 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.67 2011/10/09 17:08:22 miod Exp $ */
/*
* Copyright (c) 2001-2004, 2010, Miodrag Vallat.
@@ -1883,3 +1883,52 @@ pmap_cache_ctrl(vaddr_t sva, vaddr_t eva, u_int mode)
}
splx(s);
}
+
+/*
+ * [MD PUBLIC]
+ * Change the cache control bits of all mappings of the given physical page to
+ * disable cached accesses.
+ */
+void
+pmap_page_uncache(paddr_t pa)
+{
+ struct vm_page *pg = PHYS_TO_VM_PAGE(pa);
+ struct pmap *pmap;
+ pv_entry_t pvl, pvep;
+ pt_entry_t *pte, opte, npte;
+ vaddr_t va;
+ int s;
+
+ s = splvm();
+ pvl = pg_to_pvh(pg);
+ if (pvl->pv_pmap != NULL) {
+ for (pvep = pvl; pvep != NULL; pvep = pvep->pv_next) {
+ pmap = pvep->pv_pmap;
+ va = pvep->pv_va;
+ pte = pmap_pte(pmap, va);
+
+ if (pte == NULL || !PDT_VALID(pte))
+ continue; /* no page mapping */
+ opte = *pte;
+ if ((opte & CACHE_MASK) != CACHE_INH) {
+ /*
+ * Skip the direct mapping; it will be changed
+ * by the pmap_cache_ctrl() call below.
+ */
+ if (pmap == pmap_kernel() && va == pa)
+ continue;
+ /*
+ * Invalidate pte temporarily to avoid the
+ * specified bit being written back by any
+ * other cpu.
+ */
+ invalidate_pte(pte);
+ npte = (opte & ~CACHE_MASK) | CACHE_INH;
+ *pte = npte;
+ tlb_flush(pmap, va, npte);
+ }
+ }
+ }
+ splx(s);
+ pmap_cache_ctrl(pa, pa + PAGE_SIZE, CACHE_INH);
+}
diff --git a/sys/arch/mvme88k/mvme88k/bus_dma.c b/sys/arch/mvme88k/mvme88k/bus_dma.c
index 695619bc6c6..ca9bff72645 100644
--- a/sys/arch/mvme88k/mvme88k/bus_dma.c
+++ b/sys/arch/mvme88k/mvme88k/bus_dma.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus_dma.c,v 1.17 2011/06/23 20:44:39 ariane Exp $ */
+/* $OpenBSD: bus_dma.c,v 1.18 2011/10/09 17:08:22 miod Exp $ */
/* $NetBSD: bus_dma.c,v 1.2 2001/06/10 02:31:25 briggs Exp $ */
/*-
@@ -548,6 +548,8 @@ bus_dmamem_map(t, segs, nsegs, size, kvap, flags)
uvm_km_free(kernel_map, sva, ssize);
return (error);
}
+ if (flags & BUS_DMA_COHERENT)
+ pmap_page_uncache(addr);
}
}
pmap_update(pmap_kernel());