[PATCH v2 1/8] event: signal when livetree has been built

Simon Glass sjg at chromium.org
Thu Apr 17 23:37:07 CEST 2025


Hi Caleb,

On Mon, 14 Apr 2025 at 06:33, Caleb Connolly <caleb.connolly at linaro.org> wrote:
>
> Hi Simon,
>
> On 4/11/25 20:27, Simon Glass wrote:
> > Hi Caleb,
> >
> > On Fri, 11 Apr 2025 at 06:47, Caleb Connolly <caleb.connolly at linaro.org> wrote:
> >>
> >> OF_LIVE offers a variety of benefits, one of them being that the live
> >> tree can be modified without caring about the underlying FDT. This is
> >> particularly valuable for working around U-Boot limitations like lacking
> >> USB superspeed support on Qualcomm platforms, no runtime OTG, or
> >> peripherals like the sdcard being broken (and displaying potentially
> >> worrying error messages).
> >>
> >> Add an event to signal when the live tree has been built so that we can
> >> apply fixups to it directly before devices are bound.
> >>
> >> Signed-off-by: Caleb Connolly <caleb.connolly at linaro.org>
> >> ---
> >>   common/event.c  |  3 +++
> >>   include/event.h | 18 ++++++++++++++++++
> >>   lib/of_live.c   | 11 +++++++++++
> >>   3 files changed, 32 insertions(+)
> >>
> >> diff --git a/common/event.c b/common/event.c
> >> index dda569d447851f559a83f98fb7b1f3543156eab5..8d7513eb10b61919e1e784481dfdcc076be14986 100644
> >> --- a/common/event.c
> >> +++ b/common/event.c
> >> @@ -47,8 +47,11 @@ const char *const type_name[] = {
> >>          "ft_fixup",
> >>
> >>          /* main loop events */
> >>          "main_loop",
> >> +
> >> +       /* livetree has been built */
> >> +       "of_live_init",
> >>   };
> >>
> >>   _Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
> >>   #endif
> >> diff --git a/include/event.h b/include/event.h
> >> index 75141a192a48b0931667632f41be8ff4d6139f7c..1d267f1d10547642d381fa287ab4981a2bf03543 100644
> >> --- a/include/event.h
> >> +++ b/include/event.h
> >> @@ -152,8 +152,17 @@ enum event_t {
> >>           * A non-zero return value causes the boot to fail.
> >>           */
> >>          EVT_MAIN_LOOP,
> >>
> >> +       /**
> >> +        * @EVT_OF_LIVE_BUILT:
> >> +        * This event is triggered immediately after the live device tree has been
> >> +        * built. This allows for machine specific fixups to be done to the live tree
> >> +        * (like disabling known-unsupported devices) before it is used. This
> >> +        * event is only available if OF_LIVE is enabled and is only used after relocation.
> >
> > Add a bit more detail, e.g.: before it is used by U-Boot
> > post-relocation. This means it is possible to affect the devices bound
> > by driver model.
>
> I think this is really implied and made obvious by context clues. IF
> there comes a time where we build the live tree more than once (e.g. to
> build it as part of the DT_FIXUP_PROTOCOL for some reason) then the
> extra info you propose adding would no longer be correct, where the
> current wording would remain correct.

OK, leave it alone if you like.

>
> >
> > You should also note that the flattree is inactive when livetree is
> > used and any changes may eventually be passed onto the OS, if it
> > doesn't have its own devicetree. This is the point we were discussing
> > on the other thread.
>
> This information is totally irrelevant though, and there is no broad
> agreement with your proposed changes. The livetree API is also set up so
> that one could build multiple livetrees (for whatever reason), this
> event is modelled to reflect that (where you can see in my v1 patches
> that the event assumed you would only ever build the global tree).

Hmmm, if Linaro is going to block livetree fixups then we are going to
have a problem. I have not heard that, but let me know.

>
> >
> >> +        */
> >> +       EVT_OF_LIVE_BUILT,
> >> +
> >>          /**
> >>           * @EVT_COUNT:
> >>           * This constants holds the maximum event number + 1 and is used when
> >>           * looping over all event classes.
> >> @@ -202,8 +211,17 @@ union event_data {
> >>          struct event_ft_fixup {
> >>                  oftree tree;
> >>                  struct bootm_headers *images;
> >>          } ft_fixup;
> >> +
> >> +       /**
> >> +        * struct event_of_live_built - livetree has been built
> >> +        *
> >> +        * @root: The root node of the live device tree
> >> +        */
> >> +       struct event_of_live_built {
> >> +               struct device_node *root;
> >> +       } of_live_built;
> >>   };
> >>
> >>   /**
> >>    * struct event - an event that can be sent and received
> >> diff --git a/lib/of_live.c b/lib/of_live.c
> >> index 90b9459ede313e492e28c8556c730f3bd8aaa9df..c1620616513c2e32448b4a6d156a9162d97c76b7 100644
> >> --- a/lib/of_live.c
> >> +++ b/lib/of_live.c
> >> @@ -10,8 +10,9 @@
> >>
> >>   #define LOG_CATEGORY   LOGC_DT
> >>
> >>   #include <abuf.h>
> >> +#include <event.h>
> >>   #include <log.h>
> >>   #include <linux/libfdt.h>
> >>   #include <of_live.h>
> >>   #include <malloc.h>
> >> @@ -320,8 +321,9 @@ int unflatten_device_tree(const void *blob, struct device_node **mynodes)
> >>
> >>   int of_live_build(const void *fdt_blob, struct device_node **rootp)
> >>   {
> >>          int ret;
> >> +       union event_data evt;
> >>
> >>          debug("%s: start\n", __func__);
> >>          ret = unflatten_device_tree(fdt_blob, rootp);
> >>          if (ret) {
> >> @@ -334,8 +336,17 @@ int of_live_build(const void *fdt_blob, struct device_node **rootp)
> >>                  return ret;
> >>          }
> >>          debug("%s: stop\n", __func__);
> >>
> >> +       if (CONFIG_IS_ENABLED(EVENT)) {
> >> +               evt.of_live_built.root = *rootp;
> >> +               ret = event_notify(EVT_OF_LIVE_BUILT, &evt, sizeof(evt));
> >> +               if (ret) {
> >> +                       log_debug("Failed to notify livetree build event: err=%d\n", ret);
> >> +                       return ret;
> >> +               }
> >> +       }
> >> +
> >
> > This should move to the caller of this function. We should also have a
>
> Why move it to the caller? Then every caller would need to signal the
> event and we'd pointlessly duplicate code. The event signals that /a/
> livetree has been built. Today this only happens once and we make the
> assumption that this livetree is to be used by U-Boot and only U-Boot.
>
> Should this assumption become incorrect in the future, it would be
> trivial to introduce a variable to the event_data that describes what
> the livetree is and/or where it will be used so that anyone catching the
> event can decide what to do.
>
> Since we don't yet know any other usecases, it would be overzealous to
> try and capture this information since we just don't know what's important.

There is (and will only ever be) one caller. At this point I really
don't mind what you do.

>
> > sandbox test for this feature, e.g. catch the event and add a
> > node/prop and check in a test in test-fdt.c (or similar) that it is
> > present.
>
> What would this test other than that the event is sent? We already have
> tests for the event framework...

If the CI tests pass, then it's fine.


>
> >
> > I'm not sure if you need to update test_event_dump.py but since CI
> > presumably passes, I guess not.>
> >>          return ret;
> >>   }
> >>
> >>   void of_live_free(struct device_node *root)
> >>
> >> --
> >> 2.49.0
> >>

Regards,
Simon


More information about the U-Boot mailing list