diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2011-10-09 17:08:23 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2011-10-09 17:08:23 +0000 |
commit | 9603ee675113a8054b9897b9580b4fda12921d86 (patch) | |
tree | 0e426ac1853b26fed6b4cbe0bba5b4eefb4cc4c1 /sys/arch | |
parent | 647dd25f73e043143b7399a54c7439ee7c3b3824 (diff) |
Let BUS_DMA_COHERENT allocations return cache-inhibited pages.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/aviion/aviion/bus_dma.c | 4 | ||||
-rw-r--r-- | sys/arch/m88k/include/pmap.h | 3 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/pmap.c | 51 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/bus_dma.c | 4 |
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()); |