On 04.03.24 10:37, 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 Ouch. Thanks for fixing! > > 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 |