Add an option show_of_embedded used in SPL to dump the used device tree. Signed-off-by: Patrick Delaunay <patrick.delau...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot