From patchwork Mon Oct 10 18:11:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Hanson X-Patchwork-Id: 680525 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3st7cK10qcz9rxv for ; Tue, 11 Oct 2016 05:16:33 +1100 (AEDT) Received: from localhost ([::1]:51874 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btf7m-00059i-35 for incoming@patchwork.ozlabs.org; Mon, 10 Oct 2016 14:16:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49281) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btf3O-0001o3-0W for qemu-devel@nongnu.org; Mon, 10 Oct 2016 14:11:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1btf3J-0003ti-Ox for qemu-devel@nongnu.org; Mon, 10 Oct 2016 14:11:56 -0400 Received: from g4t3427.houston.hpe.com ([15.241.140.73]:7269) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btf3J-0003qm-GK for qemu-devel@nongnu.org; Mon, 10 Oct 2016 14:11:53 -0400 Received: from TomH-Z-Workstation.americas.hpqcorp.net (tomh-z-workstation.americas.hpqcorp.net [16.78.178.129]) by g4t3427.houston.hpe.com (Postfix) with ESMTP id 7769550; Mon, 10 Oct 2016 18:11:48 +0000 (UTC) From: Thomas Hanson To: qemu-devel@nongnu.org Date: Mon, 10 Oct 2016 12:11:14 -0600 Message-Id: <1476123077-35698-2-git-send-email-thomas.hanson@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1476123077-35698-1-git-send-email-thomas.hanson@linaro.org> References: <1476123077-35698-1-git-send-email-thomas.hanson@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 15.241.140.73 Subject: [Qemu-devel] [PATCH v2 1/4] target-arm: Infrastucture changes to enable handling of tagged address loading into PC X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: grant.likely@hpe.com, peter.maydell@linaro.org, thomas.hanson@linaro.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 --- target-arm/cpu.h | 39 +++++++++++++++++++++++++++++++++++++-- target-arm/helper.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ target-arm/translate-a64.c | 2 ++ target-arm/translate.h | 2 ++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 76d824d..699e6e5 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -2191,7 +2191,11 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env) #define ARM_TBFLAG_BE_DATA_SHIFT 20 #define ARM_TBFLAG_BE_DATA_MASK (1 << ARM_TBFLAG_BE_DATA_SHIFT) -/* Bit usage when in AArch64 state: currently we have no A64 specific bits */ +/* Bit usage when in AArch64 state */ +#define ARM_TBFLAG_TBI0_SHIFT 0 /* TBI0 for EL0/1 or TBI for EL2/3 */ +#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT) +#define ARM_TBFLAG_TBI1_SHIFT 1 /* TBI1 for EL0/1 */ +#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT) /* some convenience accessor macros */ #define ARM_TBFLAG_AARCH64_STATE(F) \ @@ -2222,6 +2226,10 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env) (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT) #define ARM_TBFLAG_BE_DATA(F) \ (((F) & ARM_TBFLAG_BE_DATA_MASK) >> ARM_TBFLAG_BE_DATA_SHIFT) +#define ARM_TBFLAG_TBI0(F) \ + (((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT) +#define ARM_TBFLAG_TBI1(F) \ + (((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT) static inline bool bswap_code(bool sctlr_b) { @@ -2319,12 +2327,38 @@ static inline bool arm_cpu_bswap_data(CPUARMState *env) } #endif +/** + * arm_regime_tbi0: + * @env: CPUARMState + * @mmu_idx: MMU index indicating required translation regime + * + * Extracts the TBI0 value from the appropriate TCR for the current EL + * + * Returns: the TBI0 value. + */ +extern uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx); + +/** + * arm_regime_tbi1: + * @env: CPUARMState + * @mmu_idx: MMU index indicating required translation regime + * + * Extracts the TBI1 value from the appropriate TCR for the current EL + * + * Returns: the TBI1 value. + */ +extern uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx); + static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, target_ulong *cs_base, uint32_t *flags) { + ARMMMUIdx mmu_idx = cpu_mmu_index(env, false); if (is_a64(env)) { *pc = env->pc; *flags = ARM_TBFLAG_AARCH64_STATE_MASK; + /* Get control bits for tagged addresses */ + *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT); + *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT); } else { *pc = env->regs[15]; *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT) @@ -2343,7 +2377,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, << ARM_TBFLAG_XSCALE_CPAR_SHIFT); } - *flags |= (cpu_mmu_index(env, false) << ARM_TBFLAG_MMUIDX_SHIFT); + *flags |= (mmu_idx << ARM_TBFLAG_MMUIDX_SHIFT); + /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine * states defined in the ARM ARM for software singlestep: * SS_ACTIVE PSTATE.SS State diff --git a/target-arm/helper.c b/target-arm/helper.c index 25f612d..70e2742 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) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 307e281..3b15d2c 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -11175,6 +11175,8 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb) dc->condexec_mask = 0; dc->condexec_cond = 0; dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags); + dc->tbi0 = ARM_TBFLAG_TBI0(tb->flags); + dc->tbi1 = ARM_TBFLAG_TBI1(tb->flags); dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx); #if !defined(CONFIG_USER_ONLY) dc->user = (dc->current_el == 0); diff --git a/target-arm/translate.h b/target-arm/translate.h index dbd7ac8..a53f25a 100644 --- a/target-arm/translate.h +++ b/target-arm/translate.h @@ -22,6 +22,8 @@ typedef struct DisasContext { int user; #endif ARMMMUIdx mmu_idx; /* MMU index to use for normal loads/stores */ + bool tbi0; /* TBI0 for EL0/1 or TBI for EL2/3 */ + bool tbi1; /* TBI1 for EL0/1, not used for EL2/3 */ bool ns; /* Use non-secure CPREG bank on access */ int fp_excp_el; /* FP exception EL or 0 if enabled */ /* Flag indicating that exceptions from secure mode are routed to EL3. */