aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2012-09-06 18:12:44 +0100
committerPeter Maydell <peter.maydell@linaro.org>2012-09-26 15:20:59 +0100
commit43130b7183c333ebe7af495ae327a50c8116643b (patch)
tree18000d608272cc1f9b2dcc206b36dc701a106ede
parent6c648c46553f0213dd523bdf8430aececdf1e42d (diff)
downloadboot-wrapper-43130b7183c333ebe7af495ae327a50c8116643b.tar.gz
bootwrapper: Delay switch to Hyp mode until kernel entry
The bootwrapper is really doubling as firmware, so it doesn't make sense for it to drop out of the Secure World before getting a chance to parse its parameters and configuration. Instead, it is better to delay switching to the Normal World for as long as possible so that we have a chance to do any required firmware-level configuration in the Secure World first. Signed-off-by: Dave Martin <dave.martin@linaro.org> [PMM: moved enter_hyp for secondary CPUs to just before the WFE loop to avoid making the loop code that needs relocation bigger] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--boot.S14
-rw-r--r--semi_loader.h6
2 files changed, 16 insertions, 4 deletions
diff --git a/boot.S b/boot.S
index 128f74e..1e24b0e 100644
--- a/boot.S
+++ b/boot.S
@@ -96,8 +96,6 @@ start:
mov r7, #0xfffffff0
smc #0 @ Set HVBAR
- enter_hyp
-
@ Check CPU nr again
mrc p15, 0, r0, c0, c0, 5 @ MPIDR (ARMv7 only)
and r0, r0, #15 @ CPU number
@@ -107,6 +105,7 @@ start:
@
@ Secondary CPUs (following the RealView SMP booting protocol)
@
+ enter_hyp
ldr r1, =fs_start - 0x100
adr r2, 1f
@@ -170,6 +169,17 @@ __semi_call:
#endif
mov pc, lr
+.globl __boot_kernel
+__boot_kernel:
+ mov r4, r0
+ stmfd sp!, {r1-r3}
+ ldmia sp, {r0-r3}
+
+ enter_hyp
+
+ bx r4
+.type __boot_kernel, %function
+
@
@ Data
@
diff --git a/semi_loader.h b/semi_loader.h
index 6afba40..29f3d63 100644
--- a/semi_loader.h
+++ b/semi_loader.h
@@ -90,10 +90,12 @@ struct loader_info {
void load_kernel(struct loader_info *info);
+void __boot_kernel(unsigned entry_point,
+ unsigned r0, unsigned r1, unsigned r2, unsigned r3);
+
static void boot_kernel(struct loader_info *info,
unsigned r0, unsigned r1, unsigned r2, unsigned r3) {
- ((void (*)(unsigned, unsigned, unsigned, unsigned))info->kernel_entry)(
- r0, r1, r2, r3);
+ __boot_kernel(info->kernel_entry, r0, r1, r2, r3);
}
#endif /* ! SEMI_LOADER_H */