Merge git://www.denx.de/git/u-boot
[platform/kernel/u-boot.git] / common / cmd_bootm.c
index e19f83e..2fa906b 100644 (file)
@@ -260,6 +260,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        if (hdr->ih_arch != IH_CPU_NIOS2)
 #elif defined(__PPC__)
        if (hdr->ih_arch != IH_CPU_PPC)
+#elif defined(__sh__)
+       if (hdr->ih_arch != IH_CPU_SH)
 #else
 # error Unknown CPU type
 #endif
@@ -817,27 +819,34 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                int i;
 
                /* skip kernel length, initrd length, and terminator */
-               of_data = (ulong)(&len_ptr[3]);
+               of_flat_tree = (char *)(&len_ptr[3]);
                /* skip any additional image length fields */
                for (i=2; len_ptr[i]; ++i)
-                       of_data += 4;
+                       of_flat_tree += 4;
                /* add kernel length, and align */
-               of_data += ntohl(len_ptr[0]);
+               of_flat_tree += ntohl(len_ptr[0]);
                if (tail) {
-                       of_data += 4 - tail;
+                       of_flat_tree += 4 - tail;
                }
 
                /* add initrd length, and align */
                tail = ntohl(len_ptr[1]) % 4;
-               of_data += ntohl(len_ptr[1]);
+               of_flat_tree += ntohl(len_ptr[1]);
                if (tail) {
-                       of_data += 4 - tail;
+                       of_flat_tree += 4 - tail;
                }
 
+#ifndef CFG_NO_FLASH
+               /* move the blob if it is in flash (set of_data to !null) */
+               if (addr2info ((ulong)of_flat_tree) != NULL)
+                       of_data = (ulong)of_flat_tree;
+#endif
+
+
 #if defined(CONFIG_OF_FLAT_TREE)
-               if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) {
+               if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) {
 #else
-               if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) != 0) {
+               if (fdt_check_header (of_flat_tree) != 0) {
 #endif
                        puts ("ERROR: image is not a fdt - "
                                "must RESET the board to recover.\n");
@@ -845,9 +854,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                }
 
 #if defined(CONFIG_OF_FLAT_TREE)
-               if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) {
+               if (((struct boot_param_header *)of_flat_tree)->totalsize !=
+                       ntohl (len_ptr[2])) {
 #else
-               if (be32_to_cpu(fdt_totalsize(of_data)) !=  ntohl(len_ptr[2])) {
+               if (be32_to_cpu (fdt_totalsize (of_flat_tree)) !=
+                       ntohl(len_ptr[2])) {
 #endif
                        puts ("ERROR: fdt size != image size - "
                                "must RESET the board to recover.\n");
@@ -925,17 +936,25 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
        }
 
 #if defined(CONFIG_OF_LIBFDT)
+
+#ifdef CFG_BOOTMAPSZ
+       /*
+        * The blob must be within CFG_BOOTMAPSZ,
+        * so we flag it to be copied if it is not.
+        */
+       if (of_flat_tree >= (char *)CFG_BOOTMAPSZ)
+               of_data = (ulong)of_flat_tree;
+#endif
+
        /* move of_flat_tree if needed */
        if (of_data) {
                int err;
                ulong of_start, of_len;
 
                of_len = be32_to_cpu(fdt_totalsize(of_data));
-               /* position on a 4K boundary before the initrd/kbd */
-               if (initrd_start)
-                       of_start = initrd_start - of_len;
-               else
-                       of_start  = (ulong)kbd - of_len;
+
+               /* position on a 4K boundary before the kbd */
+               of_start  = (ulong)kbd - of_len;
                of_start &= ~(4096 - 1);        /* align on page */
                debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
                        of_data, of_data + of_len - 1, of_len, of_len);
@@ -949,45 +968,55 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                                "must RESET the board to recover.\n");
                        do_reset (cmdtp, flag, argc, argv);
                }
+               puts ("OK\n");
        }
        /*
         * Add the chosen node if it doesn't exist, add the env and bd_t
         * if the user wants it (the logic is in the subroutines).
         */
-       if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) {
-               puts ("ERROR: /chosen node create failed - "
-                       "must RESET the board to recover.\n");
-               do_reset (cmdtp, flag, argc, argv);
-       }
+       if (of_flat_tree) {
+               if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) {
+                       puts ("ERROR: /chosen node create failed - "
+                               "must RESET the board to recover.\n");
+                       do_reset (cmdtp, flag, argc, argv);
+               }
 #ifdef CONFIG_OF_HAS_UBOOT_ENV
-       if (fdt_env(of_flat_tree) < 0) {
-               puts ("ERROR: /u-boot-env node create failed - "
-                       "must RESET the board to recover.\n");
-               do_reset (cmdtp, flag, argc, argv);
-       }
+               if (fdt_env(of_flat_tree) < 0) {
+                       puts ("ERROR: /u-boot-env node create failed - "
+                               "must RESET the board to recover.\n");
+                       do_reset (cmdtp, flag, argc, argv);
+               }
 #endif
 #ifdef CONFIG_OF_HAS_BD_T
-       if (fdt_bd_t(of_flat_tree) < 0) {
-               puts ("ERROR: /bd_t node create failed - "
-                       "must RESET the board to recover.\n");
-               do_reset (cmdtp, flag, argc, argv);
-       }
+               if (fdt_bd_t(of_flat_tree) < 0) {
+                       puts ("ERROR: /bd_t node create failed - "
+                               "must RESET the board to recover.\n");
+                       do_reset (cmdtp, flag, argc, argv);
+               }
 #endif
 #ifdef CONFIG_OF_BOARD_SETUP
-       /* Call the board-specific fixup routine */
-       ft_board_setup(of_flat_tree, gd->bd);
+               /* Call the board-specific fixup routine */
+               ft_board_setup(of_flat_tree, gd->bd);
 #endif
+       }
 #endif /* CONFIG_OF_LIBFDT */
 #if defined(CONFIG_OF_FLAT_TREE)
+#ifdef CFG_BOOTMAPSZ
+       /*
+        * The blob must be within CFG_BOOTMAPSZ,
+        * so we flag it to be copied if it is not.
+        */
+       if (of_flat_tree >= (char *)CFG_BOOTMAPSZ)
+               of_data = (ulong)of_flat_tree;
+#endif
+
        /* move of_flat_tree if needed */
        if (of_data) {
                ulong of_start, of_len;
                of_len = ((struct boot_param_header *)of_data)->totalsize;
+
                /* provide extra 8k pad */
-               if (initrd_start)
-                       of_start = initrd_start - of_len - 8192;
-               else
-                       of_start  = (ulong)kbd - of_len - 8192;
+               of_start  = (ulong)kbd - of_len - 8192;
                of_start &= ~(4096 - 1);        /* align on page */
                debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
                        of_data, of_data + of_len - 1, of_len, of_len);
@@ -996,6 +1025,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                printf ("   Loading Device Tree to %08lx, end %08lx ... ",
                        of_start, of_start + of_len - 1);
                memmove ((void *)of_start, (void *)of_data, of_len);
+               puts ("OK\n");
        }
        /*
         * Create the /chosen node and modify the blob with board specific