diff options
author | Aijun Sun <aijun.sun@spreadtrum.com> | 2017-09-19 16:52:08 +0800 |
---|---|---|
committer | Aijun Sun <aijun.sun@spreadtrum.com> | 2017-09-19 19:20:48 +0800 |
commit | ab609e1a76399969f8318360ea3fff30687c9638 (patch) | |
tree | 595f29d23a824aed9ab12025102030af753905ad /services/spd | |
parent | 1cde9b94fad9b778688cfec478b6d1b9f162b146 (diff) |
trusty: save/restore FPU registers in world switch
Currently, Trusty OS/LK implemented FPU context switch in internal
thread switch but does not implement the proper mechanism for world
switch. This commit just simply saves/restores FPU registes in world
switch to prevent FPU context from being currupted when Trusty OS uses
VFP in its applications.
It should be noted that the macro *CTX_INCLUDE_FPREGS* must be defined
in trusty.mk if Trusty OS uses VFP
Signed-off-by: Aijun Sun <aijun.sun@spreadtrum.com>
Diffstat (limited to 'services/spd')
-rw-r--r-- | services/spd/trusty/trusty.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index e386f71c..ecbcfaea 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -99,6 +99,16 @@ static struct args trusty_context_switch(uint32_t security_state, uint64_t r0, ret.r1 = r1; ret.r0 = r0; + /* + * To avoid the additional overhead in PSCI flow, skip FP context + * saving/restoring in case of CPU suspend and resume, asssuming that + * when it's needed the PSCI caller has preserved FP context before + * going here. + */ +#if CTX_INCLUDE_FPREGS + if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME) + fpregs_context_save(get_fpregs_ctx(cm_get_context(security_state))); +#endif cm_el1_sysregs_context_save(security_state); ctx->saved_security_state = security_state; @@ -107,6 +117,11 @@ static struct args trusty_context_switch(uint32_t security_state, uint64_t r0, assert(ctx->saved_security_state == !security_state); cm_el1_sysregs_context_restore(security_state); +#if CTX_INCLUDE_FPREGS + if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME) + fpregs_context_restore(get_fpregs_ctx(cm_get_context(security_state))); +#endif + cm_set_next_eret_context(security_state); return ret; |