On the Raspberry Pi 4, XHCI can only DMA to the first 3 GiB of memory, and devices behind the GPU — to the first 1 GiB (though DWC OTG USB2.0 worked fine anyway).
_DMA in ACPI describes *valid* ranges (potentially multiple), and inheritance seems to be additive rather than restrictive (quoting ACPI 6.3 spec):
Any ranges described in the resources of a _DMA object can be used by child devices for DMA or bus master transactions
If the _DMA object is not present for a bus device, the OS assumes that any address placed on a bus by a child device will be decoded either by a device on the bus or by the bus itself, (in other words, all address ranges can be used for DMA).
Our bus_dma_tags (sadly) describe only one *in*accessible range, with a filter function option for more advanced checking, but I couldn't get that to work (with lowaddr 0 and a filter set, the system would just hang before calling filters; with lowaddr set to max, the filter would never apply).
But we haven't actually encountered any devices where that one range isn't enough. We don't have to handle all the possible complexity right now.
This patch adds enough support to make the RPi4 fully work (with the memory limiter off in UEFI settings). That is, inheritance by finding the first parent handle with a _DMA method, and calculation of the smallest lowaddr from the ranges.
Handles are used rather than device_get_parent because (at least on arm64) devices in ACPI0004 containers end up as direct children of acpi0.
NetBSD seems to have DMA tags that describe multiple ranges, and both device and CPU side base..