diff options
author | 2017-02-22 22:55:27 +0000 | |
---|---|---|
committer | 2017-02-22 22:55:27 +0000 | |
commit | 2d784deaae60ed682a085dc1d07e1151de3349ec (patch) | |
tree | a9b5d661726abb779b9a6733d6b4a9612acd5e99 /sys | |
parent | The assembly for sigprocmask(2) had a tiny typo which made it jump to (diff) | |
download | wireguard-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@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm64/arm64/bus_dma.c | 15 | ||||
-rw-r--r-- | sys/arch/arm64/dev/mainbus.c | 3 | ||||
-rw-r--r-- | sys/arch/arm64/dev/simplebus.c | 9 | ||||
-rw-r--r-- | sys/arch/arm64/include/bus.h | 3 |
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. |