diff options
author | Thomas Hanson <thomas.hanson@linaro.org> | 2016-10-17 19:22:18 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-10-17 19:22:18 +0100 |
commit | 86fb3fa4ed5873b021a362ea26a021f4aeab1bb4 (patch) | |
tree | 324b6bd80a71a5b3a14a820ef4974874fef37333 /target-arm/helper.c | |
parent | 08426da7dd0a63835dcf3003e9a022c0d5678be7 (diff) |
target-arm: Infrastucture changes to enable handling of tagged address loading into PC
When capturing the current CPU state for the TB, extract the TBI0 and TBI1
values from the correct TCR for the current EL and then add them to the TB
flags field.
Then, at the start of code generation for the block, copy the TBI fields
into the DisasContext structure.
Signed-off-by: Thomas Hanson <thomas.hanson@linaro.org>
Message-id: 1476301853-15774-2-git-send-email-thomas.hanson@linaro.org
[PMM: drop useless 'extern' keyword on function prototypes;
provide CONFIG_USER_ONLY trivial versions of arm_regime_tbi[01]()]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r-- | target-arm/helper.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index 25f612d493..70e274221c 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -6720,6 +6720,52 @@ static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx) return &env->cp15.tcr_el[regime_el(env, mmu_idx)]; } +/* Returns TBI0 value for current regime el */ +uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + TCR *tcr; + uint32_t el; + + /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert + * a stage 1+2 mmu index into the appropriate stage 1 mmu index. + */ + if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) { + mmu_idx += ARMMMUIdx_S1NSE0; + } + + tcr = regime_tcr(env, mmu_idx); + el = regime_el(env, mmu_idx); + + if (el > 1) { + return extract64(tcr->raw_tcr, 20, 1); + } else { + return extract64(tcr->raw_tcr, 37, 1); + } +} + +/* Returns TBI1 value for current regime el */ +uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + TCR *tcr; + uint32_t el; + + /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert + * a stage 1+2 mmu index into the appropriate stage 1 mmu index. + */ + if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) { + mmu_idx += ARMMMUIdx_S1NSE0; + } + + tcr = regime_tcr(env, mmu_idx); + el = regime_el(env, mmu_idx); + + if (el > 1) { + return 0; + } else { + return extract64(tcr->raw_tcr, 38, 1); + } +} + /* Return the TTBR associated with this translation regime */ static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, int ttbrn) |