diff options
Diffstat (limited to 'cmd/fdt.c')
-rw-r--r-- | cmd/fdt.c | 98 |
1 files changed, 56 insertions, 42 deletions
@@ -77,7 +77,17 @@ static int fdt_value_env_set(const void *nodep, int len, sprintf(buf, "0x%08X", fdt32_to_cpu(*(fdt32_t *)nodep)); env_set(var, buf); - } else if (len%4 == 0 && len <= 20) { + } else if (len % 4 == 0 && index >= 0) { + /* Needed to print integer arrays. */ + const unsigned int *nodec = (const unsigned int *)nodep; + char buf[11]; + + if (index * 4 >= len) + return 1; + + sprintf(buf, "0x%08X", fdt32_to_cpu(*(nodec + index))); + env_set(var, buf); + } else if (len % 4 == 0 && len <= 20) { /* Needed to print things like sha1 hashes. */ char buf[41]; int i; @@ -446,15 +456,17 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } else { nodep = fdt_getprop( working_fdt, nodeoffset, prop, &len); - if (len == 0) { - /* no property value */ - env_set(var, ""); - return 0; - } else if (nodep && len > 0) { + if (nodep && len >= 0) { if (subcmd[0] == 'v') { - int index = 0; + int index = -1; int ret; + if (len == 0) { + /* no property value */ + env_set(var, ""); + return 0; + } + if (argc == 7) index = simple_strtoul(argv[6], NULL, 10); @@ -464,9 +476,10 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return ret; } else if (subcmd[0] == 'a') { /* Get address */ - char buf[11]; + char buf[19]; - sprintf(buf, "0x%p", nodep); + snprintf(buf, sizeof(buf), "0x%lx", + (ulong)map_to_sysmem(nodep)); env_set(var, buf); } else if (subcmd[0] == 's') { /* Get size */ @@ -545,16 +558,16 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc > 3) { err = fdt_delprop(working_fdt, nodeoffset, argv[3]); if (err < 0) { - printf("libfdt fdt_delprop(): %s\n", + printf("libfdt fdt_delprop(): %s\n", fdt_strerror(err)); - return err; + return CMD_RET_FAILURE; } } else { err = fdt_del_node(working_fdt, nodeoffset); if (err < 0) { - printf("libfdt fdt_del_node(): %s\n", + printf("libfdt fdt_del_node(): %s\n", fdt_strerror(err)); - return err; + return CMD_RET_FAILURE; } } @@ -595,7 +608,12 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) * Set boot cpu id */ } else if (strncmp(argv[1], "boo", 3) == 0) { - unsigned long tmp = hextoul(argv[2], NULL); + unsigned long tmp; + + if (argc != 3) + return CMD_RET_USAGE; + + tmp = hextoul(argv[2], NULL); fdt_set_boot_cpuid_phys(working_fdt, tmp); /* @@ -604,6 +622,10 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } else if (strncmp(argv[1], "me", 2) == 0) { uint64_t addr, size; int err; + + if (argc != 4) + return CMD_RET_USAGE; + addr = simple_strtoull(argv[2], NULL, 16); size = simple_strtoull(argv[3], NULL, 16); err = fdt_fixup_memory(working_fdt, addr, size); @@ -642,18 +664,18 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) err = fdt_add_mem_rsv(working_fdt, addr, size); if (err < 0) { - printf("libfdt fdt_add_mem_rsv(): %s\n", + printf("libfdt fdt_add_mem_rsv(): %s\n", fdt_strerror(err)); - return err; + return CMD_RET_FAILURE; } } else if (argv[2][0] == 'd') { unsigned long idx = hextoul(argv[3], NULL); int err = fdt_del_mem_rsv(working_fdt, idx); if (err < 0) { - printf("libfdt fdt_del_mem_rsv(): %s\n", + printf("libfdt fdt_del_mem_rsv(): %s\n", fdt_strerror(err)); - return err; + return CMD_RET_FAILURE; } } else { /* Unrecognized command */ @@ -878,41 +900,33 @@ static int fdt_parse_prop(char * const *newval, int count, char *data, int *len) static int is_printable_string(const void *data, int len) { const char *s = data; + const char *ss, *se; /* zero length is not */ if (len == 0) return 0; - /* must terminate with zero or '\n' */ - if (s[len - 1] != '\0' && s[len - 1] != '\n') + /* must terminate with zero */ + if (s[len - 1] != '\0') return 0; - /* printable or a null byte (concatenated strings) */ - while (((*s == '\0') || isprint(*s) || isspace(*s)) && (len > 0)) { - /* - * If we see a null, there are three possibilities: - * 1) If len == 1, it is the end of the string, printable - * 2) Next character also a null, not printable. - * 3) Next character not a null, continue to check. - */ - if (s[0] == '\0') { - if (len == 1) - return 1; - if (s[1] == '\0') - return 0; - } + se = s + len; + + while (s < se) { + ss = s; + while (s < se && *s && isprint((unsigned char)*s)) + s++; + + /* not zero, or not done yet */ + if (*s != '\0' || s == ss) + return 0; + s++; - len--; } - /* Not the null termination, or not done yet: not printable */ - if (*s != '\0' || (len != 0)) - return 0; - return 1; } - /* * Print the property in the best format, a heuristic guess. Print as * a string, concatenated strings, a byte, word, double word, or (if all @@ -1135,8 +1149,8 @@ static char fdt_help_text[] = " <start>/<size> - initrd start addr/size\n" #if defined(CONFIG_FIT_SIGNATURE) "fdt checksign [<addr>] - check FIT signature\n" - " <start> - addr of key blob\n" - " default gd->fdt_blob\n" + " <addr> - address of key blob\n" + " default gd->fdt_blob\n" #endif "NOTE: Dereference aliases by omitting the leading '/', " "e.g. fdt print ethernet0."; |