|
@@ -56,27 +56,38 @@ static char data[SCRATCHPAD];
|
|
|
static int fdt_valid(void);
|
|
|
static void print_data(const void *data, int len);
|
|
|
|
|
|
+static int findnodeoffset(const char *pathp)
|
|
|
+{
|
|
|
+ int nodeoffset;
|
|
|
+
|
|
|
+ if (strcmp(pathp, "/") == 0) {
|
|
|
+ nodeoffset = 0;
|
|
|
+ } else {
|
|
|
+ nodeoffset = fdt_path_offset (fdt, pathp);
|
|
|
+ if (nodeoffset < 0) {
|
|
|
+ /*
|
|
|
+ * Not found or something else bad happened.
|
|
|
+ */
|
|
|
+ printf ("findnodeoffset() libfdt: %s\n", fdt_strerror(nodeoffset));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nodeoffset;
|
|
|
+}
|
|
|
|
|
|
/*
|
|
|
* Flattened Device Tree command, see the help for parameter definitions.
|
|
|
*/
|
|
|
int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
{
|
|
|
- char op;
|
|
|
-
|
|
|
if (argc < 2) {
|
|
|
printf ("Usage:\n%s\n", cmdtp->usage);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * Figure out which subcommand was given
|
|
|
- */
|
|
|
- op = argv[1][0];
|
|
|
/********************************************************************
|
|
|
* Set the address of the fdt
|
|
|
********************************************************************/
|
|
|
- if (op == 'a') {
|
|
|
+ if (argv[1][0] == 'a') {
|
|
|
/*
|
|
|
* Set the address [and length] of the fdt.
|
|
|
*/
|
|
@@ -102,7 +113,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
*/
|
|
|
err = fdt_open_into(fdt, fdt, len);
|
|
|
if (err != 0) {
|
|
|
- printf ("libfdt: %s\n", fdt_strerror(err));
|
|
|
+ printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -110,7 +121,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
/********************************************************************
|
|
|
* Move the fdt
|
|
|
********************************************************************/
|
|
|
- } else if (op == 'm') {
|
|
|
+ } else if ((argv[1][0] == 'm') && (argv[1][1] == 'o')) {
|
|
|
struct fdt_header *newaddr;
|
|
|
int len;
|
|
|
int err;
|
|
@@ -150,15 +161,48 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
*/
|
|
|
err = fdt_open_into(fdt, newaddr, len);
|
|
|
if (err != 0) {
|
|
|
- printf ("libfdt: %s\n", fdt_strerror(err));
|
|
|
+ printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err));
|
|
|
return 1;
|
|
|
}
|
|
|
fdt = newaddr;
|
|
|
|
|
|
/********************************************************************
|
|
|
- * Set the value of a node in the fdt.
|
|
|
+ * Make a new node
|
|
|
+ ********************************************************************/
|
|
|
+ } else if ((argv[1][0] == 'm') && (argv[1][1] == 'k')) {
|
|
|
+ char *pathp; /* path */
|
|
|
+ char *nodep; /* new node to add */
|
|
|
+ int nodeoffset; /* node offset from libfdt */
|
|
|
+ int err;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Parameters: Node path, new node to be appended to the path.
|
|
|
+ */
|
|
|
+ if (argc < 4) {
|
|
|
+ printf ("Usage:\n%s\n", cmdtp->usage);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ pathp = argv[2];
|
|
|
+ nodep = argv[3];
|
|
|
+
|
|
|
+ nodeoffset = findnodeoffset(pathp);
|
|
|
+ if (nodeoffset < 0) {
|
|
|
+ /*
|
|
|
+ * Not found or something else bad happened.
|
|
|
+ */
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ err = fdt_add_subnode(fdt, nodeoffset, nodep);
|
|
|
+ if (err < 0) {
|
|
|
+ printf ("libfdt fdt_add_subnode(): %s\n", fdt_strerror(err));
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /********************************************************************
|
|
|
+ * Set the value of a property in the fdt.
|
|
|
********************************************************************/
|
|
|
- } else if (op == 's') {
|
|
|
+ } else if (argv[1][0] == 's') {
|
|
|
char *pathp; /* path */
|
|
|
char *prop; /* property */
|
|
|
struct fdt_property *nodep; /* node struct pointer */
|
|
@@ -183,102 +227,85 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
prop = argv[3];
|
|
|
newval = argv[4];
|
|
|
|
|
|
- if (strcmp(pathp, "/") == 0) {
|
|
|
- nodeoffset = 0;
|
|
|
- } else {
|
|
|
- nodeoffset = fdt_path_offset (fdt, pathp);
|
|
|
- if (nodeoffset < 0) {
|
|
|
- /*
|
|
|
- * Not found or something else bad happened.
|
|
|
- */
|
|
|
- printf ("libfdt: %s\n", fdt_strerror(nodeoffset));
|
|
|
- return 1;
|
|
|
- }
|
|
|
- }
|
|
|
- nodep = fdt_getprop (fdt, nodeoffset, prop, &oldlen);
|
|
|
- if (oldlen < 0) {
|
|
|
- printf ("libfdt %s\n", fdt_strerror(oldlen));
|
|
|
- return 1;
|
|
|
- } else if (oldlen == 0) {
|
|
|
+ nodeoffset = findnodeoffset(pathp);
|
|
|
+ if (nodeoffset < 0) {
|
|
|
/*
|
|
|
- * The specified property has no value
|
|
|
+ * Not found or something else bad happened.
|
|
|
*/
|
|
|
- printf("%s has no value, cannot set one (yet).\n", prop);
|
|
|
return 1;
|
|
|
- } else {
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * Convert the new property
|
|
|
+ */
|
|
|
+ vp = data;
|
|
|
+ if (*newval == '<') {
|
|
|
/*
|
|
|
- * Convert the new property
|
|
|
+ * Bigger values than bytes.
|
|
|
*/
|
|
|
- vp = data;
|
|
|
- if (*newval == '<') {
|
|
|
- /*
|
|
|
- * Bigger values than bytes.
|
|
|
- */
|
|
|
- len = 0;
|
|
|
- newval++;
|
|
|
- while ((*newval != '>') && (*newval != '\0')) {
|
|
|
- cp = newval;
|
|
|
- tmp = simple_strtoul(cp, &newval, 16);
|
|
|
- if ((newval - cp) <= 2) {
|
|
|
- *vp = tmp & 0xFF;
|
|
|
- vp += 1;
|
|
|
- len += 1;
|
|
|
- } else if ((newval - cp) <= 4) {
|
|
|
- *(uint16_t *)vp = __cpu_to_be16(tmp);
|
|
|
- vp += 2;
|
|
|
- len += 2;
|
|
|
- } else if ((newval - cp) <= 8) {
|
|
|
- *(uint32_t *)vp = __cpu_to_be32(tmp);
|
|
|
- vp += 4;
|
|
|
- len += 4;
|
|
|
- } else {
|
|
|
- printf("Sorry, I could not convert \"%s\"\n", cp);
|
|
|
- return 1;
|
|
|
- }
|
|
|
- while (*newval == ' ')
|
|
|
- newval++;
|
|
|
- }
|
|
|
- if (*newval != '>') {
|
|
|
- printf("Unexpected character '%c'\n", *newval);
|
|
|
- return 1;
|
|
|
- }
|
|
|
- } else if (*newval == '[') {
|
|
|
- /*
|
|
|
- * Byte stream. Convert the values.
|
|
|
- */
|
|
|
- len = 0;
|
|
|
- newval++;
|
|
|
- while ((*newval != ']') && (*newval != '\0')) {
|
|
|
- tmp = simple_strtoul(newval, &newval, 16);
|
|
|
- *vp++ = tmp & 0xFF;
|
|
|
- len++;
|
|
|
- while (*newval == ' ')
|
|
|
- newval++;
|
|
|
- }
|
|
|
- if (*newval != ']') {
|
|
|
- printf("Unexpected character '%c'\n", *newval);
|
|
|
+ len = 0;
|
|
|
+ newval++;
|
|
|
+ while ((*newval != '>') && (*newval != '\0')) {
|
|
|
+ cp = newval;
|
|
|
+ tmp = simple_strtoul(cp, &newval, 16);
|
|
|
+ if ((newval - cp) <= 2) {
|
|
|
+ *vp = tmp & 0xFF;
|
|
|
+ vp += 1;
|
|
|
+ len += 1;
|
|
|
+ } else if ((newval - cp) <= 4) {
|
|
|
+ *(uint16_t *)vp = __cpu_to_be16(tmp);
|
|
|
+ vp += 2;
|
|
|
+ len += 2;
|
|
|
+ } else if ((newval - cp) <= 8) {
|
|
|
+ *(uint32_t *)vp = __cpu_to_be32(tmp);
|
|
|
+ vp += 4;
|
|
|
+ len += 4;
|
|
|
+ } else {
|
|
|
+ printf("Sorry, I could not convert \"%s\"\n", cp);
|
|
|
return 1;
|
|
|
}
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * Assume it is a string. Copy it into our data area for
|
|
|
- * convenience (including the terminating '\0').
|
|
|
- */
|
|
|
- len = strlen(newval) + 1;
|
|
|
- strcpy(data, newval);
|
|
|
+ while (*newval == ' ')
|
|
|
+ newval++;
|
|
|
}
|
|
|
-
|
|
|
- ret = fdt_setprop(fdt, nodeoffset, prop, data, len);
|
|
|
- if (ret < 0) {
|
|
|
- printf ("libfdt %s\n", fdt_strerror(ret));
|
|
|
+ if (*newval != '>') {
|
|
|
+ printf("Unexpected character '%c'\n", *newval);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ } else if (*newval == '[') {
|
|
|
+ /*
|
|
|
+ * Byte stream. Convert the values.
|
|
|
+ */
|
|
|
+ len = 0;
|
|
|
+ newval++;
|
|
|
+ while ((*newval != ']') && (*newval != '\0')) {
|
|
|
+ tmp = simple_strtoul(newval, &newval, 16);
|
|
|
+ *vp++ = tmp & 0xFF;
|
|
|
+ len++;
|
|
|
+ while (*newval == ' ')
|
|
|
+ newval++;
|
|
|
+ }
|
|
|
+ if (*newval != ']') {
|
|
|
+ printf("Unexpected character '%c'\n", *newval);
|
|
|
return 1;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * Assume it is a string. Copy it into our data area for
|
|
|
+ * convenience (including the terminating '\0').
|
|
|
+ */
|
|
|
+ len = strlen(newval) + 1;
|
|
|
+ strcpy(data, newval);
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = fdt_setprop(fdt, nodeoffset, prop, data, len);
|
|
|
+ if (ret < 0) {
|
|
|
+ printf ("libfdt fdt_setprop(): %s\n", fdt_strerror(ret));
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
|
* Print (recursive) / List (single level)
|
|
|
********************************************************************/
|
|
|
- } else if ((op == 'p') || (op == 'l')) {
|
|
|
+ } else if ((argv[1][0] == 'p') || (argv[1][0] == 'l')) {
|
|
|
/*
|
|
|
* Recursively print (a portion of) the fdt.
|
|
|
*/
|
|
@@ -297,7 +324,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
/*
|
|
|
* list is an alias for print, but limited to 1 level
|
|
|
*/
|
|
|
- if (op == 'l') {
|
|
|
+ if (argv[1][0] == 'l') {
|
|
|
depth = 1;
|
|
|
}
|
|
|
|
|
@@ -311,18 +338,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
else
|
|
|
prop = NULL;
|
|
|
|
|
|
- if (strcmp(pathp, "/") == 0) {
|
|
|
- nodeoffset = 0;
|
|
|
- printf("/");
|
|
|
- } else {
|
|
|
- nodeoffset = fdt_path_offset (fdt, pathp);
|
|
|
- if (nodeoffset < 0) {
|
|
|
- /*
|
|
|
- * Not found or something else bad happened.
|
|
|
- */
|
|
|
- printf ("libfdt %s\n", fdt_strerror(nodeoffset));
|
|
|
- return 1;
|
|
|
- }
|
|
|
+ nodeoffset = findnodeoffset(pathp);
|
|
|
+ if (nodeoffset < 0) {
|
|
|
+ /*
|
|
|
+ * Not found or something else bad happened.
|
|
|
+ */
|
|
|
+ return 1;
|
|
|
}
|
|
|
/*
|
|
|
* The user passed in a property as well as node path. Print only
|
|
@@ -339,7 +360,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
printf("\n");
|
|
|
return 0;
|
|
|
} else {
|
|
|
- printf ("libfdt %s\n", fdt_strerror(len));
|
|
|
+ printf ("libfdt fdt_getprop(): %s\n", fdt_strerror(len));
|
|
|
return 1;
|
|
|
}
|
|
|
}
|
|
@@ -359,7 +380,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
level++;
|
|
|
offstack[level] = nodeoffset;
|
|
|
if (level >= MAX_LEVEL) {
|
|
|
- printf("Aaaiii <splat> nested too deep.\n");
|
|
|
+ printf("Aaaiii <splat> nested too deep. Aborting.\n");
|
|
|
return 1;
|
|
|
}
|
|
|
break;
|
|
@@ -374,7 +395,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
case FDT_PROP:
|
|
|
nodep = fdt_getprop (fdt, offstack[level], pathp, &len);
|
|
|
if (len < 0) {
|
|
|
- printf ("libfdt %s\n", fdt_strerror(len));
|
|
|
+ printf ("libfdt fdt_getprop(): %s\n", fdt_strerror(len));
|
|
|
return 1;
|
|
|
} else if (len == 0) {
|
|
|
/* the property has no value */
|
|
@@ -403,7 +424,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
/********************************************************************
|
|
|
* Remove a property/node
|
|
|
********************************************************************/
|
|
|
- } else if (op == 'r') {
|
|
|
+ } else if (argv[1][0] == 'r') {
|
|
|
int nodeoffset; /* node offset from libfdt */
|
|
|
int err;
|
|
|
|
|
@@ -411,17 +432,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
* Get the path. The root node is an oddball, the offset
|
|
|
* is zero and has no name.
|
|
|
*/
|
|
|
- if (strcmp(argv[2], "/") == 0) {
|
|
|
- nodeoffset = 0;
|
|
|
- } else {
|
|
|
- nodeoffset = fdt_path_offset (fdt, argv[2]);
|
|
|
- if (nodeoffset < 0) {
|
|
|
- /*
|
|
|
- * Not found or something else bad happened.
|
|
|
- */
|
|
|
- printf ("libfdt %s\n", fdt_strerror(nodeoffset));
|
|
|
- return 1;
|
|
|
- }
|
|
|
+ nodeoffset = findnodeoffset(argv[2]);
|
|
|
+ if (nodeoffset < 0) {
|
|
|
+ /*
|
|
|
+ * Not found or something else bad happened.
|
|
|
+ */
|
|
|
+ return 1;
|
|
|
}
|
|
|
/*
|
|
|
* Do the delete. A fourth parameter means delete a property,
|
|
@@ -430,13 +446,13 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
if (argc > 3) {
|
|
|
err = fdt_delprop(fdt, nodeoffset, argv[3]);
|
|
|
if (err < 0) {
|
|
|
- printf("fdt_delprop libfdt: %s\n", fdt_strerror(err));
|
|
|
+ printf("libfdt fdt_delprop(): %s\n", fdt_strerror(err));
|
|
|
return err;
|
|
|
}
|
|
|
} else {
|
|
|
err = fdt_del_node(fdt, nodeoffset);
|
|
|
if (err < 0) {
|
|
|
- printf("fdt_del_node libfdt: %s\n", fdt_strerror(err));
|
|
|
+ printf("libfdt fdt_del_node(): %s\n", fdt_strerror(err));
|
|
|
return err;
|
|
|
}
|
|
|
}
|
|
@@ -444,19 +460,19 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
|
/********************************************************************
|
|
|
* Create a chosen node
|
|
|
********************************************************************/
|
|
|
- } else if (op == 'c') {
|
|
|
+ } else if (argv[1][0] == 'c') {
|
|
|
fdt_chosen(fdt, 0, 0, 1);
|
|
|
|
|
|
/********************************************************************
|
|
|
* Create a u-boot-env node
|
|
|
********************************************************************/
|
|
|
- } else if (op == 'e') {
|
|
|
+ } else if (argv[1][0] == 'e') {
|
|
|
fdt_env(fdt);
|
|
|
|
|
|
/********************************************************************
|
|
|
* Create a bd_t node
|
|
|
********************************************************************/
|
|
|
- } else if (op == 'b') {
|
|
|
+ } else if (argv[1][0] == 'b') {
|
|
|
fdt_bd_t(fdt);
|
|
|
|
|
|
/********************************************************************
|
|
@@ -486,7 +502,7 @@ static int fdt_valid(void)
|
|
|
return 1; /* valid */
|
|
|
|
|
|
if (err < 0) {
|
|
|
- printf("libfdt: %s", fdt_strerror(err));
|
|
|
+ printf("libfdt fdt_check_header(): %s", fdt_strerror(err));
|
|
|
/*
|
|
|
* Be more informative on bad version.
|
|
|
*/
|
|
@@ -630,7 +646,6 @@ U_BOOT_CMD(
|
|
|
"fdt bd_t - Add/replace the \"/bd_t\" branch in the tree\n"
|
|
|
#endif
|
|
|
"Hints:\n"
|
|
|
- " * Set a larger length with the fdt addr command to add to the blob.\n"
|
|
|
" * If the property you are setting/printing has a '#' character,\n"
|
|
|
" you MUST escape it with a \\ character or quote it with \" or\n"
|
|
|
" it will be ignored as a comment.\n"
|