[PATCH 13/18] arm64: ioremap: use nGnRnE mappings on platforms that require it

Arnd Bergmann arnd at kernel.org
Thu Feb 4 17:21:37 EST 2021


On Thu, Feb 4, 2021 at 9:39 PM Hector Martin <marcan at marcan.st> wrote:
>
>     Currently there are three ioremap variants:
>
>     ioremap()
>     ioremap_wc()
>     ioremap_uc() (not normally used on arm64)
>
>     None of these really capture the nGnRE vs nGnRnE distinction. If
>     a new variant is introduced in common code, we'd have to provide
>     a default implementation that falls back to regular ioremap() on
>     other arches. Something like ioremap() vs. ioremap_np() (nonposted)?

The ioport_map() function could be considered a variant of nonposted
I/O, as being nonposted is a requirement for PCI I/O space. It's
a bit weird to overload it here, as I/O space has a number of other
special cases, including a limit for the total size of the address space,
and the assumption that all I/O ports are always mapped into virtual
addresses at boot time.

Are the registers that need nGnRnE all part of a well-defined
physical address range that we could pretend to be I/O space?
Also, is the actual PCI I/O space within this region?

The main advantage here would be that we could reuse the
IORESOURCE_IO bit to signify a register in this area.

Note: I don't actually think this is going to be a good solution, just
throwing it out as another alternative in case everything else ends
up being worse.

> (2) The converse of (1): keep the nGnRE default, but introduce special
>     casing to the OF binding code to use nGnRnE when instructed to do so
>     on these platforms. This means of_iomap() needs changing.

It probably also means changing of_address_to_resource(),
and devm_ioremap_resource().

> (3) Do it at a lower level, in ioremap() itself. This requires that
>     ioremap() somehow discriminates based on address range to pick what
>     kind of mapping to make.
>
>     Declaring these address ranges would be an issue. Options:
>
>     a) An out of band list in a DT node, a la /reserved-memory
>
>     b) Something based on the existing DT hierarchy, where we can scan
>        bus ranges and locate buses with a property that says "nGnRnE" or
>        "nGnRE" and dynamically build the list based on that.
>
>     The advantage of this option is that it doesn't touch non-arch code.
>     The disadvantage is that it adds a complete new bespoke mechanism to
>     the DT, and that it does not let device drivers actually select the
>     IO mode, which might be desirable in the future anyway for some
>     devices.
>
> All discussion and additional ideas welcome.

A very simple but ugly hack would be to take one of the high address
bits in phys_addr_t to encode the type, and then pass that through
all the way into the ioremap implementation.

This does have some precedent with the upper bits of the (96-bit)
PCI addresses encoding the type of resource, but it also conflates
the DT representation with the arm64 kernel implementation and
requires extending both in a fairly generic way to do something that
is highly platform specific.

         Arnd



More information about the linux-arm-kernel mailing list