[U-Boot] [PATCH v2 3/8] sandbox: add option show_of_embedded for spl test
Patrick Delaunay
patrick.delaunay at st.com
Mon May 20 13:00:02 UTC 2019
Add an option show_of_embedded used in SPL to dump the used device tree.
Signed-off-by: Patrick Delaunay <patrick.delaunay at st.com>
---
Changes in v2:
- add new option for spl test: show embedded dtb
arch/sandbox/cpu/spl.c | 188 +++++++++++++++++++++++++++++++++++++++
arch/sandbox/cpu/start.c | 9 ++
arch/sandbox/include/asm/state.h | 1 +
3 files changed, 198 insertions(+)
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 2ca4cd6..d3d9b08 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -46,6 +46,190 @@ static int spl_board_load_image(struct spl_image_info *spl_image,
}
SPL_LOAD_IMAGE_METHOD("sandbox", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
+#ifdef CONFIG_OF_EMBED
+/****************************************************************************/
+/* the next functions mainly copyied from cmd fdt for SPL sandbox test */
+
+#include <linux/ctype.h>
+
+#define CMD_FDT_MAX_DUMP 64
+#define MAX_LEVEL 32 /* how deeply nested we will go */
+
+/*
+ * Heuristic to guess if this is a string or concatenated strings.
+ */
+
+static int is_printable_string(const void *data, int len)
+{
+ const char *s = data;
+
+ /* zero length is not */
+ if (len == 0)
+ return 0;
+
+ /* must terminate with zero or '\n' */
+ if (s[len - 1] != '\0' && s[len - 1] != '\n')
+ 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;
+ }
+ 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
+ * else fails) it is printed as a stream of bytes.
+ */
+static void print_data(const void *data, int len)
+{
+ int j;
+
+ /* no data, don't print */
+ if (len == 0)
+ return;
+
+ /*
+ * It is a string, but it may have multiple strings (embedded '\0's).
+ */
+ if (is_printable_string(data, len)) {
+ puts("\"");
+ j = 0;
+ while (j < len) {
+ if (j > 0)
+ puts("\", \"");
+ puts(data);
+ j += strlen(data) + 1;
+ data += strlen(data) + 1;
+ }
+ puts("\"");
+ return;
+ }
+
+ if ((len % 4) == 0) {
+ if (len > CMD_FDT_MAX_DUMP) {
+ printf("* 0x%p [0x%08x]", data, len);
+ } else {
+ const __be32 *p;
+
+ printf("<");
+ for (j = 0, p = data; j < len / 4; j++)
+ printf("0x%08x%s", fdt32_to_cpu(p[j]),
+ j < (len / 4 - 1) ? " " : "");
+ printf(">");
+ }
+ } else { /* anything else... hexdump */
+ if (len > CMD_FDT_MAX_DUMP) {
+ printf("* 0x%p [0x%08x]", data, len);
+ } else {
+ const u8 *s;
+
+ printf("[");
+ for (j = 0, s = data; j < len; j++)
+ printf("%02x%s", s[j], j < len - 1 ? " " : "");
+ printf("]");
+ }
+ }
+}
+
+/*
+ * Recursively print the working_fdt.
+ */
+static int fdt_print(const struct fdt_header *working_fdt)
+{
+ static char tabs[MAX_LEVEL + 1] =
+ "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
+ "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+ const void *nodep; /* property node pointer */
+ int nodeoffset = 0; /* node offset from libfdt */
+ int nextoffset; /* next node offset from libfdt */
+ u32 tag; /* tag */
+ int len; /* length of the property */
+ int level = 0; /* keep track of nesting level */
+ const struct fdt_property *fdt_prop;
+ const char *pathp;
+
+ /* print the node and all subnodes. */
+ while (level >= 0) {
+ tag = fdt_next_tag(working_fdt, nodeoffset, &nextoffset);
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ pathp = fdt_get_name(working_fdt, nodeoffset, NULL);
+ if (!pathp)
+ pathp = "/* NULL pointer error */";
+ if (*pathp == '\0')
+ pathp = "/"; /* root is nameless */
+ printf("%s%s {\n",
+ &tabs[MAX_LEVEL - level], pathp);
+ level++;
+ break;
+ case FDT_END_NODE:
+ level--;
+ printf("%s};\n", &tabs[MAX_LEVEL - level]);
+ if (level == 0)
+ level = -1; /* exit the loop */
+ break;
+ case FDT_PROP:
+ fdt_prop = fdt_offset_ptr(working_fdt, nodeoffset,
+ sizeof(*fdt_prop));
+ pathp = fdt_string(working_fdt,
+ fdt32_to_cpu(fdt_prop->nameoff));
+ len = fdt32_to_cpu(fdt_prop->len);
+ nodep = fdt_prop->data;
+ if (len < 0) {
+ printf("libfdt fdt_getprop(): %s\n",
+ fdt_strerror(len));
+ return 1;
+ } else if (len == 0) {
+ /* the property has no value */
+ printf("%s%s;\n",
+ &tabs[MAX_LEVEL - level],
+ pathp);
+ } else {
+ printf("%s%s = ",
+ &tabs[MAX_LEVEL - level],
+ pathp);
+ print_data(nodep, len);
+ printf(";\n");
+ }
+ break;
+ case FDT_NOP:
+ printf("%s/* NOP */\n", &tabs[MAX_LEVEL - level]);
+ break;
+ case FDT_END:
+ return 1;
+ default:
+ return 1;
+ }
+ nodeoffset = nextoffset;
+ }
+
+ return 0;
+}
+
+/***************************************************************************/
+#endif
+
void spl_board_init(void)
{
struct sandbox_state *state = state_get_current();
@@ -63,6 +247,10 @@ void spl_board_init(void)
uclass_next_device(&dev))
;
}
+#ifdef CONFIG_OF_EMBED
+ if (state->show_of_embedded)
+ fdt_print(gd->fdt_blob);
+#endif
}
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 82828f0..8116e3c 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -293,6 +293,15 @@ static int sandbox_cmdline_cb_show_of_platdata(struct sandbox_state *state,
}
SANDBOX_CMDLINE_OPT(show_of_platdata, 0, "Show of-platdata in SPL");
+static int sandbox_cmdline_cb_show_of_embedded(struct sandbox_state *state,
+ const char *arg)
+{
+ state->show_of_embedded = true;
+
+ return 0;
+}
+SANDBOX_CMDLINE_OPT(show_of_embedded, 0, "Show of-embedded in SPL");
+
int board_run_command(const char *cmdline)
{
printf("## Commands are disabled. Please enable CONFIG_CMDLINE.\n");
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 2d773d3..c8142c8 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -90,6 +90,7 @@ struct sandbox_state {
bool show_test_output; /* Don't suppress stdout in tests */
int default_log_level; /* Default log level for sandbox */
bool show_of_platdata; /* Show of-platdata in SPL */
+ bool show_of_embedded; /* Show of-embedded in SPL */
bool ram_buf_read; /* true if we read the RAM buffer */
/* Pointer to information for each SPI bus/cs */
--
2.7.4
More information about the U-Boot
mailing list