Module Name: src Committed By: matt Date: Sun Jan 27 17:38:55 UTC 2013
Modified Files: src/sys/arch/arm/arm32: bus_dma.c src/sys/arch/arm/broadcom: bcm2835_obio.c src/sys/arch/arm/include: bus_defs.h Log Message: Add a flag to make bus_dmamem_map use the bus/sys transation table when mapping bus addresses. Make bcm2835 obio use it. To generate a diff of this commit: cvs rdiff -u -r1.67 -r1.68 src/sys/arch/arm/arm32/bus_dma.c cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/broadcom/bcm2835_obio.c cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/include/bus_defs.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/arm32/bus_dma.c diff -u src/sys/arch/arm/arm32/bus_dma.c:1.67 src/sys/arch/arm/arm32/bus_dma.c:1.68 --- src/sys/arch/arm/arm32/bus_dma.c:1.67 Wed Jan 16 22:32:45 2013 +++ src/sys/arch/arm/arm32/bus_dma.c Sun Jan 27 17:38:55 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_dma.c,v 1.67 2013/01/16 22:32:45 matt Exp $ */ +/* $NetBSD: bus_dma.c,v 1.68 2013/01/27 17:38:55 matt Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #define _ARM32_BUS_DMA_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.67 2013/01/16 22:32:45 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.68 2013/01/27 17:38:55 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -970,7 +970,7 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm if (!bouncing && pre_ops == 0 && post_ops == BUS_DMASYNC_POSTWRITE) { return; } - + KASSERT(pre_ops != 0 || (post_ops & BUS_DMASYNC_POSTREAD)); #ifdef _ARM32_NEED_BUS_DMA_BOUNCE if (bouncing && (ops & BUS_DMASYNC_PREWRITE)) { struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie; @@ -1213,34 +1213,37 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma * avoid having a separate mapping for it. */ if (nsegs == 1) { - paddr_t paddr = segs[0].ds_addr; /* * If this is a non-COHERENT mapping, then the existing kernel * mapping is already compatible with it. */ - if ((flags & BUS_DMA_COHERENT) == 0) { -#ifdef DEBUG_DMA - printf("dmamem_map: =%p\n", *kvap); -#endif /* DEBUG_DMA */ - *kvap = (void *)PMAP_MAP_POOLPAGE(paddr); - return 0; - } + bool direct_mapable = (flags & BUS_DMA_COHERENT) == 0; + pa = segs[0].ds_addr; + /* - * This is a COHERENT mapping, which unless this address is in + * This is a COHERENT mapping which, unless this address is in * a COHERENT dma range, will not be compatible. */ if (t->_ranges != NULL) { const struct arm32_dma_range * const dr = - _bus_dma_paddr_inrange(t->_ranges, t->_nranges, - paddr); - if (dr != NULL - && (dr->dr_flags & _BUS_DMAMAP_COHERENT) != 0) { - *kvap = (void *)PMAP_MAP_POOLPAGE(paddr); + _bus_dma_paddr_inrange(t->_ranges, t->_nranges, pa); + if (dr != NULL) { + if (dr->dr_flags & _BUS_DMAMAP_COHERENT) { + direct_mapable = true; + } + if (dr->dr_flags & _BUS_DMAMAP_MEM_XLATE) { + pa = (pa - dr->dr_sysbase) + + dr->dr_busbase; + } + } + } + + if (direct_mapable) { + *kvap = (void *)PMAP_MAP_POOLPAGE(pa); #ifdef DEBUG_DMA - printf("dmamem_map: =%p\n", *kvap); + printf("dmamem_map: =%p\n", *kvap); #endif /* DEBUG_DMA */ - return 0; - } + return 0; } } #endif @@ -1273,11 +1276,28 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma for (pa = segs[curseg].ds_addr; pa < (segs[curseg].ds_addr + segs[curseg].ds_len); pa += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) { + bool uncached = (flags & BUS_DMA_COHERENT); #ifdef DEBUG_DMA printf("wiring p%lx to v%lx", pa, va); #endif /* DEBUG_DMA */ if (size == 0) panic("_bus_dmamem_map: size botch"); + + const struct arm32_dma_range * const dr = + _bus_dma_paddr_inrange(t->_ranges, t->_nranges, pa); + /* + * If this dma region is coherent then there is + * no need for an uncached mapping. + */ + if (dr != NULL) { + if (dr->dr_flags & _BUS_DMAMAP_COHERENT) { + uncached = false; + } + if (dr->dr_flags & _BUS_DMAMAP_MEM_XLATE) { + pa = (pa - dr->dr_sysbase) + + dr->dr_busbase; + } + } pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED); @@ -1289,21 +1309,6 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma * contain the virtal addresses we are making * uncacheable. */ - - bool uncached = (flags & BUS_DMA_COHERENT); - if (uncached) { - const struct arm32_dma_range * const dr = - _bus_dma_paddr_inrange(t->_ranges, - t->_nranges, pa); - /* - * If this dma region is coherent then there is - * no need for an uncached mapping. - */ - if (dr != NULL - && (dr->dr_flags & _BUS_DMAMAP_COHERENT)) { - uncached = false; - } - } if (uncached) { cpu_dcache_wbinv_range(va, PAGE_SIZE); cpu_sdcache_wbinv_range(va, pa, PAGE_SIZE); Index: src/sys/arch/arm/broadcom/bcm2835_obio.c diff -u src/sys/arch/arm/broadcom/bcm2835_obio.c:1.13 src/sys/arch/arm/broadcom/bcm2835_obio.c:1.14 --- src/sys/arch/arm/broadcom/bcm2835_obio.c:1.13 Sat Jan 26 08:01:49 2013 +++ src/sys/arch/arm/broadcom/bcm2835_obio.c Sun Jan 27 17:38:55 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835_obio.c,v 1.13 2013/01/26 08:01:49 skrll Exp $ */ +/* $NetBSD: bcm2835_obio.c,v 1.14 2013/01/27 17:38:55 matt Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.13 2013/01/26 08:01:49 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.14 2013/01/27 17:38:55 matt Exp $"); #include "locators.h" #include "obio.h" @@ -183,6 +183,7 @@ obio_attach(device_t parent, device_t se sc->sc_dmarange.dr_sysbase = 0; sc->sc_dmarange.dr_busbase = BCM2835_BUSADDR_CACHE_COHERENT; sc->sc_dmarange.dr_len = physmem * PAGE_SIZE; + sc->sc_dmarange.dr_flags = _BUS_DMAMAP_MEM_XLATE; bcm2835_bus_dma_tag._ranges = &sc->sc_dmarange; bcm2835_bus_dma_tag._nranges = 1; Index: src/sys/arch/arm/include/bus_defs.h diff -u src/sys/arch/arm/include/bus_defs.h:1.5 src/sys/arch/arm/include/bus_defs.h:1.6 --- src/sys/arch/arm/include/bus_defs.h:1.5 Mon Nov 12 18:00:37 2012 +++ src/sys/arch/arm/include/bus_defs.h Sun Jan 27 17:38:55 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_defs.h,v 1.5 2012/11/12 18:00:37 skrll Exp $ */ +/* $NetBSD: bus_defs.h,v 1.6 2013/01/27 17:38:55 matt Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. @@ -301,6 +301,7 @@ struct bus_space { */ #define _BUS_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */ #define _BUS_DMAMAP_IS_BOUNCING 0x20000 /* is bouncing current xfer */ +#define _BUS_DMAMAP_MEM_XLATE 0x40000 /* translate sys->bus for dmamam_map */ /* Forwards needed by prototypes below. */ struct mbuf;