From 4f806f31fc29b30f06bd13abe44a1d3649d480e5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 22 Feb 2023 12:17:03 -0700 Subject: bootflow: Rename bootflow_flags_t These flags actually relate to the iterator, not the bootflow struct itself. Rename them. Signed-off-by: Simon Glass --- cmd/bootflow.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/bootflow.c b/cmd/bootflow.c index 3548bbb6830..42f6e14a437 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -135,13 +135,13 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc, flags = 0; if (list) - flags |= BOOTFLOWF_SHOW; + flags |= BOOTFLOWIF_SHOW; if (all) - flags |= BOOTFLOWF_ALL; + flags |= BOOTFLOWIF_ALL; if (no_global) - flags |= BOOTFLOWF_SKIP_GLOBAL; + flags |= BOOTFLOWIF_SKIP_GLOBAL; if (!no_hunter) - flags |= BOOTFLOWF_HUNT; + flags |= BOOTFLOWIF_HUNT; /* * If we have a device, just scan for bootflows attached to that device -- cgit v1.3.1 From 56915fa4ccc7d995f832723b62ed403bd9a4cf44 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:14 +0100 Subject: cmd: fdt: Import is_printable_string() from DTC to fix u32 misprint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Import is_printable_string() implementation from DTC 1.7.0 as of DTC commit 039a994 ("Bump version to v1.7.0") . This fixes a print of u32 property which so far used to be printed as string by U-Boot fdt print command. We might see the case where the parsed property value, in this case it is a 32-bit integer, identified as a printable string or a null byte (concatenated strings) because of its last character happens to be: 0x00 (null character), 0xB (vertical tab character) or 0x10 (line feed character) In this situation, if the string is identified as printable string, it will be displayed as character instead of hex value When the isprint() condition is true, there are two possibilities: 1) The character is ASCII character (except the first 32) 2) The character is extended ASCII character For example, NG property in device tree: clock-frequency = <16640000>; by default, would be displayed as clock-frequency = "", "ýè"; and with this patch applied, would be displayed as clock-frequency = <0x00fde800>; Full investigation was done by Nam and Hai, patch reworked by Marek to use common code from DTC. Signed-off-by: Hai Pham Signed-off-by: Nam Nguyen Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index 1972490bdc2..bf2415661e2 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -878,41 +878,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 -- cgit v1.3.1 From 45d20f55a178bd00f631460909881176fb12b37d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:15 +0100 Subject: cmd: fdt: Fix handling of empty properties for fdt get addr and fdt get size It is perfectly valid to request an address or size of FDT property without value, the only special case if requesting of the value of FDT property without value. Invert the test such, that properties without value still set the variable from 'fdt get addr/size' to address of the property or size of the property, where the later is 0. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index bf2415661e2..56b3585c3ac 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -446,15 +446,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 ret; + if (len == 0) { + /* no property value */ + env_set(var, ""); + return 0; + } + if (argc == 7) index = simple_strtoul(argv[6], NULL, 10); -- cgit v1.3.1 From 9597637f93632d4399f07cd0570a544edd55596a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:16 +0100 Subject: cmd: fdt: Fix fdt rm behavior on non-existent property and error message space In case an FDT contains a node '/test-node@1234' , with no property called 'noprop' in that node, the following command triggers a print of help message for 'fdt' command instead of erroring out: => fdt rm /test-node@1234 noprop This is because the subcommand errornously returns 'err' instead of CMD_RET_FAILURE, fix it. Furthermore, align the number of spaces past fdt_delprop() in error message with the rest of the code. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index 56b3585c3ac..644b58ac4d7 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -547,16 +547,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; } } -- cgit v1.3.1 From 778c7ab5a7905dd984ce1fc743962c16b5bf3d82 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:17 +0100 Subject: cmd: fdt: Fix fdt rsvmem behavior on non-existent index and error message space In case 'fdt rsvmem delete index' is passed a non-existent index, one which does not exist in 'fdt rsvmem print', then the following command triggers a print of help message for 'fdt' command instead of erroring out: => fdt rsvmem delete 1234 This is because the subcommand errornously returns 'err' instead of CMD_RET_FAILURE, fix it. Furthermore, align the number of spaces past fdt_del_mem_rsv() and fdt_add_mem_rsv() in error message with the rest of the code. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index 644b58ac4d7..29d748891d0 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -644,18 +644,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 */ -- cgit v1.3.1 From 9d019f5106cc677fefd8ab6ccfc5ba0ed9e0b738 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:18 +0100 Subject: cmd: fdt: Check argc before accessing argv in fdt bootcpu On case 'fdt bootcpu' is invoked without parameters, argv[2] is not valid and this command would SEGFAULT in sandbox environment. Add missing argc test to avoid the crash and rather print usage help message. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index 29d748891d0..734c9b36a07 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -597,7 +597,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); /* -- cgit v1.3.1 From e023b8601ee72eb04098ffa9bd0d113ce98dba38 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:19 +0100 Subject: cmd: fdt: Check argc before accessing argv in fdt memory On case 'fdt memory' is invoked without parameters, argv[2]/argv[3] is not valid and this command would SEGFAULT in sandbox environment. Add missing argc test to avoid the crash and rather print usage help message. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index 734c9b36a07..f257bee8643 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -611,6 +611,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); -- cgit v1.3.1 From 3300a6027772105ed4f4dd34001bd532ee21de8c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:20 +0100 Subject: cmd: fdt: Align checksign parameter names in help text The help text references 'addr' as an optional key start address, but the explanation references the same as 'start', make sure they both read as 'addr'. Also update the abbreviated 'addr' in the explanation to 'address'. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index f257bee8643..279dad9fe11 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -1138,8 +1138,8 @@ static char fdt_help_text[] = " / - initrd start addr/size\n" #if defined(CONFIG_FIT_SIGNATURE) "fdt checksign [] - check FIT signature\n" - " - addr of key blob\n" - " default gd->fdt_blob\n" + " - address of key blob\n" + " default gd->fdt_blob\n" #endif "NOTE: Dereference aliases by omitting the leading '/', " "e.g. fdt print ethernet0."; -- cgit v1.3.1 From 22cbd654d33f60b7d7941c4ba2484bcc610f4e50 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:21 +0100 Subject: cmd: fdt: Handle 64bit pointers in fdt get addr The command assumed 32bit pointers so far, with 64bit pointer the command would overwrite a piece of stack. Fix it by extending the array size to cater for 64bit pointer, and use snprintf() to avoid writing past the end of the array ever again. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index 279dad9fe11..bc19303159d 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -466,9 +466,9 @@ 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%p", nodep); env_set(var, buf); } else if (subcmd[0] == 's') { /* Get size */ -- cgit v1.3.1 From c2a5d1078027b6c0480eda45bd4d2eae80ceb67e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:22 +0100 Subject: cmd: fdt: Map address returned from fdt get addr to sysmem The address returned from 'fdt get addr' command must be mapped into sysmem, as this is a working FDT. Access to this address without mapping it would lead to crash e.g. in sandbox. The following command triggers the crash: " ./u-boot -Dc 'fdt addr $fdtcontroladdr ; fdt get addr var / compatible ; md $var' " Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index bc19303159d..f2576ab4b38 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -468,7 +468,8 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) /* Get address */ char buf[19]; - snprintf(buf, sizeof(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 */ -- cgit v1.3.1 From 95d85d0da4ae13946325c39a0dffefcbeaa07a38 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 2 Mar 2023 04:08:23 +0100 Subject: cmd: fdt: Add support for integer arrays in fdt get value with index Currently any integer array value is set as long up-to-40 character hexadecimal string into environment variable when extracted from an FDT using 'fdt get value path prop index', because the support for handling integer arrays is not implemented, and fdt_value_env_set() code falls back into the hash handling behavior instead. Implement this support simply by checking whether user supplied any index. If index is set and the property length is multiple of four, then this is an integer array, and the code would extract value at specified index. There is a subtle change where default index is set to -1 instead of 0. This is OK, since the only place which checks for index to be less or equal zero is the string array handling code in fdt_value_env_set() and that code would work perfectly well with index -1 too. Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- cmd/fdt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/fdt.c b/cmd/fdt.c index f2576ab4b38..f38fe909c3e 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; @@ -448,7 +458,7 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) working_fdt, nodeoffset, prop, &len); if (nodep && len >= 0) { if (subcmd[0] == 'v') { - int index = 0; + int index = -1; int ret; if (len == 0) { -- cgit v1.3.1