Module Name: src Committed By: matt Date: Sat Sep 22 01:48:50 UTC 2012
Modified Files: src/sys/arch/arm/arm32: bus_dma.c Log Message: Add busaddr to paddr routine and use it. cleanup the PREREAD sync case. To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.59 src/sys/arch/arm/arm32/bus_dma.c 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.58 src/sys/arch/arm/arm32/bus_dma.c:1.59 --- src/sys/arch/arm/arm32/bus_dma.c:1.58 Tue Sep 18 05:47:26 2012 +++ src/sys/arch/arm/arm32/bus_dma.c Sat Sep 22 01:48:50 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_dma.c,v 1.58 2012/09/18 05:47:26 matt Exp $ */ +/* $NetBSD: bus_dma.c,v 1.59 2012/09/22 01:48:50 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.58 2012/09/18 05:47:26 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.59 2012/09/22 01:48:50 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -92,13 +92,13 @@ EVCNT_ATTACH_STATIC(bus_dma_bounced_dest int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, struct vmspace *, int); static struct arm32_dma_range * - _bus_dma_inrange(struct arm32_dma_range *, int, bus_addr_t); + _bus_dma_paddr_inrange(struct arm32_dma_range *, int, paddr_t); /* * Check to see if the specified page is in an allowed DMA range. */ inline struct arm32_dma_range * -_bus_dma_inrange(struct arm32_dma_range *ranges, int nranges, +_bus_dma_paddr_inrange(struct arm32_dma_range *ranges, int nranges, bus_addr_t curaddr) { struct arm32_dma_range *dr; @@ -114,6 +114,26 @@ _bus_dma_inrange(struct arm32_dma_range } /* + * Check to see if the specified busaddr is in an allowed DMA range. + */ +static inline paddr_t +_bus_dma_busaddr_to_paddr(bus_dma_tag_t t, bus_addr_t curaddr) +{ + struct arm32_dma_range *dr; + u_int i; + + if (t->_nranges == 0) + return curaddr; + + for (i = 0, dr = t->_ranges; i < t->_nranges; i++, dr++) { + if (dr->dr_busbase <= curaddr + && round_page(curaddr) <= dr->dr_busbase + dr->dr_len) + return curaddr - dr->dr_busbase + dr->dr_sysbase; + } + panic("%s: curaddr %#lx not in range", __func__, curaddr); +} + +/* * Common function to load the specified physical address into the * DMA map, coalescing segments and boundary checking as necessary. */ @@ -140,7 +160,7 @@ _bus_dmamap_load_paddr(bus_dma_tag_t t, if (t->_ranges != NULL) { /* XXX cache last result? */ const struct arm32_dma_range * const dr = - _bus_dma_inrange(t->_ranges, t->_nranges, paddr); + _bus_dma_paddr_inrange(t->_ranges, t->_nranges, paddr); if (dr == NULL) return (EINVAL); @@ -685,27 +705,30 @@ _bus_dmamap_sync_segment(vaddr_t va, pad /* FALLTHROUGH */ case BUS_DMASYNC_PREREAD: { - vsize_t misalignment = va & arm_dcache_align_mask; + const size_t line_size = arm_dcache_align; + const size_t line_mask = arm_dcache_align_mask; + vsize_t misalignment = va & line_mask; if (misalignment) { - va &= ~arm_dcache_align_mask; - pa &= ~arm_dcache_align_mask; - cpu_dcache_wbinv_range(va, arm_dcache_align); - cpu_sdcache_wbinv_range(va, pa, arm_dcache_align); - if (len <= arm_dcache_align - misalignment) + va -= misalignment; + pa -= misalignment; + len += misalignment; + cpu_dcache_wbinv_range(va, line_size); + cpu_sdcache_wbinv_range(va, pa, line_size); + if (len <= line_size) break; - len -= arm_dcache_align - misalignment; - va += arm_dcache_align; - pa += arm_dcache_align; + va += line_size; + pa += line_size; + len -= line_size; } - misalignment = len & arm_dcache_align_mask; + misalignment = len & line_mask; len -= misalignment; cpu_dcache_inv_range(va, len); cpu_sdcache_inv_range(va, pa, len); if (misalignment) { va += len; pa += len; - cpu_dcache_wbinv_range(va, arm_dcache_align); - cpu_sdcache_wbinv_range(va, pa, arm_dcache_align); + cpu_dcache_wbinv_range(va, line_size); + cpu_sdcache_wbinv_range(va, pa, line_size); } break; } @@ -740,7 +763,7 @@ _bus_dmamap_sync_linear(bus_dma_tag_t t, ds++; } - paddr_t pa = ds->ds_addr + offset; + paddr_t pa = _bus_dma_busaddr_to_paddr(t, ds->ds_addr + offset); size_t seglen = min(len, ds->ds_len - offset); _bus_dmamap_sync_segment(va + offset, pa, seglen, ops, false); @@ -777,7 +800,7 @@ _bus_dmamap_sync_mbuf(bus_dma_tag_t t, b */ vsize_t seglen = min(len, min(m->m_len - voff, ds->ds_len - ds_off)); vaddr_t va = mtod(m, vaddr_t) + voff; - paddr_t pa = ds->ds_addr + ds_off; + paddr_t pa = _bus_dma_busaddr_to_paddr(t, ds->ds_addr + ds_off); /* * We can save a lot of work here if we know the mapping @@ -832,7 +855,7 @@ _bus_dmamap_sync_uio(bus_dma_tag_t t, bu */ vsize_t seglen = min(len, min(iov->iov_len - voff, ds->ds_len - ds_off)); vaddr_t va = (vaddr_t) iov->iov_base + voff; - paddr_t pa = ds->ds_addr + ds_off; + paddr_t pa = _bus_dma_busaddr_to_paddr(t, ds->ds_addr + ds_off); _bus_dmamap_sync_segment(va, pa, seglen, ops, false);