#address-cells and #size-cells field in device tree overlay range property

1

I am trying to load a file into a stratix10 FPGA and map the FPGA busses using the embedded Hard processor, ARM running linux

(Linux 5.4.23-03466-gcc83036e6a78 #1 SMP PREEMPT Wed Aug 5 10:15:00 CEST 2020 aarch64 GNU/Linux).

This is done with device tree overlays.

The main device tree contains: (where [...] indicates removed section of -hopefully- no interrest)

#include "socfpga_stratix10.dtsi"

/ {
   [...]
       soc {
                clocks {
                        osc1 {
                                clock-frequency = <25000000>;
                        };
                };

                eccmgr {
                        sdmmca-ecc@ff8c8c00 {
                                compatible = "altr,socfpga-s10-sdmmc-ecc",
                                             "altr,socfpga-sdmmc-ecc";
                                reg = <0xff8c8c00 0x100>;
                                altr,ecc-parent = <&mmc>;
                                interrupts = <14 4>,
                                             <15 4>;
                        };
                };
        };
};

The included file, socfpga_stratix10.dtsi contains:

/{
        soc {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "simple-bus";
                device_type = "soc";
                interrupt-parent = <&intc>;
                ranges = <0 0 0 0xffffffff>;

                base_fpga_region {
                        #address-cells = <0x1>;
                        #size-cells = <0x1>;

                        compatible = "fpga-region";
                        fpga-mgr = <&fpga_mgr>;
                };
        [...]
        };
[...]
};

Note that fields #address-cells and #size-cells are set to <1> in both the parent (/soc) and child(/soc/base_fpga_region) nodes. My initial try for the device tree overlay hence looked like this:

/dts-v1/;
/plugin/;
/ {
        fragment@1 {
                target-path = "/soc/base_fpga_region";
                __overlay__ {
                        firmware-name = "fpga_image.rbf";
                        config-complete-timeout-us = <3000000>;
                        #address-cells = <1>;                           /* address in the child (fpga region) space are given as 1 U32 values */
                        #size-cells = <1>;                              /* sizes   in the child (fpga region) space are given as 1 U32 values */
                                                                        /* mapping from ARM address to FPGA addresses: */
                                                                        /* see https://www.intel.com/content/www/us/en/programmable/hps/stratix-10/hps.html */
                        ranges = <0x00000000 0x80000000 0x40000000>,    /* hps to FPGA mapping: address 0 of the child bus mapps to address 80000000 in the parent space: length 0x40000 */
                                 <0x00000000 0xf9000000 0x00200000>;    /* lightweight hps to FPGA mapping: 0 maps to parent f9000000. length 1000 */
                };
        };
};

But when I compile this device tree, I get:

arch/arm64/boot/dts/altera/socfpga_stratix10_ovl_load.dts:13.4-14.41: Warning (ranges_format): /fragment@1/__overlay__:ranges: "ranges" property has invalid length (24 bytes) (parent #address-cells == 2, child #address-cells == 1, #size-cells == 1)
arch/arm64/boot/dts/altera/socfpga_stratix10_ovl_load.dts:6.15-15.5: Warning (avoid_default_addr_size): /fragment@1/__overlay__: Relying on default #address-cells value
arch/arm64/boot/dts/altera/socfpga_stratix10_ovl_load.dts:6.15-15.5: Warning (avoid_default_addr_size): /fragment@1/__overlay__: Relying on default #size-cells value

OK... after all, the compiler maybe does not know much about the parent node /soc when compiling my overlay, and takes default values for #address-cells and #size-cells... So I added a little reminder in my overlay as follows:

dts-v1/;
/plugin/;
/ {
        fragment@0 {
                target-path = "/soc";
                __overlay__ {
                        #address-cells = <1>;                           /* */
                        #size-cells = <1>;                              /* */
                };
        };

        fragment@1 {
                target-path = "/soc/base_fpga_region";
                __overlay__ {
                        firmware-name = "fpga_image.rbf";
                        config-complete-timeout-us = <3000000>;
                        #address-cells = <1>;                           /* address in the child (fpga region) space are given as 1 U32 values */
                        #size-cells = <1>;                              /* sizes   in the child (fpga region) space are given as 1 U32 values */
                                                                        /* mapping from ARM address to FPGA addresses: */
                                                                        /* see https://www.intel.com/content/www/us/en/programmable/hps/stratix-10/hps.html */
                        ranges = <0x00000000 0x80000000 0x40000000>,    /* hps to FPGA mapping: address 0 of the child bus mapps to address 80000000 in the parent space: length 0x40000 */
                                 <0x00000000 0xf9000000 0x00200000>;    /* lightweight hps to FPGA mapping: 0 maps to parent f9000000. length 1000 */
                };
        };
};

But that did not do any difference! I still get:

arch/arm64/boot/dts/altera/socfpga_stratix10_ovl_load.dts:21.4-22.41: Warning (ranges_format): /fragment@1/__overlay__:ranges: "ranges" property has invalid length (24 bytes) (parent #address-cells == 2, child #address-cells == 1, #size-cells == 1)
arch/arm64/boot/dts/altera/socfpga_stratix10_ovl_load.dts:14.15-23.5: Warning (avoid_default_addr_size): /fragment@1/__overlay__: Relying on default #address-cells value
arch/arm64/boot/dts/altera/socfpga_stratix10_ovl_load.dts:14.15-23.5: Warning (avoid_default_addr_size): /fragment@1/__overlay__: Relying on default #size-cells value

That confuses me a bit: the #address-cells of the parent /soc node is now clearly specified (twice: once in the original device-tree and once in the overlay)...

What is going on? what am I doing wrong?

In desperation I also tried (note the extra zero for the parent adress in the range spec):

/dts-v1/;
/plugin/;
/ {
        fragment@1 {
                target-path = "/soc/base_fpga_region";
                __overlay__ {
                        firmware-name = "fpga_image.rbf";
                        config-complete-timeout-us = <3000000>;
                        #address-cells = <1>;                           /* address in the child (fpga region) space are given as 1 U32 values */
                        #size-cells = <1>;                              /* sizes   in the child (fpga region) space are given as 1 U32 values */
                                                                        /* mapping from ARM address to FPGA addresses: */
                                                                        /* see https://www.intel.com/content/www/us/en/programmable/hps/stratix-10/hps.html */
                        ranges = <0x00000000 0 0x80000000 0x40000000>,  /* hps to FPGA mapping: address 0 of the child bus mapps to address 80000000 in the parent space: length 0x40000 */
                                 <0x00000000 0 0xf9000000 0x00200000>;  /* lightweight hps to FPGA mapping: 0 maps to parent f9000000. length 1000 */
                };
        };
};

which compiles with the usual warning:

arch/arm64/boot/dts/altera/socfpga_stratix10_ovl_load.dts:6.15-15.5: Warning (avoid_default_addr_size): /fragment@1/__overlay__: Relying on default #address-cells value
arch/arm64/boot/dts/altera/socfpga_stratix10_ovl_load.dts:6.15-15.5: Warning (avoid_default_addr_size): /fragment@1/__overlay__: Relying on default #size-cells value

But when I apply my overlay and try to access something in the mapped region (e.g. at address 0xF9000000 for the light weight bus), it result in a Bus Error... Which possibly tells me that even this was not done as I wished...

The device tree specification says:

The child-bus-addressis a physical address within the child bus address space. The number of cells to represent the address is bus dependent and can be determined from the #address-cells of this node (the node in which the ranges property appears)

The parent-bus-address is a physical address within the parent bus address space. The number of cells to represent the parent address is bus dependent and can be determined from the #address-cellsproperty of the node that defines the parent’s address space.

The length specifies the size of the range in the child’s address space. The number of cells to represent the size can be determined from the #size-cellsof this node (the node in which the rangesproperty appears).

From this, I don't understand why my first, or at least second attempt failed. When it comes to the third desperate attempt, I am not sure what gets done, but comments are appreciated. Thanks

linux
embedded-linux
fpga
intel-fpga
device-tree
asked on Stack Overflow Aug 5, 2020 by user1159290 • edited Aug 5, 2020 by user1159290

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0