X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cmd%2Ffdt.c;h=99b1b5b3fcb94c44a8517d531c3ee47e019081b9;hb=HEAD;hp=95dd673b957e45dca344367fe2f3c1d682f28418;hpb=035ebf85b09cf11c820ae9eec414097420741abd;p=oweals%2Fu-boot.git diff --git a/cmd/fdt.c b/cmd/fdt.c index 95dd673b95..99b1b5b3fc 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -1,28 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2007 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com * Based on code written by: * Pantelis Antoniou and * Matthew McClintock - * - * SPDX-License-Identifier: GPL-2.0+ */ #include #include +#include +#include #include #include #include -#include +#include #include #include #include #define MAX_LEVEL 32 /* how deeply nested we will go */ #define SCRATCHPAD 1024 /* bytes of scratchpad memory */ -#ifndef CONFIG_CMD_FDT_MAX_DUMP -#define CONFIG_CMD_FDT_MAX_DUMP 64 -#endif +#define CMD_FDT_MAX_DUMP 64 /* * Global data (for the gd->bd) @@ -45,21 +44,21 @@ void set_working_fdt_addr(ulong addr) buf = map_sysmem(addr, 0); working_fdt = buf; - setenv_hex("fdtaddr", addr); + env_set_hex("fdtaddr", addr); } /* * Get a value from the fdt and format it to be set in the environment */ -static int fdt_value_setenv(const void *nodep, int len, const char *var) +static int fdt_value_env_set(const void *nodep, int len, const char *var) { if (is_printable_string(nodep, len)) - setenv(var, (void *)nodep); + env_set(var, (void *)nodep); else if (len == 4) { char buf[11]; sprintf(buf, "0x%08X", fdt32_to_cpu(*(fdt32_t *)nodep)); - setenv(var, buf); + env_set(var, buf); } else if (len%4 == 0 && len <= 20) { /* Needed to print things like sha1 hashes. */ char buf[41]; @@ -68,7 +67,7 @@ static int fdt_value_setenv(const void *nodep, int len, const char *var) for (i = 0; i < len; i += sizeof(unsigned int)) sprintf(buf + (i * 2), "%08x", *(unsigned int *)(nodep + i)); - setenv(var, buf); + env_set(var, buf); } else { printf("error: unprintable value\n"); return 1; @@ -76,10 +75,44 @@ static int fdt_value_setenv(const void *nodep, int len, const char *var) return 0; } +static const char * const fdt_member_table[] = { + "magic", + "totalsize", + "off_dt_struct", + "off_dt_strings", + "off_mem_rsvmap", + "version", + "last_comp_version", + "boot_cpuid_phys", + "size_dt_strings", + "size_dt_struct", +}; + +static int fdt_get_header_value(int argc, char *const argv[]) +{ + fdt32_t *fdtp = (fdt32_t *)working_fdt; + ulong val; + int i; + + if (argv[2][0] != 'g') + return CMD_RET_FAILURE; + + for (i = 0; i < ARRAY_SIZE(fdt_member_table); i++) { + if (strcmp(fdt_member_table[i], argv[4])) + continue; + + val = fdt32_to_cpu(fdtp[i]); + env_set_hex(argv[3], val); + return CMD_RET_SUCCESS; + } + + return CMD_RET_FAILURE; +} + /* * Flattened Device Tree command, see the help for parameter definitions. */ -static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { if (argc < 2) return CMD_RET_USAGE; @@ -113,7 +146,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; printf("The address of the fdt is %#08lx\n", control ? (ulong)map_to_sysmem(blob) : - getenv_hex("fdtaddr", 0)); + env_get_hex("fdtaddr", 0)); return 0; } @@ -205,7 +238,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) fdt_strerror(err)); return 1; } - working_fdt = newaddr; + set_working_fdt_addr((ulong)newaddr); #ifdef CONFIG_OF_SYSTEM_SETUP /* Call the board-specific fixup routine */ } else if (strncmp(argv[1], "sys", 3) == 0) { @@ -254,11 +287,12 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* * Set the value of a property in the working_fdt. */ - } else if (argv[1][0] == 's') { + } else if (strncmp(argv[1], "se", 2) == 0) { char *pathp; /* path */ char *prop; /* property */ int nodeoffset; /* node offset from libfdt */ - static char data[SCRATCHPAD]; /* storage for the property */ + static char data[SCRATCHPAD] __aligned(4);/* property storage */ + const void *ptmp; int len; /* new length of the property */ int ret; /* return value */ @@ -270,13 +304,6 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) pathp = argv[2]; prop = argv[3]; - if (argc == 4) { - len = 0; - } else { - ret = fdt_parse_prop(&argv[4], argc - 4, data, &len); - if (ret != 0) - return ret; - } nodeoffset = fdt_path_offset (working_fdt, pathp); if (nodeoffset < 0) { @@ -288,6 +315,23 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } + if (argc == 4) { + len = 0; + } else { + ptmp = fdt_getprop(working_fdt, nodeoffset, prop, &len); + if (len > SCRATCHPAD) { + printf("prop (%d) doesn't fit in scratchpad!\n", + len); + return 1; + } + if (ptmp != NULL) + memcpy(data, ptmp, len); + + ret = fdt_parse_prop(&argv[4], argc - 4, data, &len); + if (ret != 0) + return ret; + } + ret = fdt_setprop(working_fdt, nodeoffset, prop, data, len); if (ret < 0) { printf ("libfdt fdt_setprop(): %s\n", fdt_strerror(ret)); @@ -347,10 +391,12 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (curDepth == startDepth + 1) curIndex++; if (subcmd[0] == 'n' && curIndex == reqIndex) { - const char *nodeName = fdt_get_name( - working_fdt, nextNodeOffset, NULL); + const char *node_name; - setenv(var, (char *)nodeName); + node_name = fdt_get_name(working_fdt, + nextNodeOffset, + NULL); + env_set(var, node_name); return 0; } nextNodeOffset = fdt_next_node( @@ -360,7 +406,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (subcmd[0] == 's') { /* get the num nodes at this level */ - setenv_ulong(var, curIndex + 1); + env_set_ulong(var, curIndex + 1); } else { /* node index not found */ printf("libfdt node not found\n"); @@ -371,13 +417,14 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) working_fdt, nodeoffset, prop, &len); if (len == 0) { /* no property value */ - setenv(var, ""); + env_set(var, ""); return 0; - } else if (len > 0) { + } else if (nodep && len > 0) { if (subcmd[0] == 'v') { int ret; - ret = fdt_value_setenv(nodep, len, var); + ret = fdt_value_env_set(nodep, len, + var); if (ret != 0) return ret; } else if (subcmd[0] == 'a') { @@ -385,13 +432,13 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char buf[11]; sprintf(buf, "0x%p", nodep); - setenv(var, buf); + env_set(var, buf); } else if (subcmd[0] == 's') { /* Get size */ char buf[11]; sprintf(buf, "0x%08X", len); - setenv(var, buf); + env_set(var, buf); } else return CMD_RET_USAGE; return 0; @@ -480,6 +527,9 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * Display header info */ } else if (argv[1][0] == 'h') { + if (argc == 5) + return fdt_get_header_value(argc, argv); + u32 version = fdt_version(working_fdt); printf("magic:\t\t\t0x%x\n", fdt_magic(working_fdt)); printf("totalsize:\t\t0x%x (%d)\n", fdt_totalsize(working_fdt), @@ -585,6 +635,9 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) fdt_strerror(err)); return CMD_RET_FAILURE; } +#ifdef CONFIG_SOC_KEYSTONE + ft_board_setup_ex(working_fdt, gd->bd); +#endif } #endif /* Create a chosen node */ @@ -655,11 +708,10 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (!fdt_valid(&blob)) return CMD_RET_FAILURE; - ret = fdt_overlay_apply(working_fdt, blob); - if (ret) { - printf("fdt_overlay_apply(): %s\n", fdt_strerror(ret)); + /* apply method prints messages on error */ + ret = fdt_overlay_apply_verbose(working_fdt, blob); + if (ret) return CMD_RET_FAILURE; - } } #endif /* resize the fdt */ @@ -768,7 +820,11 @@ static int fdt_parse_prop(char * const *newval, int count, char *data, int *len) cp = newp; tmp = simple_strtoul(cp, &newp, 0); - *(fdt32_t *)data = cpu_to_fdt32(tmp); + if (*cp != '?') + *(fdt32_t *)data = cpu_to_fdt32(tmp); + else + newp++; + data += 4; *len += 4; @@ -901,7 +957,7 @@ static void print_data(const void *data, int len) } if ((len %4) == 0) { - if (len > CONFIG_CMD_FDT_MAX_DUMP) + if (len > CMD_FDT_MAX_DUMP) printf("* 0x%p [0x%08x]", data, len); else { const __be32 *p; @@ -913,7 +969,7 @@ static void print_data(const void *data, int len) printf(">"); } } else { /* anything else... hexdump */ - if (len > CONFIG_CMD_FDT_MAX_DUMP) + if (len > CMD_FDT_MAX_DUMP) printf("* 0x%p [0x%08x]", data, len); else { const u8 *s; @@ -964,7 +1020,7 @@ static int fdt_print(const char *pathp, char *prop, int depth) /* no property value */ printf("%s %s\n", pathp, prop); return 0; - } else if (len > 0) { + } else if (nodep && len > 0) { printf("%s = ", prop); print_data (nodep, len); printf("\n"); @@ -1073,7 +1129,8 @@ static char fdt_help_text[] = "fdt set [] - Set [to ]\n" "fdt mknode - Create a new node after \n" "fdt rm [] - Delete the node or \n" - "fdt header - Display header info\n" + "fdt header [get ] - Display header info\n" + " get - get header member and store it in \n" "fdt bootcpu - Set boot cpuid\n" "fdt memory - Add/Update memory node\n" "fdt rsvmem print - Show current mem reserves\n"