Search code examples
linux-kernellinux-device-driverembedded-linuxdevice-tree

Why my program gets wrong address-cell/size-cell values from Device tree?


I use libfdt and I have trouble to get right address-cell/size-cells values from reserved memory region node (leaf) into my device tree. fdt_address_cells returns 0x2 and fdt_size_cells returns 0x1 for "some-block" even though "address-cells"/"size-cells" are not specified into some-block node. fdt_address_cells/fdt_size_cells suppose to return "-FDT_BAD_NCELLS" based on their description into libfdt.h

`

reserved-memory {
        #address-cells = <0x02>;
        #size-cells = <0x02>;
        
       some-block {
            reg = <0x00 0xaa000000 0x00 0xbb00000>;
            no-map;
            compatible = "somevendor,something";
        };
 }

`

I expect that these function return "-FDT_BAD_NCELLS" if address-cells/size-cells are not specified into node.


Solution

  • From section 2.3.5. of The Devicetree specification v0.3:

    If missing, a client program should assume a default value of 2 for #address-cells, and a value of 1 for #size-cells.

    The documentation for the return values of fdt_address_cells() and fdt_size_cells() in libfdt agrees with this:

    /**
     * fdt_address_cells - retrieve address size for a bus represented in the tree
     * @fdt: pointer to the device tree blob
     * @nodeoffset: offset of the node to find the address size for
     *
     * When the node has a valid #address-cells property, returns its value.
     *
     * returns:
     *  0 <= n < FDT_MAX_NCELLS, on success
     *      2, if the node has no #address-cells property
     *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
     *      #address-cells property
     *  -FDT_ERR_BADMAGIC,
     *  -FDT_ERR_BADVERSION,
     *  -FDT_ERR_BADSTATE,
     *  -FDT_ERR_BADSTRUCTURE,
     *  -FDT_ERR_TRUNCATED, standard meanings
     */
    int fdt_address_cells(const void *fdt, int nodeoffset);
    
    /**
     * fdt_size_cells - retrieve address range size for a bus represented in the
     *                  tree
     * @fdt: pointer to the device tree blob
     * @nodeoffset: offset of the node to find the address range size for
     *
     * When the node has a valid #size-cells property, returns its value.
     *
     * returns:
     *  0 <= n < FDT_MAX_NCELLS, on success
     *      1, if the node has no #size-cells property
     *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
     *      #size-cells property
     *  -FDT_ERR_BADMAGIC,
     *  -FDT_ERR_BADVERSION,
     *  -FDT_ERR_BADSTATE,
     *  -FDT_ERR_BADSTRUCTURE,
     *  -FDT_ERR_TRUNCATED, standard meanings
     */
    int fdt_size_cells(const void *fdt, int nodeoffset);