The RISC-V architecture has cache-coherent DMA... until it doesn't. This
authorkettenis <kettenis@openbsd.org>
Sun, 7 Apr 2024 21:08:59 +0000 (21:08 +0000)
committerkettenis <kettenis@openbsd.org>
Sun, 7 Apr 2024 21:08:59 +0000 (21:08 +0000)
is indicated by a "dma-noncoherent" property on the bus or device nodes
in the device tree.  Set the BUS_DMA_COHERENT flag on the DMA tag for
mainbus(4) and modify the flags based on the presence of "dma-coherent"
and "dma-noncoherent" properties where appropriate.

ok patrick@

sys/arch/riscv64/dev/mainbus.c
sys/arch/riscv64/dev/simplebus.c

index d68acbd..c51f6b0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mainbus.c,v 1.8 2021/06/20 16:51:37 deraadt Exp $ */
+/*     $OpenBSD: mainbus.c,v 1.9 2024/04/07 21:08:59 kettenis Exp $ */
 
 /*
  * Copyright (c) 2016 Patrick Wildt <patrick@blueri.se>
@@ -64,7 +64,7 @@ struct cfdriver mainbus_cd = {
 
 struct machine_bus_dma_tag mainbus_dma_tag = {
        NULL,
-       0,
+       BUS_DMA_COHERENT,
        _dmamap_create,
        _dmamap_destroy,
        _dmamap_load,
@@ -246,6 +246,18 @@ mainbus_attach_node(struct device *self, int node, cfmatch_t submatch)
                OF_getpropintarray(node, "interrupts", fa.fa_intr, len);
        }
 
+       if (OF_getproplen(node, "dma-noncoherent") >= 0) {
+               fa.fa_dmat = malloc(sizeof(*sc->sc_dmat),
+                   M_DEVBUF, M_WAITOK | M_ZERO);
+               memcpy(fa.fa_dmat, sc->sc_dmat, sizeof(*sc->sc_dmat));
+               fa.fa_dmat->_flags &= ~BUS_DMA_COHERENT;
+       } else if (OF_getproplen(node, "dma-coherent") >= 0) {
+               fa.fa_dmat = malloc(sizeof(*sc->sc_dmat),
+                   M_DEVBUF, M_WAITOK | M_ZERO);
+               memcpy(fa.fa_dmat, sc->sc_dmat, sizeof(*sc->sc_dmat));
+               fa.fa_dmat->_flags |= BUS_DMA_COHERENT;
+       }
+
        if (submatch == NULL && sc->sc_early == 0)
                print = mainbus_print;
        if (submatch == NULL)
index 3f74e23..082395c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: simplebus.c,v 1.6 2023/09/22 01:10:44 jsg Exp $       */
+/*     $OpenBSD: simplebus.c,v 1.7 2024/04/07 21:08:59 kettenis Exp $  */
 
 /*
  * Copyright (c) 2016 Patrick Wildt <patrick@blueri.se>
@@ -226,7 +226,12 @@ simplebus_attach_node(struct device *self, int node)
                OF_getpropintarray(node, "interrupts", fa.fa_intr, len);
        }
 
-       if (OF_getproplen(node, "dma-coherent") >= 0) {
+       if (OF_getproplen(node, "dma-noncoherent") >= 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;
+       } else 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));