Merge pull request #1436 from antonio-nino-diaz-arm/an/spm-sync
SPM: Allow entering the SP without needing a SMC
This commit is contained in:
commit
ab676e00d3
|
@ -74,6 +74,9 @@ uint64_t spm_smc_handler(uint32_t smc_fid,
|
||||||
void *handle,
|
void *handle,
|
||||||
uint64_t flags);
|
uint64_t flags);
|
||||||
|
|
||||||
|
/* Helper to enter a Secure Partition */
|
||||||
|
uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3);
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* __SPM_SVC_H__ */
|
#endif /* __SPM_SVC_H__ */
|
||||||
|
|
|
@ -180,6 +180,35 @@ int32_t spm_setup(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Function to perform a call to a Secure Partition.
|
||||||
|
******************************************************************************/
|
||||||
|
uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
|
||||||
|
{
|
||||||
|
uint64_t rc;
|
||||||
|
sp_context_t *sp_ptr = &sp_ctx;
|
||||||
|
|
||||||
|
/* Wait until the Secure Partition is idle and set it to busy. */
|
||||||
|
sp_state_wait_switch(sp_ptr, SP_STATE_IDLE, SP_STATE_BUSY);
|
||||||
|
|
||||||
|
/* Set values for registers on SP entry */
|
||||||
|
cpu_context_t *cpu_ctx = &(sp_ptr->cpu_ctx);
|
||||||
|
|
||||||
|
write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X0, smc_fid);
|
||||||
|
write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X1, x1);
|
||||||
|
write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X2, x2);
|
||||||
|
write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3, x3);
|
||||||
|
|
||||||
|
/* Jump to the Secure Partition. */
|
||||||
|
rc = spm_sp_synchronous_entry(sp_ptr);
|
||||||
|
|
||||||
|
/* Flag Secure Partition as idle. */
|
||||||
|
assert(sp_ptr->state == SP_STATE_BUSY);
|
||||||
|
sp_state_set(sp_ptr, SP_STATE_IDLE);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* MM_COMMUNICATE handler
|
* MM_COMMUNICATE handler
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -188,7 +217,6 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
|
||||||
uint64_t comm_size_address, void *handle)
|
uint64_t comm_size_address, void *handle)
|
||||||
{
|
{
|
||||||
uint64_t rc;
|
uint64_t rc;
|
||||||
sp_context_t *ctx = &sp_ctx;
|
|
||||||
|
|
||||||
/* Cookie. Reserved for future use. It must be zero. */
|
/* Cookie. Reserved for future use. It must be zero. */
|
||||||
if (mm_cookie != 0U) {
|
if (mm_cookie != 0U) {
|
||||||
|
@ -208,23 +236,8 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
|
||||||
/* Save the Normal world context */
|
/* Save the Normal world context */
|
||||||
cm_el1_sysregs_context_save(NON_SECURE);
|
cm_el1_sysregs_context_save(NON_SECURE);
|
||||||
|
|
||||||
/* Wait until the Secure Partition is idle and set it to busy. */
|
rc = spm_sp_call(smc_fid, comm_buffer_address, comm_size_address,
|
||||||
sp_state_wait_switch(ctx, SP_STATE_IDLE, SP_STATE_BUSY);
|
plat_my_core_pos());
|
||||||
|
|
||||||
/* Set values for registers on SP entry */
|
|
||||||
cpu_context_t *cpu_ctx = &(ctx->cpu_ctx);
|
|
||||||
|
|
||||||
write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X0, smc_fid);
|
|
||||||
write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X1, comm_buffer_address);
|
|
||||||
write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X2, comm_size_address);
|
|
||||||
write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3, plat_my_core_pos());
|
|
||||||
|
|
||||||
/* Jump to the Secure Partition. */
|
|
||||||
rc = spm_sp_synchronous_entry(ctx);
|
|
||||||
|
|
||||||
/* Flag Secure Partition as idle. */
|
|
||||||
assert(ctx->state == SP_STATE_BUSY);
|
|
||||||
sp_state_set(ctx, SP_STATE_IDLE);
|
|
||||||
|
|
||||||
/* Restore non-secure state */
|
/* Restore non-secure state */
|
||||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||||
|
|
Loading…
Reference in New Issue