summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile17
-rw-r--r--bl2/bl2_main.c19
-rw-r--r--docs/porting-guide.md9
-rw-r--r--include/plat/arm/common/plat_arm.h1
-rw-r--r--plat/arm/common/arm_bl1_setup.c14
-rw-r--r--plat/arm/common/arm_common.mk5
-rw-r--r--plat/arm/common/arm_pm.c2
-rw-r--r--plat/arm/common/arm_security.c14
-rw-r--r--plat/arm/css/common/css_bl2_setup.c39
9 files changed, 114 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index c3252c23..80e05fa6 100644
--- a/Makefile
+++ b/Makefile
@@ -235,6 +235,10 @@ INCLUDE_TBBR_MK := 1
################################################################################
ifneq (${SPD},none)
+ifdef EL3_PAYLOAD_BASE
+ $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
+ $(warning "The SPD and its BL32 companion will be present but ignored.")
+endif
# We expect to locate an spd.mk under the specified SPD directory
SPD_MAKE := $(shell m="services/spd/${SPD}/${SPD}.mk"; [ -f "$$m" ] && echo "$$m")
@@ -300,7 +304,12 @@ endif
# supplied for the FIP and Certificate generation tools. This flag can be
# overridden by the platform.
ifdef BL2_SOURCES
+ifndef EL3_PAYLOAD_BASE
NEED_BL33 ?= yes
+else
+# The BL33 image is not needed when booting an EL3 payload.
+NEED_BL33 := no
+endif
endif
# Process TBB related flags
@@ -375,6 +384,10 @@ $(eval $(call add_define,PSCI_EXTENDED_STATE_ID))
$(eval $(call add_define,ERROR_DEPRECATED))
$(eval $(call add_define,ENABLE_PLAT_COMPAT))
$(eval $(call add_define,SPIN_ON_BL1_EXIT))
+# Define the EL3_PAYLOAD_BASE flag only if it is provided.
+ifdef EL3_PAYLOAD_BASE
+$(eval $(call add_define,EL3_PAYLOAD_BASE))
+endif
################################################################################
@@ -392,9 +405,13 @@ include bl2/bl2.mk
endif
ifdef BL31_SOURCES
+# When booting an EL3 payload, there is no need to compile the BL31 image nor
+# put it in the FIP.
+ifndef EL3_PAYLOAD_BASE
NEED_BL31 := yes
include bl31/bl31.mk
endif
+endif
################################################################################
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index f8a2372f..a3f016f9 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -83,6 +83,7 @@ static int load_bl30(void)
return e;
}
+#ifndef EL3_PAYLOAD_BASE
/*******************************************************************************
* Load the BL3-1 image.
* The bl2_to_bl31_params and bl31_ep_info params will be updated with the
@@ -190,6 +191,7 @@ static int load_bl33(bl31_params_t *bl2_to_bl31_params)
return e;
}
+#endif /* EL3_PAYLOAD_BASE */
/*******************************************************************************
* The only thing to do in BL2 is to load further images and pass control to
@@ -232,6 +234,22 @@ void bl2_main(void)
bl2_to_bl31_params = bl2_plat_get_bl31_params();
bl31_ep_info = bl2_plat_get_bl31_ep_info();
+#ifdef EL3_PAYLOAD_BASE
+ /*
+ * In the case of an EL3 payload, we don't need to load any further
+ * images. Just update the BL31 entrypoint info structure to make BL1
+ * jump to the EL3 payload.
+ * The pointer to the memory the platform has set aside to pass
+ * information to BL3-1 in the normal boot flow is reused here, even
+ * though only a fraction of the information contained in the
+ * bl31_params_t structure makes sense in the context of EL3 payloads.
+ * This will be refined in the future.
+ */
+ VERBOSE("BL2: Populating the entrypoint info for the EL3 payload\n");
+ bl31_ep_info->pc = EL3_PAYLOAD_BASE;
+ bl31_ep_info->args.arg0 = (unsigned long) bl2_to_bl31_params;
+ bl2_plat_set_bl31_ep_info(NULL, bl31_ep_info);
+#else
e = load_bl31(bl2_to_bl31_params, bl31_ep_info);
if (e) {
ERROR("Failed to load BL3-1 (%i)\n", e);
@@ -253,6 +271,7 @@ void bl2_main(void)
ERROR("Failed to load BL3-3 (%i)\n", e);
plat_error_handler(e);
}
+#endif /* EL3_PAYLOAD_BASE */
/* Flush the params to be passed to memory */
bl2_plat_flush_bl31_params();
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 2c828c27..5e823e81 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -1001,10 +1001,13 @@ structure in BL2 memory.
Argument : image_info *, entry_point_info *
Return : void
-This function is called after loading BL3-1 image and it can be used to
-overwrite the entry point set by loader and also set the security state
-and SPSR which represents the entry point system state for BL3-1.
+In the normal boot flow, this function is called after loading BL3-1 image and
+it can be used to overwrite the entry point set by loader and also set the
+security state and SPSR which represents the entry point system state for BL3-1.
+When booting an EL3 payload instead, this function is called after populating
+its entry point address and can be used for the same purpose for the payload
+image. It receives a null pointer as its first argument in this case.
### Function : bl2_plat_set_bl32_ep_info() [mandatory]
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 044e18ef..aadf58d8 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -149,6 +149,7 @@ int arm_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state);
int arm_validate_ns_entrypoint(uintptr_t entrypoint);
void arm_system_pwr_domain_resume(void);
+void arm_program_trusted_mailbox(uintptr_t address);
/* Topology utility function */
int arm_check_mpidr(u_register_t mpidr);
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index ddf383fe..887223cf 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -145,6 +145,20 @@ void bl1_platform_setup(void)
arm_bl1_platform_setup();
}
+void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
+{
+#ifdef EL3_PAYLOAD_BASE
+ /*
+ * Program the EL3 payload's entry point address into the CPUs mailbox
+ * in order to release secondary CPUs from their holding pen and make
+ * them jump there.
+ */
+ arm_program_trusted_mailbox(ep_info->pc);
+ dsbsy();
+ sev();
+#endif
+}
+
/*******************************************************************************
* Before calling this function BL2 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index eb5ae111..7b235275 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -81,6 +81,11 @@ BL1_SOURCES += drivers/arm/cci/cci.c \
plat/arm/common/arm_bl1_setup.c \
plat/arm/common/arm_io_storage.c \
plat/common/aarch64/platform_up_stack.S
+ifdef EL3_PAYLOAD_BASE
+# Need the arm_program_trusted_mailbox() function to release secondary CPUs from
+# their holding pen
+BL1_SOURCES += plat/arm/common/arm_pm.c
+endif
BL2_SOURCES += drivers/arm/tzc400/tzc400.c \
drivers/io/io_fip.c \
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index d13d2683..cae65970 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -175,7 +175,7 @@ void arm_system_pwr_domain_resume(void)
* from reset. This function assumes that the Trusted mail box base is within
* the ARM_SHARED_RAM region
******************************************************************************/
-static void arm_program_trusted_mailbox(uintptr_t address)
+void arm_program_trusted_mailbox(uintptr_t address)
{
uintptr_t *mailbox = (void *) PLAT_ARM_TRUSTED_MAILBOX_BASE;
diff --git a/plat/arm/common/arm_security.c b/plat/arm/common/arm_security.c
index 990d8d4a..8b46aaed 100644
--- a/plat/arm/common/arm_security.c
+++ b/plat/arm/common/arm_security.c
@@ -40,8 +40,13 @@
/*******************************************************************************
* Initialize the TrustZone Controller for ARM standard platforms.
- * Configure Region 0 with no access, Region 1 with secure access only, and
- * the remaining DRAM regions access from the given Non-Secure masters.
+ * Configure:
+ * - Region 0 with no access;
+ * - Region 1 with secure access only;
+ * - the remaining DRAM regions access from the given Non-Secure masters.
+ *
+ * When booting an EL3 payload, this is simplified: we configure region 0 with
+ * secure access only and do not enable any other region.
******************************************************************************/
void arm_tzc_setup(void)
{
@@ -52,6 +57,7 @@ void arm_tzc_setup(void)
/* Disable filters. */
tzc_disable_filters();
+#ifndef EL3_PAYLOAD_BASE
/* Region 0 set to no access by default */
tzc_configure_region0(TZC_REGION_S_NONE, 0);
@@ -73,6 +79,10 @@ void arm_tzc_setup(void)
ARM_DRAM2_BASE, ARM_DRAM2_END,
TZC_REGION_S_NONE,
PLAT_ARM_TZC_NS_DEV_ACCESS);
+#else
+ /* Allow secure access only to DRAM for EL3 payloads. */
+ tzc_configure_region0(TZC_REGION_S_RDWR, 0);
+#endif /* EL3_PAYLOAD_BASE */
/*
* Raise an exception if a NS device tries to access secure memory
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 2e423d96..6054f7a5 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -29,7 +29,11 @@
*/
#include <bl_common.h>
+#include <css_def.h>
#include <debug.h>
+#include <mmio.h>
+#include <plat_arm.h>
+#include <string.h>
#include "css_scp_bootloader.h"
/* Weak definition may be overridden in specific CSS based platform */
@@ -55,3 +59,38 @@ int bl2_plat_handle_bl30(image_info_t *bl30_image_info)
return ret;
}
+
+#ifdef EL3_PAYLOAD_BASE
+/*
+ * We need to override some of the platform functions when booting an EL3
+ * payload.
+ */
+
+static unsigned int scp_boot_config;
+
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+ arm_bl2_early_platform_setup(mem_layout);
+
+ /* Save SCP Boot config before it gets overwritten by BL30 loading */
+ scp_boot_config = mmio_read_32(SCP_BOOT_CFG_ADDR);
+ VERBOSE("BL2: Saved SCP Boot config = 0x%x\n", scp_boot_config);
+}
+
+void bl2_platform_setup(void)
+{
+ arm_bl2_platform_setup();
+
+ /*
+ * Before releasing the AP cores out of reset, the SCP writes some data
+ * at the beginning of the Trusted SRAM. It is is overwritten before
+ * reaching this function. We need to restore this data, as if the
+ * target had just come out of reset. This implies:
+ * - zeroing the first 128 bytes of Trusted SRAM;
+ * - restoring the SCP boot configuration.
+ */
+ VERBOSE("BL2: Restoring SCP reset data in Trusted SRAM\n");
+ memset((void *) ARM_TRUSTED_SRAM_BASE, 0, 128);
+ mmio_write_32(SCP_BOOT_CFG_ADDR, scp_boot_config);
+}
+#endif /* EL3_PAYLOAD_BASE */