diff options
author | Vikram Kanigiri <vikram.kanigiri@arm.com> | 2014-07-15 16:49:22 +0100 |
---|---|---|
committer | Vikram Kanigiri <vikram.kanigiri@arm.com> | 2014-08-01 09:48:07 +0100 |
commit | faaa2e7644ec6101de0e7d4f35b9dd2999f110a7 (patch) | |
tree | 8570f7a45b30ac70b8f6cdd326d8bf71c1666033 /services/spd | |
parent | 50e27dadbcc4b442f1c5ceb343c6d55783afed54 (diff) |
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
Diffstat (limited to 'services/spd')
-rw-r--r-- | services/spd/tspd/tspd_main.c | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c index b2c36152..22f302a2 100644 --- a/services/spd/tspd/tspd_main.c +++ b/services/spd/tspd/tspd_main.c @@ -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 |