Add support for BL3-2 in BL3-1
This patch adds the following support to the BL3-1 stage:
1. BL3-1 allows runtime services to specify and determine the security
state of the next image after BL3-1. This has been done by adding
the `bl31_set_next_image_type()` & `bl31_get_next_image_type()`
apis. The default security state is non-secure. The platform api
`bl31_get_next_image_info()` has been modified to let the platform
decide which is the next image in the desired security state.
2. BL3-1 exports the `bl31_prepare_next_image_entry()` function to
program entry into the target security state. It uses the apis
introduced in 1. to do so.
3. BL3-1 reads the information populated by BL2 about the BL3-2 image
into its internal data structures.
4. BL3-1 introduces a weakly defined reference `bl32_init()` to allow
initialisation of a BL3-2 image. A runtime service like the Secure
payload dispatcher will define this function if present.
Change-Id: Icc46dcdb9e475ce6575dd3f9a5dc7a48a83d21d1
diff --git a/bl31/aarch64/bl31_arch_setup.c b/bl31/aarch64/bl31_arch_setup.c
index 492c45b..03b9623 100644
--- a/bl31/aarch64/bl31_arch_setup.c
+++ b/bl31/aarch64/bl31_arch_setup.c
@@ -73,10 +73,12 @@
}
/*******************************************************************************
- * Detect what is the next Non-Secure EL and setup the required architectural
- * state
+ * Detect what the security state of the next EL is and setup the minimum
+ * required architectural state: program SCTRL to reflect the RES1 bits, and to
+ * have MMU and caches disabled
******************************************************************************/
-void bl31_arch_next_el_setup(void) {
+void bl31_next_el_arch_setup(uint32_t security_state)
+{
unsigned long id_aa64pfr0 = read_id_aa64pfr0_el1();
unsigned long current_sctlr, next_sctlr;
unsigned long el_status;
@@ -89,16 +91,20 @@
/* Find out which EL we are going to */
el_status = (id_aa64pfr0 >> ID_AA64PFR0_EL2_SHIFT) & ID_AA64PFR0_ELX_MASK;
- /* Check what if EL2 is supported */
- if (el_status && (scr & SCR_HCE_BIT)) {
- /* Set SCTLR EL2 */
- next_sctlr |= SCTLR_EL2_RES1;
-
- write_sctlr_el2(next_sctlr);
- } else {
- /* Set SCTLR Non-Secure EL1 */
- next_sctlr |= SCTLR_EL1_RES1;
-
- write_sctlr_el1(next_sctlr);
+ if (security_state == NON_SECURE) {
+ /* Check if EL2 is supported */
+ if (el_status && (scr & SCR_HCE_BIT)) {
+ /* Set SCTLR EL2 */
+ next_sctlr |= SCTLR_EL2_RES1;
+ write_sctlr_el2(next_sctlr);
+ return;
+ }
}
+
+ /*
+ * SCTLR_EL1 needs the same programming irrespective of the
+ * security state of EL1.
+ */
+ next_sctlr |= SCTLR_EL1_RES1;
+ write_sctlr_el1(next_sctlr);
}