FDT command improvements.
authorGerald Van Baren <vanbaren@cideas.com>
Sat, 12 May 2007 13:47:25 +0000 (09:47 -0400)
committerGerald Van Baren <vanbaren@cideas.com>
Fri, 10 Aug 2007 23:21:36 +0000 (19:21 -0400)
Fix "fdt set" so that it will create a non-existing property.
Add "fdt mknode" to create nodes.

Signed-off-by: Gerald Van Baren <vanbaren@cideas.com>
common/cmd_fdt.c

index a1199859425038ceab445f18be049d4f6b5414b4..8402ca78590d7ed6cd4e09a4b062f80208c0b29a 100644 (file)
@@ -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"