Hi all, sorry for the long read, I kept it as short as possible.

So, the wrapper around the PCIe block available on the Raspberry Pi 4 has a bug
preventing it from accessing anything beyond the first 3G of ram [1]. I'm
trying to figure out the best way to integrate this upstream.

Note that the only thing behind the PCIe bus is an USB3 chip. The bus is not
exposed to users directly.

I see two options:

- Isolate the PCIe block on it's own interconnect. IMO this could be acceptable
  as it's arguable that the bug is not really in the PCIe block.  I set the
  interconnect's dma-range size to 2GB instead of 3GB as dma masks don't play
  well with non power of two DMA constraints:

  buggy-scb {
        compatible = "simple-bus";
        dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x800000000>;

        pcie {
                compatible = "brcm,bcm2711-pcie";
                dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000
                              0x1 0x00000000>;
                [...]

        };
  };

  scb {
        compatible = "simple-bus";
        dma-ranges = <0x0 0x00000000 0x0 0x00000000 0xfc0000000>;

        eth0 {
                [...]
        };

        [...]
  };

  With this setup the PCIe devices should behave correctly as long as they
  don't play with their own DMA masks.

- Configure PCIe's inbound view of memory taking into account the buggy
  interconnect:

  scb {
        compatible = "simple-bus";
        dma-ranges = <0x0 0x00000000 0x0 0x00000000 0xfc000000>;

        pcie {
                compatible = "brcm,bcm2711-pcie";
                dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000
                              0x0 0x80000000>;
                [...]

        };

        eth0 {
                [...]
        };

        [...]
  };

  The downside of this is that of_dma_configure() doesn't play well with PCI
  devices. of_dma_configure() expects a device's OF node, yet the PCI core
  passes the bridge's OF node, as the device has none. The result is
  of_dma_configure() ignores PCI's dma-ranges. Solving this is not trivial.
  IMO the simplest solution would be to create a distinct OF node on PCI
  bridges, child of the actual PCI root complex.  FYI this was already an issue
  some years ago [2].

  This solution also suffers from devices setting their own DMA masks.

If you're curious abot the downstream kernel, they use their custom buffer
bouncing code, which AFAIK is something we're trying to get rid of.

Any comments? Alternative solutions?

Thanks,
Nicolas

[1] https://www.spinics.net/lists/arm-kernel/msg740693.html
[2] https://patchwork.kernel.org/patch/9650345/#20294961

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to