Re: Ranges - Intended use case

David Gibson
2026-02-14T02:17:24Z

[-- Attachment #1: Type: text/plain, Size: 7919 bytes --]

On Fri, Feb 13, 2026 at 09:04:00AM +0000, McCrae, Jamie wrote:
> On Thu, 2026-02-12 at 13:24 -0600, Rob Herring wrote:
> > On Thu, Feb 12, 2026 at 9:33 AM Yao Zi <me@ziyao.cc> wrote:
> > >
> > > On Thu, Feb 12, 2026 at 01:14:33PM +0000, Kyle Bonnici wrote:
> > > > Hi
> > > >
> > > > I have been trying to understand how ranges should/should not be
> > > > used.
> > > >
> > > > Looking at the spec
> > > >
> > > > > The ranges property provides a means of defining a mapping or
> > > > > translation between the address space of the
> > > > bus (the child address space) and the address space of the bus
> > > > node’s parent (the parent address space).
> > > >
> > > > This to me the spec leave some space for interpretation on if
> > > > ranges should be used on just buses or not. Below are some
> > > > examples to try to get a better understanding.
> > >
> > > I'd like to say ranges literally specifies the translation process
> > > between the children address space and the parent one, regardless
> > > whether the parent is a "bus".
> >
> > Yes.
> >
> > To put it simply, "ranges" should be used whenever the child nodes
> > have memory-mapped CPU addresses.
> >
> > > For example, reserved-memory nodes aren't really "buses", but often
> > > come with ranges property, as shown in the example of dt-schema[1].
> > >
> > > However it might be a signature of bad device-tree model designs if
> > > you
> > > have to use a ranges property for a random non-bus node.
> > >
> > > >
> > > > ```
> > > > / {
> > > >       foo { // not a bus
> > > >               #address-cells = <1>;
> > > >               #size-cells = <1>;
> > > >               ranges; // does this ranges have any meaning?
> > >
> > > I'd like to say, yes.
> > >
> > > >               bar@10 {
> > > >                       reg<0x10 …>
> > > >               };
> > > >       };
> > > > };
> > > > ```
> > > >
> > > > ```
> > > > / {
> > > >       foo { // not a bus
> > > >               #address-cells = <1>;
> > > >               #size-cells = <1>;
> > > >               reg = <0x100 0x50>;
> > > >               ranges = <0x0 0x100 0x50>; // is this an intended
> > > > use case?
> > >
> > > Depending on what the child node represents, but IMHO it comes with
> > > a
> > > clear meaning.
> > >
> > > >               bar@10 {
> > > >                       reg<0x10 …> // hence abs address is 0x110.
> > > >               };
> > > >       };
> > > > };
> > > > ```
> > > >
> > > > ```
> > > > / {
> > > >       foo { // bus
> > > >               compatible = <simple-bus>;
> > > >               #address-cells = <1>;
> > > >               #size-cells = <1>;
> > > >               ranges; // this I understand to declare that
> > > > children will have direct mapping
> > > >
> > > >               bar {
> > > >                       ranges; // is this needed? Or is it implied
> > > > that the foobar is in the same address space of bar?
> > >
> > > It's necessary. I don't think ranges property is ever implied.
> > >
> > > >                       foobar@10 {
> > > >                               reg<0x10 …>  // hence abs address
> > > > is 0x10.
> > > >                       };
> > > >               };
> > > >       };
> > > > };
> > > > ```
> > > >
> > > > ```
> > > > / {
> > > >       soc { // bus
> > > >               compatible = <simple-bus>;
> > > >               #address-cells = <1>;
> > > >               #size-cells = <1>;
> > > >               ranges; // this I understand to declare that
> > > > children will have direct mapping
> > > >
> > > >               flash@1000 {
> > > >                       reg<0x1000 …>
> > > >                       ranges = <0x0 0x1000 …>;
> > > >
> > > >                       partitions {
> > > >                               ranges;  // is this needed? Or is
> > > > it implied that the partition1 is in the same address space of
> > > > partitions?
> > >
> > > Personally I think it SHOULD be needed, though existing dt-bindings
> > > for
> > > fixed partition layout don't enforce such.
> > >
> > > I'm not very familiar with flash partitions and their dt patterns,
> > > so
> > > will leave the question for others :)
> >
> > It depends. Usually no, because the partition addresses are just
> > offsets in the flash device. They are their own address space and not
> > part of the CPU address space. An exception would be a parallel
> > nor-flash device that is memory-mapped into the CPU's address space.
> > Even then, it may not be all that useful to be able to translate a
> > specific partition address into a CPU address.
>
> In the case of simple MCUs where there isn't an MMU and flash is memory
> mapped, then it seems that using ranges would be the correct approach?
> e.g.

Loosely speaking, yes. There are a few wrinkles in this example
though.

>
> ```
> rram_controller: rram-controller@5004b000 {
> compatible = "nordic,rram-controller";
> reg = <0x5004b000 0x1000>;
> #address-cells = <1>;
> #size-cells = <1>;

There's no 'ranges' at this level, so nothing below is memory mapped.
That's not neccessarily wrong, but it doesn't match what you described
above.

> cpuflpr_rram: rram@165000 {
> compatible = "soc-nv-flash";
> reg = <0x165000 0x18000>; //Non-0 base address
> ranges = <0x0 0x165000 0x18000>; //Pass on full range
> to children

Having a ranges entry and reg entry overlap is.. unusual. There might
be cases where it makes more sense than the alternatives, but I'm not
sure if this is one of them. My inclination in this case would be to
omit the 'reg', and only leave the ranges. However it's possible that
would cause conflicts with existing bindings or drivers.

> #address-cells = <1>;
> #size-cells = <1>;
>
> partitions {
> compatible = "fixed-partitions";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges; //Pass parent's addresses on to
> children

This makes sense

>
> cpuflpr_code_partition: partition@0 {
> label = "image-0";
> reg = <0x0 0x18000>; //Offset 0 of
> parent (of parent) thus unit address is 0x165000

unit address is 0, because unit address is defined as the reg value.
The address of this device within the rram-controller address space is
0x165000. Since there's no 'ranges' in the rram-controller node,
that's an abstract address space that has no (direct) mapping into the
CPU's bus address space.

I'd say in principle that you're correct that ranges makes sense for
mapping partitions like this. I'm not sure if that matches with
existing bindings and conventions - and if it doesn't it's probably
more important to match those than to be correct to the overall
principles of how ranges works.

--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]