With FEAT_UINJ, allow PSTATE.UINJ to be set from aa64 and aa32 modes. Read the value back for SPSR_ELx from aa32 mode.
Reviewed-by: Peter Maydell <[email protected]> Signed-off-by: Richard Henderson <[email protected]> --- target/arm/internals.h | 3 +++ target/arm/helper.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index 843e12487ec..c41fa5225c7 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1392,6 +1392,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) if (isar_feature_aa64_nmi(id)) { valid |= PSTATE_ALLINT; } + if (isar_feature_aa64_uinj(id)) { + valid |= PSTATE_UINJ; + } return valid; } diff --git a/target/arm/helper.c b/target/arm/helper.c index 2034f1d1f17..ee48442383c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -9385,8 +9385,9 @@ uint64_t cpsr_read_for_spsr_elx(CPUARMState *env) ret &= ~CPSR_DIT; ret |= PSTATE_DIT; } - /* Merge PSTATE.SS into SPSR_ELx */ - ret |= env->pstate & PSTATE_SS; + + /* Merge PSTATE.{SS,UINJ} into SPSR_ELx */ + ret |= env->pstate & (PSTATE_SS | PSTATE_UINJ); return ret; } @@ -9395,6 +9396,14 @@ void cpsr_write_from_spsr_elx(CPUARMState *env, uint64_t val) { uint32_t mask; + /* Save SPSR_ELx.UINJ into PSTATE. */ + if (unlikely(val & PSTATE_UINJ) + && arm_feature(env, ARM_FEATURE_AARCH64) + && cpu_isar_feature(aa64_uinj, env_archcpu(env))) { + env->pstate |= PSTATE_UINJ; + val &= ~PSTATE_UINJ; + } + /* Save SPSR_ELx.SS into PSTATE. */ env->pstate = (env->pstate & ~PSTATE_SS) | (val & PSTATE_SS); val &= ~PSTATE_SS; -- 2.53.0
