Re: [Qemu-devel] [PATCH v1 1/2] target-arm: Move the regime_xxx helpers
On Fri, Jun 30, 2017 at 6:45 AM, Edgar E. Iglesiaswrote: > From: "Edgar E. Iglesias" > > Move the regime_xxx helpers in preparation for future code > that will reuse them. > > No functional change. > > Signed-off-by: Edgar E. Iglesias Reviewed-by: Alistair Francis Thanks, Alistair > --- > target/arm/helper.c | 404 > ++-- > 1 file changed, 202 insertions(+), 202 deletions(-) > > diff --git a/target/arm/helper.c b/target/arm/helper.c > index 2594faa..fd1027e 100644 > --- a/target/arm/helper.c > +++ b/target/arm/helper.c > @@ -35,6 +35,208 @@ static bool get_phys_addr_lpae(CPUARMState *env, > target_ulong address, > #define PMCRD 0x8 > #define PMCRC 0x4 > #define PMCRE 0x1 > + > +/* Return the exception level which controls this address translation regime > */ > +static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) > +{ > +switch (mmu_idx) { > +case ARMMMUIdx_S2NS: > +case ARMMMUIdx_S1E2: > +return 2; > +case ARMMMUIdx_S1E3: > +return 3; > +case ARMMMUIdx_S1SE0: > +return arm_el_is_aa64(env, 3) ? 1 : 3; > +case ARMMMUIdx_S1SE1: > +case ARMMMUIdx_S1NSE0: > +case ARMMMUIdx_S1NSE1: > +case ARMMMUIdx_MPriv: > +case ARMMMUIdx_MNegPri: > +case ARMMMUIdx_MUser: > +return 1; > +default: > +g_assert_not_reached(); > +} > +} > + > +/* Return true if this address translation regime is secure */ > +static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) > +{ > +switch (mmu_idx) { > +case ARMMMUIdx_S12NSE0: > +case ARMMMUIdx_S12NSE1: > +case ARMMMUIdx_S1NSE0: > +case ARMMMUIdx_S1NSE1: > +case ARMMMUIdx_S1E2: > +case ARMMMUIdx_S2NS: > +case ARMMMUIdx_MPriv: > +case ARMMMUIdx_MNegPri: > +case ARMMMUIdx_MUser: > +return false; > +case ARMMMUIdx_S1E3: > +case ARMMMUIdx_S1SE0: > +case ARMMMUIdx_S1SE1: > +return true; > +default: > +g_assert_not_reached(); > +} > +} > + > +/* Return the SCTLR value which controls this address translation regime */ > +static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx) > +{ > +return env->cp15.sctlr_el[regime_el(env, mmu_idx)]; > +} > + > +/* Return true if the specified stage of address translation is disabled */ > +static inline bool regime_translation_disabled(CPUARMState *env, > + ARMMMUIdx mmu_idx) > +{ > +if (arm_feature(env, ARM_FEATURE_M)) { > +switch (env->v7m.mpu_ctrl & > +(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) > { > +case R_V7M_MPU_CTRL_ENABLE_MASK: > +/* Enabled, but not for HardFault and NMI */ > +return mmu_idx == ARMMMUIdx_MNegPri; > +case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK: > +/* Enabled for all cases */ > +return false; > +case 0: > +default: > +/* HFNMIENA set and ENABLE clear is UNPREDICTABLE, but > + * we warned about that in armv7m_nvic.c when the guest set it. > + */ > +return true; > +} > +} > + > +if (mmu_idx == ARMMMUIdx_S2NS) { > +return (env->cp15.hcr_el2 & HCR_VM) == 0; > +} > +return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0; > +} > + > +static inline bool regime_translation_big_endian(CPUARMState *env, > + ARMMMUIdx mmu_idx) > +{ > +return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0; > +} > + > +/* Return the TCR controlling this translation regime */ > +static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx) > +{ > +if (mmu_idx == ARMMMUIdx_S2NS) { > +return >cp15.vtcr_el2; > +} > +return >cp15.tcr_el[regime_el(env, mmu_idx)]; > +} > + > +/* Convert a possible stage1+2 MMU index into the appropriate > + * stage 1 MMU index > + */ > +static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx) > +{ > +if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) { > +mmu_idx += (ARMMMUIdx_S1NSE0 - ARMMMUIdx_S12NSE0); > +} > +return 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. > + */ > +mmu_idx = stage_1_mmu_idx(mmu_idx); > + > +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
[Qemu-devel] [PATCH v1 1/2] target-arm: Move the regime_xxx helpers
From: "Edgar E. Iglesias"Move the regime_xxx helpers in preparation for future code that will reuse them. No functional change. Signed-off-by: Edgar E. Iglesias --- target/arm/helper.c | 404 ++-- 1 file changed, 202 insertions(+), 202 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 2594faa..fd1027e 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -35,6 +35,208 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, #define PMCRD 0x8 #define PMCRC 0x4 #define PMCRE 0x1 + +/* Return the exception level which controls this address translation regime */ +static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) +{ +switch (mmu_idx) { +case ARMMMUIdx_S2NS: +case ARMMMUIdx_S1E2: +return 2; +case ARMMMUIdx_S1E3: +return 3; +case ARMMMUIdx_S1SE0: +return arm_el_is_aa64(env, 3) ? 1 : 3; +case ARMMMUIdx_S1SE1: +case ARMMMUIdx_S1NSE0: +case ARMMMUIdx_S1NSE1: +case ARMMMUIdx_MPriv: +case ARMMMUIdx_MNegPri: +case ARMMMUIdx_MUser: +return 1; +default: +g_assert_not_reached(); +} +} + +/* Return true if this address translation regime is secure */ +static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) +{ +switch (mmu_idx) { +case ARMMMUIdx_S12NSE0: +case ARMMMUIdx_S12NSE1: +case ARMMMUIdx_S1NSE0: +case ARMMMUIdx_S1NSE1: +case ARMMMUIdx_S1E2: +case ARMMMUIdx_S2NS: +case ARMMMUIdx_MPriv: +case ARMMMUIdx_MNegPri: +case ARMMMUIdx_MUser: +return false; +case ARMMMUIdx_S1E3: +case ARMMMUIdx_S1SE0: +case ARMMMUIdx_S1SE1: +return true; +default: +g_assert_not_reached(); +} +} + +/* Return the SCTLR value which controls this address translation regime */ +static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx) +{ +return env->cp15.sctlr_el[regime_el(env, mmu_idx)]; +} + +/* Return true if the specified stage of address translation is disabled */ +static inline bool regime_translation_disabled(CPUARMState *env, + ARMMMUIdx mmu_idx) +{ +if (arm_feature(env, ARM_FEATURE_M)) { +switch (env->v7m.mpu_ctrl & +(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) { +case R_V7M_MPU_CTRL_ENABLE_MASK: +/* Enabled, but not for HardFault and NMI */ +return mmu_idx == ARMMMUIdx_MNegPri; +case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK: +/* Enabled for all cases */ +return false; +case 0: +default: +/* HFNMIENA set and ENABLE clear is UNPREDICTABLE, but + * we warned about that in armv7m_nvic.c when the guest set it. + */ +return true; +} +} + +if (mmu_idx == ARMMMUIdx_S2NS) { +return (env->cp15.hcr_el2 & HCR_VM) == 0; +} +return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0; +} + +static inline bool regime_translation_big_endian(CPUARMState *env, + ARMMMUIdx mmu_idx) +{ +return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0; +} + +/* Return the TCR controlling this translation regime */ +static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx) +{ +if (mmu_idx == ARMMMUIdx_S2NS) { +return >cp15.vtcr_el2; +} +return >cp15.tcr_el[regime_el(env, mmu_idx)]; +} + +/* Convert a possible stage1+2 MMU index into the appropriate + * stage 1 MMU index + */ +static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx) +{ +if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) { +mmu_idx += (ARMMMUIdx_S1NSE0 - ARMMMUIdx_S12NSE0); +} +return 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. + */ +mmu_idx = stage_1_mmu_idx(mmu_idx); + +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. + */ +mmu_idx = stage_1_mmu_idx(mmu_idx); + +tcr = regime_tcr(env, mmu_idx); +el = regime_el(env, mmu_idx); + +if (el > 1) { +return 0; +} else { +return extract64(tcr->raw_tcr,