diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2012-07-12 10:59:11 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2012-07-12 10:59:54 +0000 |
commit | e42c4db3a3de213f6a374dbdc7e75767dc3bfac2 (patch) | |
tree | 424122dfa789561090b8c5f0faaf00eefd8821d1 | |
parent | 702a9357897293e804d2ac7550227d0d07ed9fc9 (diff) |
target-arm: Implement TTBCR changes for LPAE
Implement the changes to the TTBCR register required for LPAE:
* many fewer bits should be RAZ/WI
* since TTBCR changes can result in a change of ASID, we must
flush the TLB on writes to it
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | target-arm/helper.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index 110858dde1..72b44b03aa 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -692,7 +692,20 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = { static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - value &= 7; + if (arm_feature(env, ARM_FEATURE_LPAE)) { + value &= ~((7 << 19) | (3 << 14) | (0xf << 3)); + /* With LPAE the TTBCR could result in a change of ASID + * via the TTBCR.A1 bit, so do a TLB flush. + */ + tlb_flush(env, 1); + } else { + value &= 7; + } + /* Note that we always calculate c2_mask and c2_base_mask, but + * they are only used for short-descriptor tables (ie if EAE is 0); + * for long-descriptor tables the TTBCR fields are used differently + * and the c2_mask and c2_base_mask values are meaningless. + */ env->cp15.c2_control = value; env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> value); env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> value); |