fdt: Add get commands to fdt
Add commands to access data in the fdt. This allows data from a dtb or itb to be accessed from the shell scripts. Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
This commit is contained in:
parent
f0a29d4331
commit
bc80295b62
144
common/cmd_fdt.c
144
common/cmd_fdt.c
@ -47,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
static int fdt_valid(void);
|
static int fdt_valid(void);
|
||||||
static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
|
static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
|
||||||
static int fdt_print(const char *pathp, char *prop, int depth);
|
static int fdt_print(const char *pathp, char *prop, int depth);
|
||||||
|
static int is_printable_string(const void *data, int len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The working_fdt points to our working flattened device tree.
|
* The working_fdt points to our working flattened device tree.
|
||||||
@ -63,6 +64,34 @@ void set_working_fdt_addr(void *addr)
|
|||||||
setenv("fdtaddr", buf);
|
setenv("fdtaddr", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a value from the fdt and format it to be set in the environment
|
||||||
|
*/
|
||||||
|
static int fdt_value_setenv(const void *nodep, int len, const char *var)
|
||||||
|
{
|
||||||
|
if (is_printable_string(nodep, len))
|
||||||
|
setenv(var, (void *)nodep);
|
||||||
|
else if (len == 4) {
|
||||||
|
char buf[11];
|
||||||
|
|
||||||
|
sprintf(buf, "0x%08X", *(uint32_t *)nodep);
|
||||||
|
setenv(var, buf);
|
||||||
|
} else if (len%4 == 0 && len <= 20) {
|
||||||
|
/* Needed to print things like sha1 hashes. */
|
||||||
|
char buf[41];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += sizeof(unsigned int))
|
||||||
|
sprintf(buf + (i * 2), "%08x",
|
||||||
|
*(unsigned int *)(nodep + i));
|
||||||
|
setenv(var, buf);
|
||||||
|
} else {
|
||||||
|
printf("error: unprintable value\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flattened Device Tree command, see the help for parameter definitions.
|
* Flattened Device Tree command, see the help for parameter definitions.
|
||||||
*/
|
*/
|
||||||
@ -253,6 +282,117 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Get the value of a property in the working_fdt.
|
||||||
|
********************************************************************/
|
||||||
|
} else if (argv[1][0] == 'g') {
|
||||||
|
char *subcmd; /* sub-command */
|
||||||
|
char *pathp; /* path */
|
||||||
|
char *prop; /* property */
|
||||||
|
char *var; /* variable to store result */
|
||||||
|
int nodeoffset; /* node offset from libfdt */
|
||||||
|
const void *nodep; /* property node pointer */
|
||||||
|
int len = 0; /* new length of the property */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parameters: Node path, property, optional value.
|
||||||
|
*/
|
||||||
|
if (argc < 5)
|
||||||
|
return CMD_RET_USAGE;
|
||||||
|
|
||||||
|
subcmd = argv[2];
|
||||||
|
|
||||||
|
if (argc < 6 && subcmd[0] != 's')
|
||||||
|
return CMD_RET_USAGE;
|
||||||
|
|
||||||
|
var = argv[3];
|
||||||
|
pathp = argv[4];
|
||||||
|
prop = argv[5];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subcmd[0] == 'n' || (subcmd[0] == 's' && argc == 5)) {
|
||||||
|
int reqIndex = -1;
|
||||||
|
int startDepth = fdt_node_depth(
|
||||||
|
working_fdt, nodeoffset);
|
||||||
|
int curDepth = startDepth;
|
||||||
|
int curIndex = -1;
|
||||||
|
int nextNodeOffset = fdt_next_node(
|
||||||
|
working_fdt, nodeoffset, &curDepth);
|
||||||
|
|
||||||
|
if (subcmd[0] == 'n')
|
||||||
|
reqIndex = simple_strtoul(argv[5], NULL, 16);
|
||||||
|
|
||||||
|
while (curDepth > startDepth) {
|
||||||
|
if (curDepth == startDepth + 1)
|
||||||
|
curIndex++;
|
||||||
|
if (subcmd[0] == 'n' && curIndex == reqIndex) {
|
||||||
|
const char *nodeName = fdt_get_name(
|
||||||
|
working_fdt, nextNodeOffset, NULL);
|
||||||
|
|
||||||
|
setenv(var, (char *)nodeName);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
nextNodeOffset = fdt_next_node(
|
||||||
|
working_fdt, nextNodeOffset, &curDepth);
|
||||||
|
if (nextNodeOffset < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (subcmd[0] == 's') {
|
||||||
|
/* get the num nodes at this level */
|
||||||
|
char buf[11];
|
||||||
|
|
||||||
|
sprintf(buf, "%d", curIndex + 1);
|
||||||
|
setenv(var, buf);
|
||||||
|
} else {
|
||||||
|
/* node index not found */
|
||||||
|
printf("libfdt node not found\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nodep = fdt_getprop(
|
||||||
|
working_fdt, nodeoffset, prop, &len);
|
||||||
|
if (len == 0) {
|
||||||
|
/* no property value */
|
||||||
|
setenv(var, "");
|
||||||
|
return 0;
|
||||||
|
} else if (len > 0) {
|
||||||
|
if (subcmd[0] == 'v') {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = fdt_value_setenv(nodep, len, var);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
} else if (subcmd[0] == 'a') {
|
||||||
|
/* Get address */
|
||||||
|
char buf[11];
|
||||||
|
|
||||||
|
sprintf(buf, "0x%08X", (uint32_t)nodep);
|
||||||
|
setenv(var, buf);
|
||||||
|
} else if (subcmd[0] == 's') {
|
||||||
|
/* Get size */
|
||||||
|
char buf[11];
|
||||||
|
|
||||||
|
sprintf(buf, "0x%08X", len);
|
||||||
|
setenv(var, buf);
|
||||||
|
} else
|
||||||
|
return CMD_RET_USAGE;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("libfdt fdt_getprop(): %s\n",
|
||||||
|
fdt_strerror(len));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print (recursive) / List (single level)
|
* Print (recursive) / List (single level)
|
||||||
*/
|
*/
|
||||||
@ -836,6 +976,10 @@ U_BOOT_CMD(
|
|||||||
"fdt resize - Resize fdt to size + padding to 4k addr\n"
|
"fdt resize - Resize fdt to size + padding to 4k addr\n"
|
||||||
"fdt print <path> [<prop>] - Recursive print starting at <path>\n"
|
"fdt print <path> [<prop>] - Recursive print starting at <path>\n"
|
||||||
"fdt list <path> [<prop>] - Print one level starting at <path>\n"
|
"fdt list <path> [<prop>] - Print one level starting at <path>\n"
|
||||||
|
"fdt get value <var> <path> <prop> - Get <property> and store in <var>\n"
|
||||||
|
"fdt get name <var> <path> <index> - Get name of node <index> and store in <var>\n"
|
||||||
|
"fdt get addr <var> <path> <prop> - Get start address of <property> and store in <var>\n"
|
||||||
|
"fdt get size <var> <path> [<prop>] - Get size of [<property>] or num nodes and store in <var>\n"
|
||||||
"fdt set <path> <prop> [<val>] - Set <property> [to <val>]\n"
|
"fdt set <path> <prop> [<val>] - Set <property> [to <val>]\n"
|
||||||
"fdt mknode <path> <node> - Create a new node after <path>\n"
|
"fdt mknode <path> <node> - Create a new node after <path>\n"
|
||||||
"fdt rm <path> [<prop>] - Delete the node or <property>\n"
|
"fdt rm <path> [<prop>] - Delete the node or <property>\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user