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:
@@ -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
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user