From 441df53f838218484cd8b95ca7c62eefa35ed2c3 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Thu, 11 Sep 2014 16:06:01 -0700 Subject: [PATCH] arm64: Switch to EL2 for libpayload jump CQ-DEPEND=CL:216826,CL:218300 BUG=chrome-os-partner:31634 BRANCH=None TEST=Compiles successfully and we are able to start execution of libpayload in EL2 and reach kernel login prompt Change-Id: I233f9867470a4723f320dc0dcaa670a56dcf0f5d Signed-off-by: Patrick Georgi Original-Commit-Id: 169948a2afeeb7848daeb37600963bd503527f1a Original-Change-Id: I336d73085f08ca03e533555a10b88f20d74b4347 Original-Signed-off-by: Furquan Shaikh Original-Reviewed-on: https://chromium-review.googlesource.com/217826 Original-Tested-by: Furquan Shaikh Original-Reviewed-by: Aaron Durbin Original-Commit-Queue: Furquan Shaikh Reviewed-on: http://review.coreboot.org/9074 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/arch/arm64/boot.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/arch/arm64/boot.c b/src/arch/arm64/boot.c index 5217a9f3b0..91980fbf19 100644 --- a/src/arch/arm64/boot.c +++ b/src/arch/arm64/boot.c @@ -18,17 +18,36 @@ */ #include +#include #include +#include #include #include #include +#include void arch_payload_run(const struct payload *payload) { void (*doit)(void *) = payload->entry; void *cb_tables = cbmem_find(CBMEM_ID_CBTABLE); + uint8_t current_el = get_current_el(); printk(BIOS_SPEW, "entry = %p\n", payload->entry); + + /* If current EL is not EL3, jump to payload at same EL. */ + if (current_el != EL3) { + cache_sync_instructions(); + /* Point of no-return */ + doit(cb_tables); + } + + /* If current EL is EL3, we transition to payload in EL2. */ + struct exc_state exc_state; + + memset(&exc_state, 0, sizeof(exc_state)); + + exc_state.elx.spsr = get_eret_el(EL2, SPSR_USE_L); + cache_sync_instructions(); - doit(cb_tables); + transition_with_entry(payload->entry, cb_tables, &exc_state); }