video: Add commands to list and change fonts
[platform/kernel/u-boot.git] / cmd / fdt.c
index f1e2fc2..4b2dcfe 100644 (file)
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -40,6 +40,7 @@ void set_working_fdt_addr(ulong addr)
 {
        void *buf;
 
+       printf("Working FDT set to %lx\n", addr);
        buf = map_sysmem(addr, 0);
        working_fdt = buf;
        env_set_hex("fdtaddr", addr);
@@ -48,11 +49,27 @@ void set_working_fdt_addr(ulong addr)
 /*
  * Get a value from the fdt and format it to be set in the environment
  */
-static int fdt_value_env_set(const void *nodep, int len, const char *var)
+static int fdt_value_env_set(const void *nodep, int len,
+                            const char *var, int index)
 {
-       if (is_printable_string(nodep, len))
-               env_set(var, (void *)nodep);
-       else if (len == 4) {
+       if (is_printable_string(nodep, len)) {
+               const char *nodec = (const char *)nodep;
+               int i;
+
+               /*
+                * Iterate over all members in stringlist and find the one at
+                * offset $index. If no such index exists, indicate failure.
+                */
+               for (i = 0; i < len; i += strlen(nodec) + 1) {
+                       if (index-- > 0)
+                               continue;
+
+                       env_set(var, nodec + i);
+                       return 0;
+               }
+
+               return 1;
+       } else if (len == 4) {
                char buf[11];
 
                sprintf(buf, "0x%08X", fdt32_to_cpu(*(fdt32_t *)nodep));
@@ -115,26 +132,34 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
        if (argc < 2)
                return CMD_RET_USAGE;
 
-       /*
-        * Set the address of the fdt
-        */
+       /* fdt addr: Set the address of the fdt */
        if (strncmp(argv[1], "ad", 2) == 0) {
                unsigned long addr;
                int control = 0;
+               int quiet = 0;
                struct fdt_header *blob;
-               /*
-                * Set the address [and length] of the fdt.
-                */
+
+               /* Set the address [and length] of the fdt */
                argc -= 2;
                argv += 2;
-/* Temporary #ifdef - some archs don't have fdt_blob yet */
-#ifdef CONFIG_OF_CONTROL
-               if (argc && !strcmp(*argv, "-c")) {
-                       control = 1;
+               while (argc > 0 && **argv == '-') {
+                       char *arg = *argv;
+
+                       while (*++arg) {
+                               switch (*arg) {
+                               case 'c':
+                                       control = 1;
+                                       break;
+                               case 'q':
+                                       quiet = 1;
+                                       break;
+                               default:
+                                       return CMD_RET_USAGE;
+                               }
+                       }
                        argc--;
                        argv++;
                }
-#endif
                if (argc == 0) {
                        if (control)
                                blob = (struct fdt_header *)gd->fdt_blob;
@@ -142,15 +167,17 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                                blob = working_fdt;
                        if (!blob || !fdt_valid(&blob))
                                return 1;
-                       printf("The address of the fdt is %#08lx\n",
+                       printf("%s fdt: %08lx\n",
+                              control ? "Control" : "Working",
                               control ? (ulong)map_to_sysmem(blob) :
-                                       env_get_hex("fdtaddr", 0));
+                              env_get_hex("fdtaddr", 0));
                        return 0;
                }
 
-               addr = simple_strtoul(argv[0], NULL, 16);
+               addr = hextoul(argv[0], NULL);
                blob = map_sysmem(addr, 0);
-               if (!fdt_valid(&blob))
+               if ((quiet && fdt_check_header(blob)) ||
+                   (!quiet && !fdt_valid(&blob)))
                        return 1;
                if (control)
                        gd->fdt_blob = blob;
@@ -160,22 +187,19 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                if (argc >= 2) {
                        int  len;
                        int  err;
-                       /*
-                        * Optional new length
-                        */
-                       len = simple_strtoul(argv[1], NULL, 16);
+
+                       /* Optional new length */
+                       len = hextoul(argv[1], NULL);
                        if (len < fdt_totalsize(blob)) {
-                               printf ("New length %d < existing length %d, "
-                                       "ignoring.\n",
-                                       len, fdt_totalsize(blob));
+                               if (!quiet)
+                                       printf("New length %d < existing length %d, ignoring\n",
+                                              len, fdt_totalsize(blob));
                        } else {
-                               /*
-                                * Open in place with a new length.
-                                */
+                               /* Open in place with a new length */
                                err = fdt_open_into(blob, blob, len);
-                               if (err != 0) {
-                                       printf ("libfdt fdt_open_into(): %s\n",
-                                               fdt_strerror(err));
+                               if (!quiet && err != 0) {
+                                       printf("libfdt fdt_open_into(): %s\n",
+                                              fdt_strerror(err));
                                }
                        }
                }
@@ -184,10 +208,9 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
        }
 
        if (!working_fdt) {
-               puts(
-                       "No FDT memory address configured. Please configure\n"
-                       "the FDT address via \"fdt addr <address>\" command.\n"
-                       "Aborting!\n");
+               puts("No FDT memory address configured. Please configure\n"
+                    "the FDT address via \"fdt addr <address>\" command.\n"
+                    "Aborting!\n");
                return CMD_RET_FAILURE;
        }
 
@@ -205,11 +228,11 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                /*
                 * Set the address and length of the fdt.
                 */
-               working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
+               working_fdt = (struct fdt_header *)hextoul(argv[2], NULL);
                if (!fdt_valid(&working_fdt))
                        return 1;
 
-               newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16);
+               newaddr = (struct fdt_header *)hextoul(argv[3], NULL);
 
                /*
                 * If the user specifies a length, use that.  Otherwise use the
@@ -218,7 +241,7 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                if (argc <= 4) {
                        len = fdt_totalsize(working_fdt);
                } else {
-                       len = simple_strtoul(argv[4], NULL, 16);
+                       len = hextoul(argv[4], NULL);
                        if (len < fdt_totalsize(working_fdt)) {
                                printf ("New length 0x%X < existing length "
                                        "0x%X, aborting.\n",
@@ -374,21 +397,22 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                }
 
                if (subcmd[0] == 'n' || (subcmd[0] == 's' && argc == 5)) {
-                       int reqIndex = -1;
+                       int req_index = -1;
                        int startDepth = fdt_node_depth(
                                working_fdt, nodeoffset);
                        int curDepth = startDepth;
-                       int curIndex = -1;
+                       int cur_index = -1;
                        int nextNodeOffset = fdt_next_node(
                                working_fdt, nodeoffset, &curDepth);
 
                        if (subcmd[0] == 'n')
-                               reqIndex = simple_strtoul(argv[5], NULL, 16);
+                               req_index = hextoul(argv[5], NULL);
 
                        while (curDepth > startDepth) {
                                if (curDepth == startDepth + 1)
-                                       curIndex++;
-                               if (subcmd[0] == 'n' && curIndex == reqIndex) {
+                                       cur_index++;
+                               if (subcmd[0] == 'n' &&
+                                   cur_index == req_index) {
                                        const char *node_name;
 
                                        node_name = fdt_get_name(working_fdt,
@@ -404,7 +428,7 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                        }
                        if (subcmd[0] == 's') {
                                /* get the num nodes at this level */
-                               env_set_ulong(var, curIndex + 1);
+                               env_set_ulong(var, cur_index + 1);
                        } else {
                                /* node index not found */
                                printf("libfdt node not found\n");
@@ -419,10 +443,14 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                                return 0;
                        } else if (nodep && len > 0) {
                                if (subcmd[0] == 'v') {
+                                       int index = 0;
                                        int ret;
 
+                                       if (argc == 7)
+                                               index = simple_strtoul(argv[6], NULL, 10);
+
                                        ret = fdt_value_env_set(nodep, len,
-                                                               var);
+                                                               var, index);
                                        if (ret != 0)
                                                return ret;
                                } else if (subcmd[0] == 'a') {
@@ -558,7 +586,7 @@ 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 = simple_strtoul(argv[2], NULL, 16);
+               unsigned long tmp = hextoul(argv[2], NULL);
                fdt_set_boot_cpuid_phys(working_fdt, tmp);
 
        /*
@@ -610,7 +638,7 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                                return err;
                        }
                } else if (argv[2][0] == 'd') {
-                       unsigned long idx = simple_strtoul(argv[3], NULL, 16);
+                       unsigned long idx = hextoul(argv[3], NULL);
                        int err = fdt_del_mem_rsv(working_fdt, idx);
 
                        if (err < 0) {
@@ -633,7 +661,7 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                               fdt_strerror(err));
                        return CMD_RET_FAILURE;
                }
-#ifdef CONFIG_SOC_KEYSTONE
+#ifdef CONFIG_ARCH_KEYSTONE
                ft_board_setup_ex(working_fdt, gd->bd);
 #endif
        }
@@ -646,8 +674,8 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                        return CMD_RET_USAGE;
 
                if (argc == 4) {
-                       initrd_start = simple_strtoul(argv[2], NULL, 16);
-                       initrd_end = simple_strtoul(argv[3], NULL, 16);
+                       initrd_start = hextoul(argv[2], NULL);
+                       initrd_end = initrd_start + hextoul(argv[3], NULL) - 1;
                }
 
                fdt_chosen(working_fdt);
@@ -664,7 +692,7 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                        return CMD_RET_FAILURE;
 
                if (argc > 2) {
-                       addr = simple_strtoul(argv[2], NULL, 16);
+                       addr = hextoul(argv[2], NULL);
                        blob = map_sysmem(addr, 0);
                } else {
                        blob = (struct fdt_header *)gd->fdt_blob;
@@ -701,7 +729,7 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                if (!working_fdt)
                        return CMD_RET_FAILURE;
 
-               addr = simple_strtoul(argv[2], NULL, 16);
+               addr = hextoul(argv[2], NULL);
                blob = map_sysmem(addr, 0);
                if (!fdt_valid(&blob))
                        return CMD_RET_FAILURE;
@@ -716,7 +744,7 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
        else if (strncmp(argv[1], "re", 2) == 0) {
                uint extrasize;
                if (argc > 2)
-                       extrasize = simple_strtoul(argv[2], NULL, 16);
+                       extrasize = hextoul(argv[2], NULL);
                else
                        extrasize = 0;
                fdt_shrink_to_minimum(working_fdt, extrasize);
@@ -807,7 +835,7 @@ static int fdt_parse_prop(char * const *newval, int count, char *data, int *len)
                        }
                        if (!isxdigit(*newp))
                                break;
-                       tmp = simple_strtoul(newp, &newp, 16);
+                       tmp = hextoul(newp, &newp);
                        *data++ = tmp & 0xFF;
                        *len    = *len + 1;
                }
@@ -893,7 +921,7 @@ static void print_data(const void *data, int len)
 
        env_max_dump = env_get("fdt_max_dump");
        if (env_max_dump)
-               max_dump = simple_strtoul(env_max_dump, NULL, 16);
+               max_dump = hextoul(env_max_dump, NULL);
 
        /*
         * It is a string, but it may have multiple strings (embedded '\0's).
@@ -1064,7 +1092,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)
 /********************************************************************/
 #ifdef CONFIG_SYS_LONGHELP
 static char fdt_help_text[] =
-       "addr [-c]  <addr> [<length>]   - Set the [control] fdt location to <addr>\n"
+       "addr [-c] [-q] <addr> [<size>]  - Set the [control] fdt location to <addr>\n"
 #ifdef CONFIG_OF_LIBFDT_OVERLAY
        "fdt apply <addr>                    - Apply overlay to the DT\n"
 #endif
@@ -1078,7 +1106,9 @@ static char fdt_help_text[] =
        "fdt resize [<extrasize>]            - Resize fdt to size + padding to 4k addr + some optional <extrasize> if needed\n"
        "fdt print  <path> [<prop>]          - Recursive print starting at <path>\n"
        "fdt list   <path> [<prop>]          - Print one level starting at <path>\n"
-       "fdt get value <var> <path> <prop>   - Get <property> and store in <var>\n"
+       "fdt get value <var> <path> <prop> [<index>] - Get <property> and store in <var>\n"
+       "                                      In case of stringlist property, use optional <index>\n"
+       "                                      to select string within the stringlist. Default is 0.\n"
        "fdt get name <var> <path> <index>   - Get name of node <index> and store in <var>\n"
        "fdt get addr <var> <path> <prop>    - Get start address of <property> and store in <var>\n"
        "fdt get size <var> <path> [<prop>]  - Get size of [<property>] or num nodes and store in <var>\n"
@@ -1092,8 +1122,8 @@ static char fdt_help_text[] =
        "fdt rsvmem print                    - Show current mem reserves\n"
        "fdt rsvmem add <addr> <size>        - Add a mem reserve\n"
        "fdt rsvmem delete <index>           - Delete a mem reserves\n"
-       "fdt chosen [<start> <end>]          - Add/update the /chosen branch in the tree\n"
-       "                                        <start>/<end> - initrd start/end addr\n"
+       "fdt chosen [<start> <size>]         - Add/update the /chosen branch in the tree\n"
+       "                                        <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"