diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2014-07-12 14:24:03 +0100 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2014-07-28 17:19:09 +0200 |
commit | f510aeae689925a660bff14683eef4147785d271 (patch) | |
tree | c64b78f6ed747616c80e52c7c20e2508fca652f1 /arch/arm/lib/bootm.c | |
parent | bf433afd60ce2ccd1bec3cf14150323be8272ac3 (diff) | |
download | u-boot-imx-f510aeae689925a660bff14683eef4147785d271.zip u-boot-imx-f510aeae689925a660bff14683eef4147785d271.tar.gz u-boot-imx-f510aeae689925a660bff14683eef4147785d271.tar.bz2 |
ARM: HYP/non-sec: allow relocation to secure RAM
The current non-sec switching code suffers from one major issue:
it cannot run in secure RAM, as a large part of u-boot still needs
to be run while we're switched to non-secure.
This patch reworks the whole HYP/non-secure strategy by:
- making sure the secure code is the *last* thing u-boot executes
before entering the payload
- performing an exception return from secure mode directly into
the payload
- allowing the code to be dynamically relocated to secure RAM
before switching to non-secure.
This involves quite a bit of horrible code, specially as u-boot
relocation is quite primitive.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
Diffstat (limited to 'arch/arm/lib/bootm.c')
-rw-r--r-- | arch/arm/lib/bootm.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 304210e..a08586f 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -20,6 +20,7 @@ #include <libfdt.h> #include <fdt_support.h> #include <asm/bootm.h> +#include <asm/secure.h> #include <linux/compiler.h> #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) @@ -184,27 +185,17 @@ static void setup_end_tag(bd_t *bd) __weak void setup_board_tags(struct tag **in_params) {} +#ifdef CONFIG_ARM64 static void do_nonsec_virt_switch(void) { -#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) - if (armv7_switch_nonsec() == 0) -#ifdef CONFIG_ARMV7_VIRT - if (armv7_switch_hyp() == 0) - debug("entered HYP mode\n"); -#else - debug("entered non-secure state\n"); -#endif -#endif - -#ifdef CONFIG_ARM64 smp_kick_all_cpus(); flush_dcache_all(); /* flush cache before swtiching to EL2 */ armv8_switch_to_el2(); #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 armv8_switch_to_el1(); #endif -#endif } +#endif /* Subcommand: PREP */ static void boot_prep_linux(bootm_headers_t *images) @@ -289,8 +280,13 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) r2 = gd->bd->bi_boot_params; if (!fake) { - do_nonsec_virt_switch(); +#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) + armv7_init_nonsec(); + secure_ram_addr(_do_nonsec_entry)(kernel_entry, + 0, machid, r2); +#else kernel_entry(0, machid, r2); +#endif } #endif } |