[U-Boot] [PATCH 00/22] dm: Add support for a 'live' device tree

Simon Glass sjg at chromium.org
Sat Apr 1 04:21:34 UTC 2017


Hi Tom,

On 21 March 2017 at 08:07, Tom Rini <trini at konsulko.com> wrote:
> On Sat, Feb 04, 2017 at 07:34:59PM -0800, Simon Glass wrote:
>> Hi,
>>
>> On 17 January 2017 at 21:50, Simon Glass <sjg at chromium.org> wrote:
>> > So far U-Boot uses a 'flat' device tree, which means that it is decoded
>> > on the fly as needed. This uses the libfdt library and avoids needing
>> > extra memory for additional tables.
>> >
>> > For some time there has been discussion about moving U-Boot to use a
>> > 'live' tree, where the device tree is decoded at start-up into a set of
>> > hierarchical structures with pointers.
>> >
>> > The advantages are:
>> >
>> > - It is somewhat faster to access (in particular scanning and looking for a
>> >     parent)
>> > - It permits the device tree to be changed at run-time (this is not
>> >     recommended at present since devices store the offset of their device
>> >     tree node and updating the tree may invalidate that). This could be
>> >     useful for overlays, for example.
>> > - It allows nodes to be referenced by a single pointer, instead of the
>> >     current device tree pointer plus offset
>> >
>> > The disadvantages are:
>> >
>> > - It requires more memory
>> > - It takes (a little) time to build the live tree
>> > - It adds more complexity under the hood, including an additional
>> >     abstraction layer
>> >
>> > This series is an attempt to introduce a useful live tree feature into
>> > U-Boot. There are many options and trade-offs. This series is the
>> > culmination of quite a bit of thought and experimentation.
>> >
>> > The approach used in this series is:
>> >
>> > - Before relocation the flat tree is used, to avoid extra memory usage
>> > and time. In general, there is not much access before relocation since
>> > most drivers are not started up. So there is little benefit in having a
>> > live tree
>> >
>> > - After relocation the live tree is built. At this point the CPU should be
>> > running quickly and there is plenty of memory. All available devices will
>> > be bound so the overhead of building the live tree may be outweighed by
>> > its greater efficiency.
>> >
>> > As a simplification, this series supports only one tree or the other. When
>> > the live tree is active, the flat tree cannot be used. That makes it easy
>> > to know the current state and avoids confusion over mixing offset and node
>> > pointers.
>> >
>> > Some drivers will need to be used both before and after relocation. This
>> > means that they must support both the flat and the live tree. To support
>> > this, the concept of a node 'reference' is defined. A reference can hold
>> > either a node offset (for the flat tree) or a node pointer (for the live
>> > tree). This allows drivers to access values from the tree regardless of
>> > which tree is in use.
>> >
>> > In addition, since most device tree access happens in the context of a
>> > device (struct udevice), a new 'dev_read' layer is provided to read device
>> > tree configuration associated with a device. This encapsulates the details
>> > of exactly how this information is read.
>> >
>> > I have taken the view that code compatibility with Linux is desirable. So
>> > the of_access.c file brings in code from Linux with very little
>> > modification. As new access methods are needed we should be able to bring
>> > in more code and avoid writing it ourselves in U-Boot.
>> >
>> > Conversion of drivers and subsystems to support the live tree (as well as
>> > flat tree) is fairly easy. A patch is included to add support to the GPIO
>> > uclass, and the cros_ec device is converted over to provide a driver
>> > example.
>> >
>> > Once I have comments on this series I will update it to build for all
>> > boards, to pass current tests and to tidy up the code. I will also add
>> > tests for the live tree and finish conversion for sandbox. So for now I am
>> > just looking for high-level comments, rather than a detailed code review.
>> >
>> >
>> > Simon Glass (22):
>> >   dm: core: Set return value first in lists_bind_fdt()
>> >   dm: core: atmel: Dont export dm_scan_fdt_node()
>> >   Update WARN_ON() to return a value
>> >   dm: Add livetree definitions
>> >   dm: Add livetree access functions
>> >   dm: Add a function to create a 'live' device tree
>> >   dm: Build a live tree after relocation
>> >   dm: Add support for device tree references
>> >   dm: Add a place to put extra device-tree reading functions
>> >   dm: core: Add device-based functions to access DT properties
>> >   dm: core: Allow binding a device from a live tree
>> >   dm: core: Add a method to find a driver for a livetree node
>> >   dm: core: Scan the live tree when setting up driver model
>> >   dm: core: Add a way to find a device by its live-tree node
>> >   dm: core: Add a way to find a device by node reference
>> >   dm: gpio: Refactor to prepare for live tree support
>> >   dm: gpio: Add live tree support
>> >   dm: gpio: Drop blank line in gpio_xlate_offs_flags() comment
>> >   dm: gpio: sandbox: Use dm_read...() functions to access DT
>> >   cros_ec: Fix debug() statement in ec_command_inptr()
>> >   cros_ec: Convert to support live tree
>> >   sandbox: Move to use live tree
>> >
>>
>> Any comments on the general concept?
>>
>> If you want to see what code that uses this might look like, see the
>> patch 'cros_ec: Convert to support live tree'.
>
> So, in the end, are the interfaces drivers use easier?  Do we reduce or
> further increase the overall amount of code?  How does this look on the
> binary size side of things?  Those kind of things are my biggest
> questions after giving the series a quick look.  I'm not sure either way
> at this moment, especially given what Franklin Cooper is doing on
> keystone 2 for example (we need to switch from a "generic" SoC tree to
> the real board tree, so he adds a hook to change the tree very early
> on).  Thanks!

1. Driver ease of writing

I believe the interface makes drivers a bit easier, e.g.:

dev_read_u32_defaut(dev, "propname", default_val)

instead of:

fdtget_get_int(gd->of_blob, dev_of_offset(dev), "propname", default_val)

2. Amount of driver code

It reduces the amount of code in drivers slightly due to the above,
and the fact that you don't need to deal with the device tree pointer
and offsets directory.

It adds another layer so there is more code overall, but (a) it is
optional so can be skipped for SPL where we don't want a livetree and
(b) it is a one-time increase so as more code is added the percentage
of increase falls

3. Binary size

Obviously there is an increase to support livetree, but it is not
large. I cannot measure it easily until I convert (say) an ARM board.
But basically it is the livetree generation code (which is small) and
the translation library (which converts node reference to either
fdtdec_... or of_... calls). You don't get anything for free, but this
is not a big change.

One benefit of doing this change soon is that it reduces the migration
cost. I am not quite happen with fdtdec_...(blob, offset...)
everywhere.

Perhaps I should try to convert an ARM board over and see how it looks.

Regards,
Simon


More information about the U-Boot mailing list