summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2017-02-22 22:55:27 +0000
committerpatrick <patrick@openbsd.org>2017-02-22 22:55:27 +0000
commit2d784deaae60ed682a085dc1d07e1151de3349ec (patch)
treea9b5d661726abb779b9a6733d6b4a9612acd5e99
parentThe assembly for sigprocmask(2) had a tiny typo which made it jump to (diff)
downloadwireguard-openbsd-2d784deaae60ed682a085dc1d07e1151de3349ec.tar.xz
wireguard-openbsd-2d784deaae60ed682a085dc1d07e1151de3349ec.zip
The AMD Seattle SoC incorporates DMA coherent controllers, especially
AHCI, PCIe and Ethernet. Since these systems rely on cache snooping, we must not map pages that are supposed to be coherent as uncacheable. Instead if we have a cache coherent device, create a bus tag and mark that tag as coherent. For users of that tag we can simply use normal, cached memory. ok kettenis@
-rw-r--r--sys/arch/arm64/arm64/bus_dma.c15
-rw-r--r--sys/arch/arm64/dev/mainbus.c3
-rw-r--r--sys/arch/arm64/dev/simplebus.c9
-rw-r--r--sys/arch/arm64/include/bus.h3
4 files changed, 25 insertions, 5 deletions
diff --git a/sys/arch/arm64/arm64/bus_dma.c b/sys/arch/arm64/arm64/bus_dma.c
index ad351c481b2..3df3b7ed14c 100644
--- a/sys/arch/arm64/arm64/bus_dma.c
+++ b/sys/arch/arm64/arm64/bus_dma.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus_dma.c,v 1.5 2017/02/18 14:14:19 patrick Exp $ */
+/* $OpenBSD: bus_dma.c,v 1.6 2017/02/22 22:55:27 patrick Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -362,6 +362,16 @@ _dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t addr,
int nsegs;
int curseg;
+ /*
+ * If our tag tells us that the device we are doing DMA
+ * with is coherent, make sure the write buffer is synced
+ * and return.
+ */
+ if (t->_flags & BUS_DMA_COHERENT) {
+ membar_sync();
+ return;
+ }
+
nsegs = map->dm_nsegs;
curseg = 0;
@@ -482,7 +492,8 @@ _dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, size_t size,
ssize = size;
pmap_flags = PMAP_WIRED | PMAP_CANFAIL;
cache = PMAP_CACHE_DEFAULT;
- if (flags & (BUS_DMA_COHERENT | BUS_DMA_NOCACHE))
+ if (((t->_flags & BUS_DMA_COHERENT) == 0 &&
+ (flags & BUS_DMA_COHERENT)) || (flags & BUS_DMA_NOCACHE))
cache = PMAP_CACHE_CI;
for (curseg = 0; curseg < nsegs; curseg++) {
for (addr = segs[curseg].ds_addr;
diff --git a/sys/arch/arm64/dev/mainbus.c b/sys/arch/arm64/dev/mainbus.c
index 6714d116967..e638d63185f 100644
--- a/sys/arch/arm64/dev/mainbus.c
+++ b/sys/arch/arm64/dev/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.2 2017/02/18 00:19:33 patrick Exp $ */
+/* $OpenBSD: mainbus.c,v 1.3 2017/02/22 22:55:27 patrick Exp $ */
/*
* Copyright (c) 2016 Patrick Wildt <patrick@blueri.se>
*
@@ -54,6 +54,7 @@ struct cfdriver mainbus_cd = {
struct machine_bus_dma_tag mainbus_dma_tag = {
NULL,
+ 0,
_dmamap_create,
_dmamap_destroy,
_dmamap_load,
diff --git a/sys/arch/arm64/dev/simplebus.c b/sys/arch/arm64/dev/simplebus.c
index 55d53edeae9..f7eac42a36d 100644
--- a/sys/arch/arm64/dev/simplebus.c
+++ b/sys/arch/arm64/dev/simplebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: simplebus.c,v 1.5 2017/01/23 10:47:53 kettenis Exp $ */
+/* $OpenBSD: simplebus.c,v 1.6 2017/02/22 22:55:27 patrick Exp $ */
/*
* Copyright (c) 2016 Patrick Wildt <patrick@blueri.se>
*
@@ -214,6 +214,13 @@ simplebus_attach_node(struct device *self, int node)
OF_getpropintarray(node, "interrupts", fa.fa_intr, len);
}
+ if (OF_getproplen(node, "dma-coherent") >= 0) {
+ fa.fa_dmat = malloc(sizeof(sc->sc_dma),
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ memcpy(fa.fa_dmat, &sc->sc_dma, sizeof(sc->sc_dma));
+ fa.fa_dmat->_flags |= BUS_DMA_COHERENT;
+ }
+
config_found_sm(self, &fa, NULL, simplebus_submatch);
free(fa.fa_reg, M_DEVBUF, fa.fa_nreg * sizeof(struct fdt_reg));
diff --git a/sys/arch/arm64/include/bus.h b/sys/arch/arm64/include/bus.h
index a681c9e929b..786bcaab52e 100644
--- a/sys/arch/arm64/include/bus.h
+++ b/sys/arch/arm64/include/bus.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus.h,v 1.1 2016/12/17 23:38:33 patrick Exp $ */
+/* $OpenBSD: bus.h,v 1.2 2017/02/22 22:55:27 patrick Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB Sweden. All rights reserved.
*
@@ -353,6 +353,7 @@ typedef struct machine_bus_dma_segment bus_dma_segment_t;
struct machine_bus_dma_tag {
void *_cookie; /* cookie used in the guts */
+ int _flags; /* misc. flags */
/*
* DMA mapping methods.