On Mon, Mar 04, 2024 at 10:37:06AM +0100, Sascha Hauer wrote: > On Fri, Mar 01, 2024 at 02:04:43PM +0100, Ahmad Fatoum wrote: > > When finding compatible bootloader spec files, barebox will unflatten > > each DTB in turn, allocating objects for each property and node, only to > > compare a single property and then free all the allocations again. > > > > Given that this operation is repeated for every device tree until a > > match is found, it's a good idea to be able to compare machine > > (top-level) compatibles without having to unflatten the whole FDT. > > > > Implemnt fdt_machine_is_compatible() that does just that. This > > intentionally opencodes the device tree iteration as to minimize > > code and runtime size. Using libfdt without LTO would be slower > > and bigger. > > > > Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> > > --- > > drivers/of/fdt.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ > > include/of.h | 3 ++ > > 2 files changed, 98 insertions(+) > > > > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c > > index 676b8a5535bf..aa3d2e967acd 100644 > > --- a/drivers/of/fdt.c > > +++ b/drivers/of/fdt.c > > @@ -668,3 +668,98 @@ void fdt_print_reserve_map(const void *__fdt) > > return; > > } > > } > > + > > +static int fdt_string_is_compatible(const char *haystack, int haystack_len, > > + const char *needle, int needle_len) > > +{ > > + const char *p; > > + int index = 0; > > + > > + while (haystack_len >= needle_len) { > > + if (memcmp(needle, haystack, needle_len + 1) == 0) > > + return OF_DEVICE_COMPATIBLE_MAX_SCORE - (index << 2); > > + > > + p = memchr(haystack, '\0', haystack_len); > > + if (!p) > > + return 0; > > + haystack_len -= (p - haystack) + 1; > > + haystack = p + 1; > > + index++; > > + } > > + > > + return 0; > > +} > > + > > +bool fdt_machine_is_compatible(const struct fdt_header *fdt, size_t fdt_size, const char *compat) > > +{ > > + uint32_t tag; > > + const struct fdt_property *fdt_prop; > > + const char *name; > > + uint32_t dt_struct; > > + const struct fdt_node_header *fnh; > > + const void *dt_strings; > > + struct fdt_header f; > > + int ret, len; > > + int expect = FDT_BEGIN_NODE; > > + int compat_len = strlen(compat); > > + > > + ret = fdt_parse_header(fdt, fdt_size, &f); > > + if (ret < 0) > > + return ERR_PTR(ret); > > return false here Fixed while applying. Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |