Some semi-recent ACPI revision introduced the _CCA method.  This
method indicates whether DMA is cache-coherent for a device.  This
isn't really relevant on i386/amd64 since its busses are pretty much
always fully cache-coherent.  But on amr64 things are different.
Server machines typically have coherent busses, but the smaller
systems are incoherent.  So far we have ignored this aspect, since our
arm64 ACPI support is mostly there to support server systems.  But now
there is an EDK2-based UEFI firmware for the Raspberry Pi3 and Pi4.
This firmware includes ACPI support and ACPI is the default.

The diff below adds support for _CCA by making acpi(4) use two differt
bus_dma tags: one for cache-coherent DMA and one for cache-incoherent
DMA.  On i386/amd64 both of these are set to the same value.  But for
am64 they are different.  If the _CCA method is absent we assume DMA
is cache-coherent.

With this diff (and the xhci diff I just mailed out) USB 3.0 works on
the rpi4 and the od1000 and ampere systems still work.  I also tested
this on amd64.

ok?


Index: arch/amd64/amd64/acpi_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/acpi_machdep.c,v
retrieving revision 1.89
diff -u -p -r1.89 acpi_machdep.c
--- arch/amd64/amd64/acpi_machdep.c     20 Dec 2019 07:49:31 -0000      1.89
+++ arch/amd64/amd64/acpi_machdep.c     10 Apr 2020 15:35:50 -0000
@@ -96,7 +96,8 @@ acpi_attach(struct device *parent, struc
 
        sc->sc_iot = ba->ba_iot;
        sc->sc_memt = ba->ba_memt;
-       sc->sc_dmat = &pci_bus_dma_tag;
+       sc->sc_cc_dmat = &pci_bus_dma_tag;
+       sc->sc_ci_dmat = &pci_bus_dma_tag;
 
        acpi_attach_common(sc, ba->ba_acpipbase);
 }
Index: arch/arm64/arm64/acpi_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/acpi_machdep.c,v
retrieving revision 1.3
diff -u -p -r1.3 acpi_machdep.c
--- arch/arm64/arm64/acpi_machdep.c     27 Aug 2019 22:39:53 -0000      1.3
+++ arch/arm64/arm64/acpi_machdep.c     10 Apr 2020 15:35:50 -0000
@@ -56,13 +56,14 @@ acpi_fdt_attach(struct device *parent, s
        struct fdt_attach_args *faa = aux;
        bus_dma_tag_t dmat;
 
+       sc->sc_memt = faa->fa_iot;
+       sc->sc_ci_dmat = faa->fa_dmat;
+
        /* Create coherent DMA tag. */
-       dmat = malloc(sizeof(*sc->sc_dmat), M_DEVBUF, M_WAITOK | M_ZERO);
+       dmat = malloc(sizeof(*sc->sc_cc_dmat), M_DEVBUF, M_WAITOK | M_ZERO);
        memcpy(dmat, faa->fa_dmat, sizeof(*dmat));
        dmat->_flags |= BUS_DMA_COHERENT;
-       
-       sc->sc_memt = faa->fa_iot;
-       sc->sc_dmat = dmat;
+       sc->sc_cc_dmat = dmat;
 
        acpi_attach_common(sc, faa->fa_reg[0].addr);
 }
Index: arch/i386/i386/acpi_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/acpi_machdep.c,v
retrieving revision 1.72
diff -u -p -r1.72 acpi_machdep.c
--- arch/i386/i386/acpi_machdep.c       20 Dec 2019 07:55:30 -0000      1.72
+++ arch/i386/i386/acpi_machdep.c       10 Apr 2020 15:35:50 -0000
@@ -106,7 +106,8 @@ acpi_attach(struct device *parent, struc
 
        sc->sc_iot = ba->ba_iot;
        sc->sc_memt = ba->ba_memt;
-       sc->sc_dmat = &pci_bus_dma_tag;
+       sc->sc_cc_dmat = &pci_bus_dma_tag;
+       sc->sc_ci_dmat = &pci_bus_dma_tag;
 
        acpi_attach_common(sc, ba->ba_acpipbase);
 }
Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.380
diff -u -p -r1.380 acpi.c
--- dev/acpi/acpi.c     7 Apr 2020 13:27:51 -0000       1.380
+++ dev/acpi/acpi.c     10 Apr 2020 15:35:50 -0000
@@ -3122,6 +3122,7 @@ acpi_foundhid(struct aml_node *node, voi
        char                     dev[32];
        struct acpi_attach_args  aaa;
        int64_t                  sta;
+       int64_t                  cca;
 #ifndef SMALL_KERNEL
        int                      i;
 #endif
@@ -3133,12 +3134,15 @@ acpi_foundhid(struct aml_node *node, voi
        if ((sta & STA_PRESENT) == 0)
                return (0);
 
+       if (aml_evalinteger(sc, node->parent, "_CCA", 0, NULL, &cca))
+               cca = 1;
+
        acpi_attach_deps(sc, node->parent);
 
        memset(&aaa, 0, sizeof(aaa));
        aaa.aaa_iot = sc->sc_iot;
        aaa.aaa_memt = sc->sc_memt;
-       aaa.aaa_dmat = sc->sc_dmat;
+       aaa.aaa_dmat = cca ? sc->sc_cc_dmat : sc->sc_ci_dmat;
        aaa.aaa_node = node->parent;
        aaa.aaa_dev = dev;
        aaa.aaa_cdev = cdev;
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.105
diff -u -p -r1.105 acpivar.h
--- dev/acpi/acpivar.h  7 Sep 2019 13:46:20 -0000       1.105
+++ dev/acpi/acpivar.h  10 Apr 2020 15:35:50 -0000
@@ -208,7 +208,8 @@ struct acpi_softc {
 
        bus_space_tag_t         sc_iot;
        bus_space_tag_t         sc_memt;
-       bus_dma_tag_t           sc_dmat;
+       bus_dma_tag_t           sc_cc_dmat;
+       bus_dma_tag_t           sc_ci_dmat;
 
        /*
         * First-level ACPI tables

Reply via email to