summaryrefslogtreecommitdiff
path: root/arch/arm/lib/bootm.c
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-07-12 14:24:03 +0100
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-07-28 17:19:09 +0200
commitf510aeae689925a660bff14683eef4147785d271 (patch)
treec64b78f6ed747616c80e52c7c20e2508fca652f1 /arch/arm/lib/bootm.c
parentbf433afd60ce2ccd1bec3cf14150323be8272ac3 (diff)
downloadu-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.c22
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
}