Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/arm32 Add busaddr to paddr routine and use it.
details: https://anonhg.NetBSD.org/src/rev/ce75c5e1f65d
branches: trunk
changeset: 781676:ce75c5e1f65d
user: matt <matt%NetBSD.org@localhost>
date: Sat Sep 22 01:48:50 2012 +0000
description:
Add busaddr to paddr routine and use it.
cleanup the PREREAD sync case.
diffstat:
sys/arch/arm/arm32/bus_dma.c | 63 ++++++++++++++++++++++++++++++-------------
1 files changed, 43 insertions(+), 20 deletions(-)
diffs (140 lines):
diff -r 833c8e20d789 -r ce75c5e1f65d sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c Sat Sep 22 01:47:46 2012 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c Sat Sep 22 01:48:50 2012 +0000
@@ -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 @@
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 @@
}
/*
+ * 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 @@
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 @@
/* 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 @@
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 @@
*/
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 @@
*/
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);
Home |
Main Index |
Thread Index |
Old Index