diff options
author | Alison Wang | 2016-11-10 10:49:03 +0800 |
---|---|---|
committer | York Sun | 2016-11-22 11:40:24 -0800 |
commit | ec6617c39741adc6c54952564579e32c3c09c66f (patch) | |
tree | 2c65fb7ab999e39eb6acc0be8890eced30c950a1 /arch/arm/lib | |
parent | 95e74a3df75bf01eaf69f5c28f9aa2db6568e901 (diff) |
armv8: Support loading 32-bit OS in AArch32 execution state
To support loading a 32-bit OS, the execution state will change from
AArch64 to AArch32 when jumping to kernel.
The architecture information will be got through checking FIT image,
then U-Boot will load 32-bit OS or 64-bit OS automatically.
Signed-off-by: Ebony Zhu <ebony.zhu@nxp.com>
Signed-off-by: Alison Wang <alison.wang@nxp.com>
Signed-off-by: Chenhui Zhao <chenhui.zhao@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
Diffstat (limited to 'arch/arm/lib')
-rw-r--r-- | arch/arm/lib/bootm.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index dedcd1e9a4b..6f3be8b528c 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -200,10 +200,6 @@ 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 @@ -280,6 +276,24 @@ bool armv7_boot_nonsec(void) } #endif +#ifdef CONFIG_ARM64 +#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, + (u64)images.ep, + ES_TO_AARCH32); + else + armv8_switch_to_el1((u64)images.ft_addr, 0, 0, + images.ep, + ES_TO_AARCH64); +} +#endif +#endif + /* Subcommand: GO */ static void boot_jump_linux(bootm_headers_t *images, int flag) { @@ -299,7 +313,22 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) if (!fake) { do_nonsec_virt_switch(); - kernel_entry(images->ft_addr, NULL, NULL, NULL); + +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + armv8_switch_to_el2((u64)images->ft_addr, 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, + (u64)images->ep, + ES_TO_AARCH32); + else + armv8_switch_to_el2((u64)images->ft_addr, 0, 0, + images->ep, + ES_TO_AARCH64); +#endif } #else unsigned long machid = gd->bd->bi_arch_number; |