2

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

user1159290
  • 951
  • 9
  • 27
  • size-cells doesn't inherit from the parent neccessarily, it depends on the number of addresses: you have two there, so it should be #size-cells = <2>; surely ? – secret squirrel Aug 05 '20 at 15:48
  • The compiler says there is a <2> somewhere, but I don't see where this comes from... I have <1> everywhere in my dts/dtsi files, haven't I? – user1159290 Aug 05 '20 at 16:09
  • where you have ranges = <0x00000000 0 0x80000000 0x40000000>, <0x00000000 0 0xf9000000 0x00200000>; thats two – secret squirrel Aug 05 '20 at 16:10
  • I mean, you quote it yourself: The length specifies the size of the range in the child’s address space. – secret squirrel Aug 05 '20 at 16:12
  • So I would try #address-cells = <2>;/ #size-cells = <1>; but these things are very tricky sometimes ;) – secret squirrel Aug 05 '20 at 16:13
  • I did try 4 cells indeed as a last try ( <0x00000000 0 0x80000000 0x40000000>) because the compilers kept telling me it beleives the parent node has address-cells set to <2> (the default), despite all my statements it is <1>! This range statemenet does not set the number of cell: it is is simply using the number of cell (which I expected to be <1> but the compiler has set has <2> for a reason I'd like to understand) – user1159290 Aug 06 '20 at 06:14
  • Also note that I have specified both the parent (/soc) and child size to 1, so I cannot see any inheritance taking place here, not either way the device tree compiler would use any default values as all are specified to 1 – user1159290 Aug 06 '20 at 06:16

0 Answers0