diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-02-05 01:13:22 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-02-05 01:13:22 +0000 |
commit | 82fda29c886a059ab961cba463ebf312068065e5 (patch) | |
tree | 6a902aa43f70f9165ac27c861964668af599c3a1 | |
parent | 74f276ec4910fc7e6bcd3162c3804bd97011549a (diff) |
add MD PMAP_NOCACHE flag to i386 and use it to implement the
BUS_DMA_NOCACHE flag with guarantees that the dma memory will be mapped
uncached. Some broken/odd hardware needs this.
discussion with miod, toby, art and kettenis. ok miod.
-rw-r--r-- | sys/arch/i386/i386/bus_dma.c | 10 | ||||
-rw-r--r-- | sys/arch/i386/i386/pmap.c | 4 | ||||
-rw-r--r-- | sys/arch/i386/include/bus.h | 3 | ||||
-rw-r--r-- | sys/arch/i386/include/pmap.h | 6 |
4 files changed, 17 insertions, 6 deletions
diff --git a/sys/arch/i386/i386/bus_dma.c b/sys/arch/i386/i386/bus_dma.c index ab75b0d9bbe..f2fbc9ff40c 100644 --- a/sys/arch/i386/i386/bus_dma.c +++ b/sys/arch/i386/i386/bus_dma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bus_dma.c,v 1.2 2008/12/04 19:25:38 oga Exp $ */ +/* $OpenBSD: bus_dma.c,v 1.3 2009/02/05 01:13:21 oga Exp $ */ /*- * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. * All rights reserved. @@ -368,7 +368,10 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, { vaddr_t va; bus_addr_t addr; - int curseg; + int curseg, pmapflags; + + if (flags & BUS_DMA_NOCACHE) + pmapflags |= PMAP_NOCACHE; size = round_page(size); va = uvm_km_valloc(kernel_map, size); @@ -385,7 +388,8 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, panic("_bus_dmamem_map: size botch"); pmap_enter(pmap_kernel(), va, addr, VM_PROT_READ | VM_PROT_WRITE, - VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED); + VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED | + pmapflags); } } pmap_update(pmap_kernel()); diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c index 7e3ebfe7cd6..753298eb42a 100644 --- a/sys/arch/i386/i386/pmap.c +++ b/sys/arch/i386/i386/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.135 2009/01/27 22:14:13 miod Exp $ */ +/* $OpenBSD: pmap.c,v 1.136 2009/02/05 01:13:21 oga Exp $ */ /* $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $ */ /* @@ -2591,6 +2591,8 @@ enter_now: pmap_exec_account(pmap, va, opte, npte); if (wired) npte |= PG_W; + if (flags & PMAP_NOCACHE) + npte |= PG_N; if (va < VM_MAXUSER_ADDRESS) npte |= PG_u; else if (va < VM_MAX_ADDRESS) diff --git a/sys/arch/i386/include/bus.h b/sys/arch/i386/include/bus.h index 6a6ccbc933e..eb89149d0dc 100644 --- a/sys/arch/i386/include/bus.h +++ b/sys/arch/i386/include/bus.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bus.h,v 1.45 2008/12/03 15:46:06 oga Exp $ */ +/* $OpenBSD: bus.h,v 1.46 2009/02/05 01:13:21 oga Exp $ */ /* $NetBSD: bus.h,v 1.6 1996/11/10 03:19:25 thorpej Exp $ */ /*- @@ -452,6 +452,7 @@ void bus_space_copy_4(bus_space_tag_t, bus_space_handle_t, bus_size_t, #define BUS_DMA_STREAMING 0x100 /* hint: sequential, unidirectional */ #define BUS_DMA_READ 0x200 /* mapping is device -> memory only */ #define BUS_DMA_WRITE 0x400 /* mapping is memory -> device only */ +#define BUS_DMA_NOCACHE 0x800 /* map memory uncached */ /* Forwards needed by prototypes below. */ struct mbuf; diff --git a/sys/arch/i386/include/pmap.h b/sys/arch/i386/include/pmap.h index fa446e6c2a0..89af1a42440 100644 --- a/sys/arch/i386/include/pmap.h +++ b/sys/arch/i386/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.50 2008/12/18 14:17:28 kurt Exp $ */ +/* $OpenBSD: pmap.h,v 1.51 2009/02/05 01:13:21 oga Exp $ */ /* $NetBSD: pmap.h,v 1.44 2000/04/24 17:18:18 thorpej Exp $ */ /* @@ -292,6 +292,10 @@ struct pv_entry { /* locked by its list's pvh_lock */ vaddr_t pv_va; /* the virtual address */ struct vm_page *pv_ptp; /* the vm_page of the PTP */ }; +/* + * MD flags to pmap_enter: + */ +#define PMAP_NOCACHE PMAP_MD0 /* * We keep mod/ref flags in struct vm_page->pg_flags. |