]> git.sur5r.net Git - u-boot/blobdiff - arch/arm/lib/bootm.c
Merge git://www.denx.de/git/u-boot-imx
[u-boot] / arch / arm / lib / bootm.c
index dedcd1e9a4b8d2d3ab4c64f615388011f5123478..5c62d9c144061aa888730a3dda682042e77a4208 100644 (file)
@@ -14,6 +14,8 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
+#include <dm/root.h>
 #include <image.h>
 #include <u-boot/zlib.h>
 #include <asm/byteorder.h>
@@ -29,6 +31,7 @@
 #ifdef CONFIG_ARMV7_NONSEC
 #include <asm/armv7.h>
 #endif
+#include <asm/setup.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -91,6 +94,13 @@ static void announce_and_cleanup(int fake)
 
        board_quiesce_devices();
 
+       /*
+        * Call remove function of all devices with a removal flag set.
+        * This may be useful for last-stage operations, like cancelling
+        * of DMA operation or releasing device internal buffers.
+        */
+       dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
+
        cleanup_before_linux();
 }
 
@@ -200,17 +210,13 @@ static void do_nonsec_virt_switch(void)
 {
        smp_kick_all_cpus();
        dcache_disable();       /* flush cache before swtiching to EL2 */
-       armv8_switch_to_el2();
-#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
-       armv8_switch_to_el1();
-#endif
 }
 #endif
 
 /* Subcommand: PREP */
 static void boot_prep_linux(bootm_headers_t *images)
 {
-       char *commandline = getenv("bootargs");
+       char *commandline = env_get("bootargs");
 
        if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
 #ifdef CONFIG_OF_LIBFDT
@@ -267,7 +273,7 @@ __weak bool armv7_boot_nonsec_default(void)
 #ifdef CONFIG_ARMV7_NONSEC
 bool armv7_boot_nonsec(void)
 {
-       char *s = getenv("bootm_boot_mode");
+       char *s = env_get("bootm_boot_mode");
        bool nonsec = armv7_boot_nonsec_default();
 
        if (s && !strcmp(s, "sec"))
@@ -280,6 +286,28 @@ bool armv7_boot_nonsec(void)
 }
 #endif
 
+#ifdef CONFIG_ARM64
+__weak void update_os_arch_secondary_cores(uint8_t os_arch)
+{
+}
+
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+static void switch_to_el1(void)
+{
+       if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+           (images.os.arch == IH_ARCH_ARM))
+               armv8_switch_to_el1(0, (u64)gd->bd->bi_arch_number,
+                                   (u64)images.ft_addr, 0,
+                                   (u64)images.ep,
+                                   ES_TO_AARCH32);
+       else
+               armv8_switch_to_el1((u64)images.ft_addr, 0, 0, 0,
+                                   images.ep,
+                                   ES_TO_AARCH64);
+}
+#endif
+#endif
+
 /* Subcommand: GO */
 static void boot_jump_linux(bootm_headers_t *images, int flag)
 {
@@ -298,8 +326,28 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
        announce_and_cleanup(fake);
 
        if (!fake) {
+#ifdef CONFIG_ARMV8_PSCI
+               armv8_setup_psci();
+#endif
                do_nonsec_virt_switch();
-               kernel_entry(images->ft_addr, NULL, NULL, NULL);
+
+               update_os_arch_secondary_cores(images->os.arch);
+
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+               armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
+                                   (u64)switch_to_el1, ES_TO_AARCH64);
+#else
+               if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+                   (images->os.arch == IH_ARCH_ARM))
+                       armv8_switch_to_el2(0, (u64)gd->bd->bi_arch_number,
+                                           (u64)images->ft_addr, 0,
+                                           (u64)images->ep,
+                                           ES_TO_AARCH32);
+               else
+                       armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
+                                           images->ep,
+                                           ES_TO_AARCH64);
+#endif
        }
 #else
        unsigned long machid = gd->bd->bi_arch_number;
@@ -309,8 +357,11 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
        int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
 
        kernel_entry = (void (*)(int, int, uint))images->ep;
-
-       s = getenv("machid");
+#ifdef CONFIG_CPU_V7M
+       ulong addr = (ulong)kernel_entry | 1;
+       kernel_entry = (void *)addr;
+#endif
+       s = env_get("machid");
        if (s) {
                if (strict_strtoul(s, 16, &machid) < 0) {
                        debug("strict_strtoul failed!\n");
@@ -379,10 +430,8 @@ void boot_prep_vxworks(bootm_headers_t *images)
        if (images->ft_addr) {
                off = fdt_path_offset(images->ft_addr, "/memory");
                if (off < 0) {
-#ifdef CONFIG_ARCH_FIXUP_FDT
                        if (arch_fixup_fdt(images->ft_addr))
                                puts("## WARNING: fixup memory failed!\n");
-#endif
                }
        }
 #endif