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);