summaryrefslogtreecommitdiffstats
path: root/rtemsbsd
diff options
context:
space:
mode:
authorChristian Mauderer <christian.mauderer@embedded-brains.de>2020-04-02 16:42:43 +0200
committerChristian Mauderer <christian.mauderer@embedded-brains.de>2020-07-29 13:09:11 +0200
commitcdd6003eb8ad3989deab5bfd8cdb1efbffecde22 (patch)
tree2a5c21a2c64dfb563d8a8fca614eacd120db55cf /rtemsbsd
parentimx: Use RTEMS GPIO driver instead of FreeBSD one (diff)
downloadrtems-libbsd-cdd6003eb8ad3989deab5bfd8cdb1efbffecde22.tar.bz2
busdma: Option to round to cache lines on sync
Some targets support only flushing or invalidating complete cache lines. In this cases misaligned buffers might lead to unexpected results. This patch adds a flag that allows drivers to signal to the bus dma driver that it is OK to round a buffer to the next full cache line. That's for example necessary if a driver wants to send out 14 byte via a USB DMA. Only the driver knows whether these 14 bytes are located in an otherwise unused cache line aligned buffer.
Diffstat (limited to 'rtemsbsd')
-rw-r--r--rtemsbsd/include/machine/rtems-bsd-bus-dma.h3
-rw-r--r--rtemsbsd/rtems/rtems-kernel-bus-dma-mbuf.c3
-rw-r--r--rtemsbsd/rtems/rtems-kernel-bus-dma.c9
3 files changed, 15 insertions, 0 deletions
diff --git a/rtemsbsd/include/machine/rtems-bsd-bus-dma.h b/rtemsbsd/include/machine/rtems-bsd-bus-dma.h
index ac970537..e9566882 100644
--- a/rtemsbsd/include/machine/rtems-bsd-bus-dma.h
+++ b/rtemsbsd/include/machine/rtems-bsd-bus-dma.h
@@ -75,6 +75,9 @@ struct bus_dma_tag {
struct bus_dmamap {
void *buffer_begin;
bus_size_t buffer_size;
+ int flags;
+/* OK to flush / invalidate the complete cache line */
+#define DMAMAP_CACHE_ALIGNED (1 << 0)
};
int
diff --git a/rtemsbsd/rtems/rtems-kernel-bus-dma-mbuf.c b/rtemsbsd/rtems/rtems-kernel-bus-dma-mbuf.c
index c435fd74..56ead4ee 100644
--- a/rtemsbsd/rtems/rtems-kernel-bus-dma-mbuf.c
+++ b/rtemsbsd/rtems/rtems-kernel-bus-dma-mbuf.c
@@ -69,6 +69,9 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map,
int first = 1;
bus_addr_t lastaddr = 0;
struct mbuf *m;
+ if ((flags & BUS_DMA_LOAD_MBUF) != 0) {
+ map->flags |= DMAMAP_CACHE_ALIGNED;
+ }
for (m = m0; m != NULL && error == 0; m = m->m_next) {
if (m->m_len > 0) {
diff --git a/rtemsbsd/rtems/rtems-kernel-bus-dma.c b/rtemsbsd/rtems/rtems-kernel-bus-dma.c
index 8c15e92b..4dc634f3 100644
--- a/rtemsbsd/rtems/rtems-kernel-bus-dma.c
+++ b/rtemsbsd/rtems/rtems-kernel-bus-dma.c
@@ -365,9 +365,13 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
map->buffer_begin = buf;
map->buffer_size = buflen;
+ if ((flags & BUS_DMA_DO_CACHE_LINE_BLOW_UP) != 0) {
+ map->flags |= DMAMAP_CACHE_ALIGNED;
+ }
lastaddr = (vm_offset_t)0;
nsegs = 0;
+
error = bus_dmamap_load_buffer(dmat, dm_segments, buf, buflen,
NULL, flags, &lastaddr, &nsegs, 1);
@@ -397,6 +401,11 @@ bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
uintptr_t begin = (uintptr_t) map->buffer_begin;
uintptr_t end = begin + size;
+ if ((map->flags & DMAMAP_CACHE_ALIGNED) != 0) {
+ begin &= ~CLMASK;
+ end = (end + CLMASK) & ~CLMASK;
+ size = end - begin;
+ }
if ((op & BUS_DMASYNC_PREWRITE) != 0 && (op & BUS_DMASYNC_PREREAD) == 0) {
rtems_cache_flush_multiple_data_lines((void *) begin, size);
}