]> git.sur5r.net Git - u-boot/blobdiff - arch/powerpc/lib/bootm.c
Merge git://git.denx.de/u-boot
[u-boot] / arch / powerpc / lib / bootm.c
index 0685a9331cba9fa7918b309b8c004709308c4436..ac5bd6d4f1599c0b0514a4d4004d17f0c93199af 100644 (file)
@@ -33,6 +33,7 @@
 #include <bzlib.h>
 #include <environment.h>
 #include <asm/byteorder.h>
+#include <asm/mp.h>
 
 #if defined(CONFIG_OF_LIBFDT)
 #include <fdt.h>
@@ -47,7 +48,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 extern ulong get_effective_memsize(void);
 static ulong get_sp (void);
 static void set_clocks_in_mhz (bd_t *kbd);
@@ -69,7 +69,7 @@ static void boot_jump_linux(bootm_headers_t *images)
        debug ("## Transferring control to Linux (at address %08lx) ...\n",
                (ulong)kernel);
 
-       show_boot_progress (15);
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
 
 #if defined(CONFIG_SYS_INIT_RAM_LOCK) && !defined(CONFIG_E500)
        unlock_ram_in_cache();
@@ -87,7 +87,7 @@ static void boot_jump_linux(bootm_headers_t *images)
                 *   r8: 0
                 *   r9: 0
                 */
-#if defined(CONFIG_85xx) || defined(CONFIG_440)
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_440)
  #define EPAPR_MAGIC   (0x45504150)
 #else
  #define EPAPR_MAGIC   (0x65504150)
@@ -96,7 +96,7 @@ static void boot_jump_linux(bootm_headers_t *images)
                debug ("   Booting using OF flat tree...\n");
                WATCHDOG_RESET ();
                (*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC,
-                          CONFIG_SYS_BOOTMAPSZ, 0, 0);
+                          getenv_bootm_mapsize(), 0, 0);
                /* does not return */
        } else
 #endif
@@ -163,26 +163,31 @@ void arch_lmb_reserve(struct lmb *lmb)
        sp = get_sp();
        debug ("## Current stack ends at 0x%08lx\n", sp);
 
-       /* adjust sp by 1K to be safe */
-       sp -= 1024;
+       /* adjust sp by 4K to be safe */
+       sp -= 4096;
        lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + get_effective_memsize() - sp));
 
+#ifdef CONFIG_MP
+       cpu_mp_lmb_reserve(lmb);
+#endif
+
        return ;
 }
 
-static void boot_prep_linux(void)
+static void boot_prep_linux(bootm_headers_t *images)
 {
 #ifdef CONFIG_MP
-       /* if we are MP make sure to flush the dcache() to any changes are made
-        * visibile to all other cores */
-       flush_dcache();
+       /*
+        * if we are MP make sure to flush the device tree so any changes are
+        * made visibile to all other cores.  In AMP boot scenarios the cores
+        * might not be HW cache coherent with each other.
+        */
+       flush_cache((unsigned long)images->ft_addr, images->ft_len);
 #endif
-       return ;
 }
 
 static int boot_cmdline_linux(bootm_headers_t *images)
 {
-       ulong bootmap_base = getenv_bootm_low();
        ulong of_size = images->ft_len;
        struct lmb *lmb = &images->lmb;
        ulong *cmd_start = &images->cmdline_start;
@@ -192,7 +197,7 @@ static int boot_cmdline_linux(bootm_headers_t *images)
 
        if (!of_size) {
                /* allocate space and init command line */
-               ret = boot_get_cmdline (lmb, cmd_start, cmd_end, bootmap_base);
+               ret = boot_get_cmdline (lmb, cmd_start, cmd_end);
                if (ret) {
                        puts("ERROR with allocation of cmdline\n");
                        return ret;
@@ -204,7 +209,6 @@ static int boot_cmdline_linux(bootm_headers_t *images)
 
 static int boot_bd_t_linux(bootm_headers_t *images)
 {
-       ulong bootmap_base = getenv_bootm_low();
        ulong of_size = images->ft_len;
        struct lmb *lmb = &images->lmb;
        bd_t **kbd = &images->kbd;
@@ -213,7 +217,7 @@ static int boot_bd_t_linux(bootm_headers_t *images)
 
        if (!of_size) {
                /* allocate space for kernel copy of board info */
-               ret = boot_get_kbd (lmb, kbd, bootmap_base);
+               ret = boot_get_kbd (lmb, kbd);
                if (ret) {
                        puts("ERROR with allocation of kernel bd\n");
                        return ret;
@@ -224,6 +228,24 @@ static int boot_bd_t_linux(bootm_headers_t *images)
        return ret;
 }
 
+/*
+ * Verify the device tree.
+ *
+ * This function is called after all device tree fix-ups have been enacted,
+ * so that the final device tree can be verified.  The definition of "verified"
+ * is up to the specific implementation.  However, it generally means that the
+ * addresses of some of the devices in the device tree are compared with the
+ * actual addresses at which U-Boot has placed them.
+ *
+ * Returns 1 on success, 0 on failure.  If 0 is returned, U-boot will halt the
+ * boot process.
+ */
+static int __ft_verify_fdt(void *fdt)
+{
+       return 1;
+}
+__attribute__((weak, alias("__ft_verify_fdt"))) int ft_verify_fdt(void *fdt);
+
 static int boot_body_linux(bootm_headers_t *images)
 {
        ulong rd_len;
@@ -231,13 +253,16 @@ static int boot_body_linux(bootm_headers_t *images)
        ulong *initrd_start = &images->initrd_start;
        ulong *initrd_end = &images->initrd_end;
 #if defined(CONFIG_OF_LIBFDT)
-       ulong bootmap_base = getenv_bootm_low();
        ulong of_size = images->ft_len;
        char **of_flat_tree = &images->ft_addr;
 #endif
 
        int ret;
 
+#if defined(CONFIG_OF_LIBFDT)
+       boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+#endif
+
        /* allocate space and init command line */
        ret = boot_cmdline_linux(images);
        if (ret)
@@ -254,7 +279,7 @@ static int boot_body_linux(bootm_headers_t *images)
                return ret;
 
 #if defined(CONFIG_OF_LIBFDT)
-       ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size);
+       ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
        if (ret)
                return ret;
 
@@ -283,21 +308,26 @@ static int boot_body_linux(bootm_headers_t *images)
                        return ret;
                of_size = ret;
 
-               if (*initrd_start && *initrd_end)
+               if (*initrd_start && *initrd_end) {
                        of_size += FDT_RAMDISK_OVERHEAD;
+                       fdt_set_totalsize(*of_flat_tree, of_size);
+               }
                /* Create a new LMB reservation */
                lmb_reserve(lmb, (ulong)*of_flat_tree, of_size);
 
                /* fixup the initrd now that we know where it should be */
                if (*initrd_start && *initrd_end)
                        fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
+
+               if (!ft_verify_fdt(*of_flat_tree))
+                       return -1;
        }
 #endif /* CONFIG_OF_LIBFDT */
        return 0;
 }
 
-__attribute__((noinline))
-int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+noinline
+int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
 {
        int     ret;
 
@@ -312,7 +342,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
        }
 
        if (flag & BOOTM_STATE_OS_PREP) {
-               boot_prep_linux();
+               boot_prep_linux(images);
                return 0;
        }
 
@@ -321,7 +351,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
                return 0;
        }
 
-       boot_prep_linux();
+       boot_prep_linux(images);
        ret = boot_body_linux(images);
        if (ret)
                return ret;