Initialise CPU contexts from entry_point_info
Consolidate all BL3-1 CPU context initialization for cold boot, PSCI
and SPDs into two functions:
* The first uses entry_point_info to initialize the relevant
cpu_context for first entry into a lower exception level on a CPU
* The second populates the EL1 and EL2 system registers as needed
from the cpu_context to ensure correct entry into the lower EL
This patch alters the way that BL3-1 determines which exception level
is used when first entering EL1 or EL2 during cold boot - this is now
fully determined by the SPSR value in the entry_point_info for BL3-3,
as set up by the platform code in BL2 (or otherwise provided to BL3-1).
In the situation that EL1 (or svc mode) is selected for a processor
that supports EL2, the context management code will now configure all
essential EL2 register state to ensure correct execution of EL1. This
allows the platform code to run non-secure EL1 payloads directly
without requiring a small EL2 stub or OS loader.
Change-Id: If9fbb2417e82d2226e47568203d5a369f39d3b0f
diff --git a/include/bl31/context_mgmt.h b/include/bl31/context_mgmt.h
index ade2fa1..6127b74 100644
--- a/include/bl31/context_mgmt.h
+++ b/include/bl31/context_mgmt.h
@@ -35,6 +35,11 @@
#include <stdint.h>
/*******************************************************************************
+ * Forward declarations
+ ******************************************************************************/
+struct entry_point_info;
+
+/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
void cm_init(void);
@@ -45,12 +50,14 @@
uint32_t security_state);
static inline void cm_set_context(void *context, uint32_t security_state);
void cm_el3_sysregs_context_save(uint32_t security_state);
+void cm_init_context(uint64_t mpidr, const struct entry_point_info *ep);
+void cm_prepare_el3_exit(uint32_t security_state);
void cm_el3_sysregs_context_restore(uint32_t security_state);
void cm_el1_sysregs_context_save(uint32_t security_state);
void cm_el1_sysregs_context_restore(uint32_t security_state);
-void cm_set_el3_eret_context(uint32_t security_state, uint64_t entrypoint,
- uint32_t spsr, uint32_t scr);
void cm_set_elr_el3(uint32_t security_state, uint64_t entrypoint);
+void cm_set_elr_spsr_el3(uint32_t security_state,
+ uint64_t entrypoint, uint32_t spsr);
void cm_write_scr_el3_bit(uint32_t security_state,
uint32_t bit_pos,
uint32_t value);
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 2f3bade..f5e2a9a 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -33,7 +33,6 @@
#define SECURE 0x0
#define NON_SECURE 0x1
-#define PARAM_EP_SECURITY_MASK 0x1
#define UP 1
#define DOWN 0
@@ -64,10 +63,23 @@
#define ENTRY_POINT_INFO_PC_OFFSET 0x08
#define ENTRY_POINT_INFO_ARGS_OFFSET 0x18
+#define PARAM_EP_SECURITY_MASK 0x1
#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK)
#define SET_SECURITY_STATE(x, security) \
((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security))
+#define EP_EE_MASK 0x2
+#define EP_EE_LITTLE 0x0
+#define EP_EE_BIG 0x2
+#define EP_GET_EE(x) (x & EP_EE_MASK)
+#define EP_SET_EE(x, ee) ((x) = ((x) & ~EP_EE_MASK) | (ee))
+
+#define EP_ST_MASK 0x4
+#define EP_ST_DISABLE 0x0
+#define EP_ST_ENABLE 0x4
+#define EP_GET_ST(x) (x & EP_ST_MASK)
+#define EP_SET_ST(x, ee) ((x) = ((x) & ~EP_ST_MASK) | (ee))
+
#define PARAM_EP 0x01
#define PARAM_IMAGE_BINARY 0x02
#define PARAM_BL31 0x03
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 0bfbd66..5dc488b 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -167,6 +167,7 @@
#define HCR_FMO_BIT (1 << 3)
/* CNTHCTL_EL2 definitions */
+#define EVNTEN_BIT (1 << 2)
#define EL1PCEN_BIT (1 << 1)
#define EL1PCTEN_BIT (1 << 0)
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 1ca3350..673e897 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -262,6 +262,9 @@
DEFINE_SYSREG_RW_FUNCS(tpidr_el3)
+DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
+DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
+
/* Implementation specific registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(cpuectlr_el1, CPUECTLR_EL1)