X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Farm%2Flib%2Fbootm.c;h=5c62d9c144061aa888730a3dda682042e77a4208;hb=470135be276b2d92c6da464c68839202d4ff0d08;hp=dedcd1e9a4b8d2d3ab4c64f615388011f5123478;hpb=c2cbd164ea5b5f564fcf03447c7bf9ec4a9f5699;p=u-boot diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index dedcd1e9a4..5c62d9c144 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -14,6 +14,8 @@ #include #include +#include +#include #include #include #include @@ -29,6 +31,7 @@ #ifdef CONFIG_ARMV7_NONSEC #include #endif +#include 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