diff options
| author | Tom Rini <[email protected]> | 2022-09-30 15:52:10 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2022-09-30 15:52:10 -0400 |
| commit | 6ee6e15975cad3c99fad3a66223f3fd9287a369b (patch) | |
| tree | 2a1798758c85d3010640cf6bacb1ad7caaa29133 /include/dm/ofnode_decl.h | |
| parent | 01c88e3dcd667281cf3aa6f6b47f90900177aff9 (diff) | |
| parent | db1ef1e12b993275e09f116ebc3d23d675c7e28c (diff) | |
Merge branch '2022-09-29-dm-core-support-multiple-device-trees-in-ofnode' into next
To quote the author:
At present the ofnode interface is somewhat limited, in that it cannot
access the device tree provided by the OS, only the one used by U-Boot
itself (assuming these are separate). This prevents using ofnode functions
to handle device tree fixups, i.e. ft_board_setup() and the like.
The ofnode interface was introduced to allow a consistent API to access
the device tree, whether a flat tree or a live tree (OF_LIVE) is in use.
With the flat tree, adding nodes and properties at the start of the tree
(as often happens when writing to the /chosen node) requires copying a
lot of data for each operation. With live tree, such operations are
quite a bit faster, since there is no memory copying required. This has to
be weighed against the required memory allocation with OF_LIVE, as well
as the cost of unflattening and flattening the device tree which U-Boot
is running.
This series enables support for access to multiple device trees with the
ofnode interface. This is already available to some extent with OF_LIVE,
but some of the ofnode functions need changes to allow the tree to be
specified.
The mechanism works by using the top 1-4 bits of the device tree offset.
The sign bit is not affected, since negative values must be supported.
With this implemented, it becomes possible to use the ofnode interface
to do device tree fixups. The only current user is the EVT_FT_FIXUP
event.
This has two main benefits:
- ofnode can now be used everywhere, in preference to the libfdt calls
- live tree can eventually be used everywhere, with potential speed
improvements when larger number of fixups are used
This series is only a step along the way. Firstly, while it is possible
to access the 'fix-up' tree using OF_LIVE, most of the fixup functions use
flat tree directly, rather than the ofnode interface. These need to be
updated. Also the tree must be flattened again before it is passed to the
OS. This is not currently implemented.
With OFNODE_MULTI_TREE disabled this has almost no effect on code size:
around 4 bytes if EVENT is enabled, 0 if not. With the feature enabled,
the increase is around 700 bytes, e.g. on venice2:
$ buildman -b ofn2a venice2 -sS --step 0
Summary of 2 commits for 1 boards (1 thread, 64 jobs per thread)
01: image: Drop some other #ifdefs in image-board.c
arm: w+ venice2
48: wip
arm: (for 1/1 boards) all +668.0 text +668.0
This size increase is not too bad, considering the extra functionality,
but is too large to enable everywhere. So for now this features needs to
be opt-in only, based on EVENT.
Diffstat (limited to 'include/dm/ofnode_decl.h')
| -rw-r--r-- | include/dm/ofnode_decl.h | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h index 266253d5e33..5c2115aab0b 100644 --- a/include/dm/ofnode_decl.h +++ b/include/dm/ofnode_decl.h @@ -31,18 +31,47 @@ * this increases code size slightly due to the subtraction. Since it offers no * real benefit, the approach described here seems best. * - * For now these points use constant types, since we don't allow writing - * the DT. + * Where multiple trees are in use, this works without any trouble with live + * tree, except for aliases, such as ofnode_path("mmc0"), which only work on the + * control FDT. When the flat tree is in use, the trees are registered and a + * 'tree ID' is encoded into the top bits of @of_offset - see immediately below + * for the associated macro definitions. Note that 64-bit machines use the same + * encoding, even though there is more space available. This is partly because + * the FDT format contains 32-bit values for things like the string-table + * offset, therefore 64-bit offsets cannot be supported anyway. + * + * For the multiple-tree case, an invalid offset (i.e. with of_offset < 0) is + * still invalid. It does not contain a tree ID. So there is no way of knowing + * which tree produced the invalid offset. * * @np: Pointer to device node, used for live tree * @of_offset: Pointer into flat device tree, used for flat tree. Note that this * is not a really a pointer to a node: it is an offset value. See above. */ typedef union ofnode_union { - const struct device_node *np; + struct device_node *np; long of_offset; } ofnode; +/* shift for the tree ID within of_offset */ +#define OF_TREE_SHIFT 28 + +/* mask to obtain the device tree offset from of_offset */ +#define OF_TREE_MASK ((1 << OF_TREE_SHIFT) - 1) + +/* encode a tree ID and node offset into an of_offset value */ +#define OFTREE_NODE(tree_id, offs) ((tree_id) << OF_TREE_SHIFT | (offs)) + +/* decode the node offset from an of_offset value */ +#define OFTREE_OFFSET(of_offs) ((of_offs) & OF_TREE_MASK) + +/* decode the tree ID from an of_offset value */ +#define OFTREE_TREE_ID(of_offs) ((of_offs) >> OF_TREE_SHIFT) + +/* encode a node offset in the tree given by another node's of_offset value */ +#define OFTREE_MAKE_NODE(other_of_offset, offs) \ + (((offs) & OF_TREE_MASK) | ((other_of_offset) & ~OF_TREE_MASK)) + /** * struct ofprop - reference to a property of a device tree node * @@ -57,7 +86,7 @@ typedef union ofnode_union { * * @node: Pointer to device node * @offset: Pointer into flat device tree, used for flat tree. - * @prop: Pointer to property, used for live treee. + * @prop: Pointer to property, used for live tree. */ struct ofprop { |
