#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) {
return 0;
}
-#ifdef CONFIG_CMD_BOOTZ
-
-struct zimage_header {
- uint32_t code[9];
- uint32_t zi_magic;
- uint32_t zi_start;
- uint32_t zi_end;
-};
-
-#define LINUX_ARM_ZIMAGE_MAGIC 0x016f2818
-
-int bootz_setup(ulong image, ulong *start, ulong *end)
-{
- struct zimage_header *zi;
-
- zi = (struct zimage_header *)map_sysmem(image, 0);
- if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
- puts("Bad Linux ARM zImage magic!\n");
- return 1;
- }
-
- *start = zi->zi_start;
- *end = zi->zi_end;
-
- printf("Kernel image @ %#08lx [ %#08lx - %#08lx ]\n", image, *start,
- *end);
-
- return 0;
-}
-
-#endif /* CONFIG_CMD_BOOTZ */
-
#if defined(CONFIG_BOOTM_VXWORKS)
void boot_prep_vxworks(bootm_headers_t *images)
{