From 25114033ab21788810c48ba4df103b649da1223b Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Sat, 12 May 2007 09:47:25 -0400 Subject: [PATCH] FDT command improvements. Fix "fdt set" so that it will create a non-existing property. Add "fdt mknode" to create nodes. Signed-off-by: Gerald Van Baren --- common/cmd_fdt.c | 271 +++++++++++++++++++++++++---------------------- 1 file changed, 143 insertions(+), 128 deletions(-) diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index a119985942..8402ca7859 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -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 nested too deep.\n"); + printf("Aaaiii 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" -- 2.39.5