lib: Add fdt_print() to print a node

Extract the core device tree printing logic from fdt_print_path() into
a new fdt_print() function that takes a node offset parameter. This
allows printing from any node offset rather than requiring a path string.

Pass in the fdt, for more flexibility.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-08-26 15:01:34 -06:00
parent c70aa53c2a
commit a52a0036bc
2 changed files with 67 additions and 41 deletions

View File

@@ -503,6 +503,19 @@ int fdt_kaslrseed(void *blob, bool overwrite);
*/
bool fdt_printable_str(const void *data, int len);
/*
* fdt_print() - Print a portion of the device tree starting from a node
*
* Recursively prints the device tree starting from the given node offset.
* The depth parameter controls how deeply nested nodes are printed.
*
* @fdt: Pointer to the device tree blob
* @nodeoffset: Node offset to start printing from
* @depth: Maximum depth to print
* Return: 0 on success, 1 on error
*/
int fdt_print(const void *fdt, int nodeoffset, int depth);
/**
* fdt_print_path() - Print a portion of the device tree
*

View File

@@ -110,62 +110,30 @@ static void print_data(const void *data, int len)
/****************************************************************************/
/*
* Recursively print (a portion of) the working_fdt. The depth parameter
* determines how deeply nested the fdt is printed.
* Recursively print (a portion of) an fdt starting from a node.
* The depth parameter determines how deeply nested the fdt is printed.
*/
int fdt_print_path(const char *pathp, char *prop, int depth)
int fdt_print(const void *fdt, int nodeoffset, int depth)
{
static char tabs[MAX_LEVEL+1] =
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
const void *nodep; /* property node pointer */
int nodeoffset; /* node offset from libfdt */
int nextoffset; /* next node offset from libfdt */
uint32_t tag; /* tag */
int len; /* length of the property */
int level = 0; /* keep track of nesting level */
const struct fdt_property *fdt_prop;
nodeoffset = fdt_path_offset (working_fdt, pathp);
if (nodeoffset < 0) {
/*
* Not found or something else bad happened.
*/
printf ("libfdt fdt_path_offset() returned %s\n",
fdt_strerror(nodeoffset));
return 1;
}
/*
* The user passed in a property as well as node path.
* Print only the given property and then return.
*/
if (prop) {
nodep = fdt_getprop (working_fdt, nodeoffset, prop, &len);
if (len == 0) {
/* no property value */
printf("%s %s\n", pathp, prop);
return 0;
} else if (nodep && len > 0) {
printf("%s = ", prop);
print_data (nodep, len);
printf("\n");
return 0;
} else {
printf ("libfdt fdt_getprop(): %s\n",
fdt_strerror(len));
return 1;
}
}
const char *pathp;
/*
* The user passed in a node path and no property,
* print the node and all subnodes.
* Print the node and all subnodes.
*/
while(level >= 0) {
tag = fdt_next_tag(working_fdt, nodeoffset, &nextoffset);
tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
switch(tag) {
case FDT_BEGIN_NODE:
pathp = fdt_get_name(working_fdt, nodeoffset, NULL);
pathp = fdt_get_name(fdt, nodeoffset, NULL);
if (level <= depth) {
if (pathp == NULL)
pathp = "/* NULL pointer error */";
@@ -189,9 +157,9 @@ int fdt_print_path(const char *pathp, char *prop, int depth)
}
break;
case FDT_PROP:
fdt_prop = fdt_offset_ptr(working_fdt, nodeoffset,
fdt_prop = fdt_offset_ptr(fdt, nodeoffset,
sizeof(*fdt_prop));
pathp = fdt_string(working_fdt,
pathp = fdt_string(fdt,
fdt32_to_cpu(fdt_prop->nameoff));
len = fdt32_to_cpu(fdt_prop->len);
nodep = fdt_prop->data;
@@ -229,3 +197,48 @@ int fdt_print_path(const char *pathp, char *prop, int depth)
}
return 0;
}
/*
* Print a portion of the working_fdt starting from a path.
* The depth parameter determines how deeply nested the fdt is printed.
*/
int fdt_print_path(const char *pathp, char *prop, int depth)
{
const void *nodep; /* property node pointer */
int nodeoffset; /* node offset from libfdt */
int len; /* length of the property */
nodeoffset = fdt_path_offset (working_fdt, pathp);
if (nodeoffset < 0) {
/*
* Not found or something else bad happened.
*/
printf ("libfdt fdt_path_offset() returned %s\n",
fdt_strerror(nodeoffset));
return 1;
}
/*
* The user passed in a property as well as node path.
* Print only the given property and then return.
*/
if (prop) {
nodep = fdt_getprop (working_fdt, nodeoffset, prop, &len);
if (len == 0) {
/* no property value */
printf("%s %s\n", pathp, prop);
return 0;
} else if (nodep && len > 0) {
printf("%s = ", prop);
print_data (nodep, len);
printf("\n");
return 0;
} else {
printf ("libfdt fdt_getprop(): %s\n",
fdt_strerror(len));
return 1;
}
}
/* Print the node and all subnodes using fdt_print() */
return fdt_print(working_fdt, nodeoffset, depth);
}