mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2024-12-02 15:47:10 +00:00
Support asynchronous method for BL3-2 initialization
This patch adds support for BL3-2 initialization by asynchronous method where BL3-1 transfers control to BL3-2 using world switch. After BL3-2 initialization, it transfers control to BL3-3 via SPD service handler. The SPD service handler initializes the CPU context to BL3-3 entrypoint depending on the return function indentifier from TSP initialization. Fixes ARM-software/TF-issues#184 Change-Id: I7b135c2ceeb356d3bb5b6a287932e96ac67c7a34
This commit is contained in:
parent
50e27dadbc
commit
faaa2e7644
@ -51,7 +51,7 @@ static int32_t (*bl32_init)(void);
|
||||
* Variable to indicate whether next image to execute after BL31 is BL33
|
||||
* (non-secure & default) or BL32 (secure).
|
||||
******************************************************************************/
|
||||
static uint32_t next_image_type;
|
||||
static uint32_t next_image_type = NON_SECURE;
|
||||
|
||||
/*******************************************************************************
|
||||
* Simple function to initialise all BL31 helper libraries.
|
||||
@ -89,9 +89,6 @@ void bl31_main(void)
|
||||
/* Clean caches before re-entering normal world */
|
||||
dcsw_op_all(DCCSW);
|
||||
|
||||
/* By default run the non-secure BL3-3 image next */
|
||||
next_image_type = NON_SECURE;
|
||||
|
||||
/*
|
||||
* All the cold boot actions on the primary cpu are done. We now need to
|
||||
* decide which is the next image (BL32 or BL33) and how to execute it.
|
||||
|
@ -39,6 +39,14 @@ BL32_SOURCES += bl32/tsp/tsp_main.c \
|
||||
|
||||
BL32_LINKERFILE := bl32/tsp/tsp.ld.S
|
||||
|
||||
# This flag determines if the TSPD initializes BL3-2 in tspd_init() (synchronous
|
||||
# method) or configures BL3-1 to pass control to BL3-2 instead of BL3-3
|
||||
# (asynchronous method).
|
||||
TSP_INIT_ASYNC := 0
|
||||
|
||||
$(eval $(call assert_boolean,TSP_INIT_ASYNC))
|
||||
$(eval $(call add_define,TSP_INIT_ASYNC))
|
||||
|
||||
# Include the platform-specific TSP Makefile
|
||||
# If no platform-specific TSP Makefile exists, it means TSP is not supported
|
||||
# on this platform.
|
||||
|
@ -811,10 +811,10 @@ and is registered using the `bl31_register_bl32_init()` function.
|
||||
Trusted Firmware supports two approaches for the SPD to pass control to BL3-2
|
||||
before returning through EL3 and running the non-trusted firmware (BL3-3):
|
||||
|
||||
1. In the BL3-2 initialization function, set up a secure context (see below
|
||||
for more details of CPU context support) for this CPU and use
|
||||
`bl31_set_next_image_type()` to request that the exit from `bl31_main()` is
|
||||
to the BL3-2 entrypoint in Secure-EL1.
|
||||
1. In the BL3-2 setup function, use `bl31_set_next_image_type()` to
|
||||
request that the exit from `bl31_main()` is to the BL3-2 entrypoint in
|
||||
Secure-EL1. BL3-1 will exit to BL3-2 using the asynchronous method by
|
||||
calling bl31_prepare_next_image_entry() and el3_exit().
|
||||
|
||||
When the BL3-2 has completed initialization at Secure-EL1, it returns to
|
||||
BL3-1 by issuing an SMC, using a Function ID allocated to the SPD. On
|
||||
@ -824,7 +824,8 @@ before returning through EL3 and running the non-trusted firmware (BL3-3):
|
||||
the normal world firmware BL3-3. On return from the handler the framework
|
||||
will exit to EL2 and run BL3-3.
|
||||
|
||||
2. In the BL3-2 initialization function, use an SPD-defined mechanism to
|
||||
2. The BL3-2 setup function registers a initialization function using
|
||||
`bl31_register_bl32_init()` which provides a SPD-defined mechanism to
|
||||
invoke a 'world-switch synchronous call' to Secure-EL1 to run the BL3-2
|
||||
entrypoint.
|
||||
NOTE: The Test SPD service included with the Trusted Firmware provides one
|
||||
|
@ -186,6 +186,13 @@ performed.
|
||||
value of `DEBUG` - i.e. by default this is only enabled for a debug
|
||||
build of the firmware.
|
||||
|
||||
* `TSP_INIT_ASYNC`: Choose BL3-2 initialization method as asynchronous or
|
||||
synchronous, e.g. "(see "Initializing a BL3-2 Image" section in [Firmware
|
||||
Design])". It can take the value 0 (BL3-2 is initialized using
|
||||
synchronous method) or 1 (BL3-2 is initialized using asynchronous method).
|
||||
Default is 0.
|
||||
|
||||
|
||||
### Creating a Firmware Image Package
|
||||
|
||||
FIPs are automatically created as part of the build instructions described in
|
||||
|
@ -181,12 +181,15 @@ int32_t tspd_setup(void)
|
||||
tsp_ep_info->pc,
|
||||
&tspd_sp_context[linear_id]);
|
||||
|
||||
#if TSP_INIT_ASYNC
|
||||
bl31_set_next_image_type(SECURE);
|
||||
#else
|
||||
/*
|
||||
* All TSPD initialization done. Now register our init function with
|
||||
* BL31 for deferred invocation
|
||||
*/
|
||||
bl31_register_bl32_init(&tspd_init);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -202,10 +205,10 @@ int32_t tspd_setup(void)
|
||||
int32_t tspd_init(void)
|
||||
{
|
||||
uint64_t mpidr = read_mpidr();
|
||||
uint32_t linear_id = platform_get_core_pos(mpidr), flags;
|
||||
uint64_t rc;
|
||||
uint32_t linear_id = platform_get_core_pos(mpidr);
|
||||
tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
|
||||
entry_point_info_t *tsp_entry_point;
|
||||
uint64_t rc;
|
||||
|
||||
/*
|
||||
* Get information about the Secure Payload (BL32) image. Its
|
||||
@ -217,32 +220,11 @@ int32_t tspd_init(void)
|
||||
cm_init_context(mpidr, tsp_entry_point);
|
||||
|
||||
/*
|
||||
* Arrange for an entry into the test secure payload. We expect an array
|
||||
* of vectors in return
|
||||
* Arrange for an entry into the test secure payload. It will be
|
||||
* returned via TSP_ENTRY_DONE case
|
||||
*/
|
||||
rc = tspd_synchronous_sp_entry(tsp_ctx);
|
||||
assert(rc != 0);
|
||||
if (rc) {
|
||||
set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON);
|
||||
|
||||
/*
|
||||
* TSP has been successfully initialized. Register power
|
||||
* managemnt hooks with PSCI
|
||||
*/
|
||||
psci_register_spd_pm_hook(&tspd_pm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register an interrupt handler for S-EL1 interrupts when generated
|
||||
* during code executing in the non-secure state.
|
||||
*/
|
||||
flags = 0;
|
||||
set_interrupt_rm_flag(flags, NON_SECURE);
|
||||
rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
|
||||
tspd_sel1_interrupt_handler,
|
||||
flags);
|
||||
if (rc)
|
||||
panic();
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -269,6 +251,10 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||
unsigned long mpidr = read_mpidr();
|
||||
uint32_t linear_id = platform_get_core_pos(mpidr), ns;
|
||||
tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
|
||||
uint64_t rc;
|
||||
#if TSP_INIT_ASYNC
|
||||
entry_point_info_t *next_image_info;
|
||||
#endif
|
||||
|
||||
/* Determine which security state this SMC originated from */
|
||||
ns = is_caller_non_secure(flags);
|
||||
@ -382,6 +368,45 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||
assert(tsp_vectors == NULL);
|
||||
tsp_vectors = (tsp_vectors_t *) x1;
|
||||
|
||||
if (tsp_vectors) {
|
||||
set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON);
|
||||
|
||||
/*
|
||||
* TSP has been successfully initialized. Register power
|
||||
* managemnt hooks with PSCI
|
||||
*/
|
||||
psci_register_spd_pm_hook(&tspd_pm);
|
||||
|
||||
/*
|
||||
* Register an interrupt handler for S-EL1 interrupts
|
||||
* when generated during code executing in the
|
||||
* non-secure state.
|
||||
*/
|
||||
flags = 0;
|
||||
set_interrupt_rm_flag(flags, NON_SECURE);
|
||||
rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
|
||||
tspd_sel1_interrupt_handler,
|
||||
flags);
|
||||
if (rc)
|
||||
panic();
|
||||
}
|
||||
|
||||
|
||||
#if TSP_INIT_ASYNC
|
||||
/* Save the Secure EL1 system register context */
|
||||
assert(cm_get_context(SECURE) == &tsp_ctx->cpu_ctx);
|
||||
cm_el1_sysregs_context_save(SECURE);
|
||||
|
||||
/* Program EL3 registers to enable entry into the next EL */
|
||||
next_image_info = bl31_plat_get_next_image_ep_info(NON_SECURE);
|
||||
assert(next_image_info);
|
||||
assert(NON_SECURE ==
|
||||
GET_SECURITY_STATE(next_image_info->h.attr));
|
||||
|
||||
cm_init_context(read_mpidr_el1(), next_image_info);
|
||||
cm_prepare_el3_exit(NON_SECURE);
|
||||
SMC_RET0(cm_get_context(NON_SECURE));
|
||||
#else
|
||||
/*
|
||||
* SP reports completion. The SPD must have initiated
|
||||
* the original request through a synchronous entry
|
||||
@ -389,6 +414,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||
* context.
|
||||
*/
|
||||
tspd_synchronous_sp_exit(tsp_ctx, x1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These function IDs is used only by the SP to indicate it has
|
||||
|
Loading…
Reference in New Issue
Block a user