aboutsummaryrefslogtreecommitdiff
path: root/cmd/fdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/fdt.c')
-rw-r--r--cmd/fdt.c98
1 files changed, 56 insertions, 42 deletions
diff --git a/cmd/fdt.c b/cmd/fdt.c
index 1972490bdc..f38fe909c3 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -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.";