]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/cmd_fdt.c
upgrade to upstream version 2013.07
[karo-tx-uboot.git] / common / cmd_fdt.c
index 6088baf64fcee5880ac19dccffe59e706495e1e0..e17c3f1d51b83ddc51eb1023e0d87d9a0e79cf12 100644 (file)
@@ -5,23 +5,7 @@
  *   Pantelis Antoniou <pantelis.antoniou@gmail.com> and
  *   Matthew McClintock <msm@freescale.com>
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -29,9 +13,9 @@
 #include <linux/ctype.h>
 #include <linux/types.h>
 #include <asm/global_data.h>
-#include <fdt.h>
 #include <libfdt.h>
 #include <fdt_support.h>
+#include <asm/io.h>
 
 #define MAX_LEVEL      32              /* how deeply nested we will go */
 #define SCRATCHPAD     1024            /* bytes of scratchpad memory */
@@ -44,7 +28,7 @@
  */
 DECLARE_GLOBAL_DATA_PTR;
 
-static int fdt_valid(void);
+static int fdt_valid(struct fdt_header **blobp);
 static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
 static int fdt_print(const char *pathp, char *prop, int depth);
 static int is_printable_string(const void *data, int len);
@@ -56,12 +40,11 @@ struct fdt_header *working_fdt;
 
 void set_working_fdt_addr(void *addr)
 {
-       char buf[17];
+       void *buf;
 
-       working_fdt = addr;
-
-       sprintf(buf, "%lx", (unsigned long)addr);
-       setenv("fdtaddr", buf);
+       buf = map_sysmem((ulong)addr, 0);
+       working_fdt = buf;
+       setenv_addr("fdtaddr", addr);
 }
 
 /*
@@ -105,40 +88,59 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
         */
        if (argv[1][0] == 'a') {
                unsigned long addr;
+               int control = 0;
+               struct fdt_header *blob;
                /*
                 * Set the address [and length] of the fdt.
                 */
-               if (argc == 2) {
-                       if (!fdt_valid()) {
+               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;
+                       argc--;
+                       argv++;
+               }
+#endif
+               if (argc == 0) {
+                       if (control)
+                               blob = (struct fdt_header *)gd->fdt_blob;
+                       else
+                               blob = working_fdt;
+                       if (!blob || !fdt_valid(&blob))
                                return 1;
-                       }
-                       printf("The address of the fdt is %p\n", working_fdt);
+                       printf("The address of the fdt is %#08lx\n",
+                              control ? (ulong)blob :
+                                       getenv_hex("fdtaddr", 0));
                        return 0;
                }
 
-               addr = simple_strtoul(argv[2], NULL, 16);
-               set_working_fdt_addr((void *)addr);
-
-               if (!fdt_valid()) {
+               addr = simple_strtoul(argv[0], NULL, 16);
+               blob = map_sysmem(addr, 0);
+               if (!fdt_valid(&blob))
                        return 1;
-               }
+               if (control)
+                       gd->fdt_blob = blob;
+               else
+                       set_working_fdt_addr(blob);
 
-               if (argc >= 4) {
+               if (argc >= 2) {
                        int  len;
                        int  err;
                        /*
                         * Optional new length
                         */
-                       len = simple_strtoul(argv[3], NULL, 16);
-                       if (len < fdt_totalsize(working_fdt)) {
+                       len = simple_strtoul(argv[1], NULL, 16);
+                       if (len < fdt_totalsize(blob)) {
                                printf ("New length %d < existing length %d, "
                                        "ignoring.\n",
-                                       len, fdt_totalsize(working_fdt));
+                                       len, fdt_totalsize(blob));
                        } else {
                                /*
                                 * Open in place with a new length.
                                 */
-                               err = fdt_open_into(working_fdt, working_fdt, len);
+                               err = fdt_open_into(blob, blob, len);
                                if (err != 0) {
                                        printf ("libfdt fdt_open_into(): %s\n",
                                                fdt_strerror(err));
@@ -172,9 +174,8 @@ static int do_fdt(cmd_tbl_t *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);
-               if (!fdt_valid()) {
+               if (!fdt_valid(&working_fdt))
                        return 1;
-               }
 
                newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16);
 
@@ -348,10 +349,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 */
-                               char buf[11];
-
-                               sprintf(buf, "%d", curIndex + 1);
-                               setenv(var, buf);
+                               setenv_ulong(var, curIndex + 1);
                        } else {
                                /* node index not found */
                                printf("libfdt node not found\n");
@@ -600,16 +598,23 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 /****************************************************************************/
 
-static int fdt_valid(void)
+/**
+ * fdt_valid() - Check if an FDT is valid. If not, change it to NULL
+ *
+ * @blobp: Pointer to FDT pointer
+ * @return 1 if OK, 0 if bad (in which case *blobp is set to NULL)
+ */
+static int fdt_valid(struct fdt_header **blobp)
 {
-       int  err;
+       const void *blob = *blobp;
+       int err;
 
-       if (working_fdt == NULL) {
+       if (blob == NULL) {
                printf ("The address of the fdt is invalid (NULL).\n");
                return 0;
        }
 
-       err = fdt_check_header(working_fdt);
+       err = fdt_check_header(blob);
        if (err == 0)
                return 1;       /* valid */
 
@@ -619,23 +624,21 @@ static int fdt_valid(void)
                 * Be more informative on bad version.
                 */
                if (err == -FDT_ERR_BADVERSION) {
-                       if (fdt_version(working_fdt) <
+                       if (fdt_version(blob) <
                            FDT_FIRST_SUPPORTED_VERSION) {
                                printf (" - too old, fdt %d < %d",
-                                       fdt_version(working_fdt),
+                                       fdt_version(blob),
                                        FDT_FIRST_SUPPORTED_VERSION);
-                               working_fdt = NULL;
                        }
-                       if (fdt_last_comp_version(working_fdt) >
+                       if (fdt_last_comp_version(blob) >
                            FDT_LAST_SUPPORTED_VERSION) {
                                printf (" - too new, fdt %d > %d",
-                                       fdt_version(working_fdt),
+                                       fdt_version(blob),
                                        FDT_LAST_SUPPORTED_VERSION);
-                               working_fdt = NULL;
                        }
-                       return 0;
                }
                printf("\n");
+               *blobp = NULL;
                return 0;
        }
        return 1;
@@ -966,7 +969,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)
 /********************************************************************/
 #ifdef CONFIG_SYS_LONGHELP
 static char fdt_help_text[] =
-       "addr   <addr> [<length>]        - Set the fdt location to <addr>\n"
+       "addr [-c]  <addr> [<length>]   - Set the [control] fdt location to <addr>\n"
 #ifdef CONFIG_OF_BOARD_SETUP
        "fdt boardsetup                      - Do board-specific set up\n"
 #endif