From 968164b6863e3a75fb0f5842f4f1cab9ac7c8c36 Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Wed, 1 Apr 2026 16:15:17 +0200 Subject: vsprintf: add %pOF This prints a full ofnode path. Signed-off-by: Casey Connolly --- lib/vsprintf.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'lib') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index c7340a047b2..49dc9c38c65 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -26,6 +26,11 @@ #include #include +/* For %pOF */ +#if CONFIG_IS_ENABLED(OF_CONTROL) +#include +#endif + /* we use this so that we can do without the ctype library */ #define is_digit(c) ((c) >= '0' && (c) <= '9') @@ -438,6 +443,30 @@ static char *uuid_string(char *buf, char *end, u8 *addr, int field_width, } #endif +#if CONFIG_IS_ENABLED(OF_CONTROL) && !defined(API_BUILD) +static char *ofnode_string(char *buf, char *end, ofnode *dp, int field_width, + int precision, int flags) +{ +#define NP_PATH_MAX 64 + char str[NP_PATH_MAX] = { 0 }; + const char *err = "..."; + + /* If dp == NULL output the string '' */ + if (!dp || !ofnode_valid(*dp)) + return string(buf, end, NULL, field_width, precision, flags); + + /* Get the path and indicate if it got cut off */ + if (ofnode_get_path(*dp, str, NP_PATH_MAX)) { + str[NP_PATH_MAX - 1] = '\0'; + char *p = str + min((NP_PATH_MAX - 2) - strlen(err), strlen(str)); + memcpy(p, err, strlen(err) + 1); + } + + return string(buf, end, str, field_width, precision, flags); +#undef NP_PATH_MAX +} +#endif + /* * Show a '%p' thing. A kernel extension is that the '%p' is followed * by an extra set of alphanumeric characters that are extended format @@ -473,6 +502,14 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'D': return device_path_string(buf, end, ptr, field_width, precision, flags); +#endif +/* Device paths only exist in the EFI context. */ +#if CONFIG_IS_ENABLED(OF_CONTROL) && !defined(API_BUILD) + case 'O': + if (fmt[1] == 'F') + return ofnode_string(buf, end, ptr, field_width, + precision, flags); + break; #endif case 'a': flags |= SPECIAL | ZEROPAD; -- cgit v1.2.3 From 139f5292e7985d0326a1d18eee88720255e423dc Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Wed, 1 Apr 2026 16:15:19 +0200 Subject: string: add strdup_const and kstrdup_const Extend Linux compat by adding kstrdup_const(), backed by lib/string.c. This leverages U-Boots .rodata section on ARM64 to avoid pointlessly duplicating const strings. This is used by the Linux CCF_FULL port and may be useful elsewhere in U-Boot. Signed-off-by: Casey Connolly --- lib/string.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'lib') diff --git a/lib/string.c b/lib/string.c index d56f88d4a84..302efe048b0 100644 --- a/lib/string.c +++ b/lib/string.c @@ -379,6 +379,37 @@ char * strndup(const char *s, size_t n) return new; } + +/** + * strdup_const - conditionally duplicate an existing const string + * @s: the string to duplicate + * + * Note: Strings allocated by kstrdup_const should be freed by kfree_const and + * must not be passed to krealloc(). + * + * Return: source string if it is in .rodata section otherwise + * fallback to kstrdup. + */ +const char *strdup_const(const char *s) +{ + if (is_kernel_rodata((unsigned long)s)) + return s; + + return strdup(s); +} + +/** + * kfree_const - conditionally free memory + * @x: pointer to the memory + * + * Function calls kfree only if @x is not in .rodata section. + */ +void kfree_const(const void *x) +{ + if (!is_kernel_rodata((unsigned long)x)) + free((void *)x); +} + #endif #ifndef __HAVE_ARCH_STRSPN -- cgit v1.2.3 From 45c610d718bd605a1b3bdf99ec0386620b54b559 Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Wed, 1 Apr 2026 16:15:20 +0200 Subject: ofnode: add read_u64_array and count_elems_of_size These are similar to their Linux counterparts, adding helpers for reading arrays of 64-bit values with of_access and fdtdec implementations. Signed-off-by: Casey Connolly --- lib/fdtdec.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index c38738b48c7..e23e53f58f2 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -714,6 +714,24 @@ int fdtdec_get_int_array(const void *blob, int node, const char *prop_name, return err; } +int fdtdec_get_long_array(const void *blob, int node, const char *prop_name, + u64 *array, int count) +{ + const u64 *cell; + int err = 0; + + debug("%s: %s\n", __func__, prop_name); + cell = get_prop_check_min_len(blob, node, prop_name, + sizeof(u64) * count, &err); + if (!err) { + int i; + + for (i = 0; i < count; i++) + array[i] = fdt64_to_cpu(cell[i]); + } + return err; +} + int fdtdec_get_int_array_count(const void *blob, int node, const char *prop_name, u32 *array, int count) { -- cgit v1.2.3