#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>
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
}
+__weak void board_quiesce_devices(void)
+{
+}
+
/**
* announce_and_cleanup() - Print message and prepare for kernel boot
*
#ifdef CONFIG_USB_DEVICE
udc_disconnect();
#endif
+
+ 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();
}
{
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
}
}
-#ifdef CONFIG_ARMV7_NONSEC
-bool armv7_boot_nonsec(void)
+__weak bool armv7_boot_nonsec_default(void)
{
- char *s = getenv("bootm_boot_mode");
#ifdef CONFIG_ARMV7_BOOT_SEC_DEFAULT
- bool nonsec = false;
+ return false;
#else
- bool nonsec = true;
+ return true;
#endif
+}
+
+#ifdef CONFIG_ARMV7_NONSEC
+bool armv7_boot_nonsec(void)
+{
+ char *s = getenv("bootm_boot_mode");
+ bool nonsec = armv7_boot_nonsec_default();
if (s && !strcmp(s, "sec"))
nonsec = false;
}
#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)
{
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;
int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
kernel_entry = (void (*)(int, int, uint))images->ep;
-
+#ifdef CONFIG_CPU_V7M
+ ulong addr = (ulong)kernel_entry | 1;
+ kernel_entry = (void *)addr;
+#endif
s = getenv("machid");
if (s) {
if (strict_strtoul(s, 16, &machid) < 0) {