From patchwork Sat Feb 15 16:07:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 24694 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f200.google.com (mail-ob0-f200.google.com [209.85.214.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2FF62203BE for ; Sat, 15 Feb 2014 16:08:03 +0000 (UTC) Received: by mail-ob0-f200.google.com with SMTP id wo20sf51145406obc.7 for ; Sat, 15 Feb 2014 08:08:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=FLNwqEh6rJDwvsfP98a4NdqS2kC4BBCdXp6hnNKntAo=; b=ONI8ISGmWGrT5M5V9ZncKm3zjjzoRNgKCTiTWQh3p8ZUX9RZfZei8eiVuClf4MW2wv 4lkba2wnV01A6MiGdhd2CiWLiHvAjwJKze8addY58fuGv2dn66I31Je59PzTy5H9E2c5 APvY3tr+OiUS/YgrFVx+JRYmC8IETuC90NBOVC6NQpdGnZpo2VW23c/DBfZXH2rZWHFY /oUZb6i30CsGR6LEGfx7rCNGgp/8NSkN+bygF8ZHfl6mxeu2m/0d3AE/1OIyiJD0vdN4 TwxKRxYJfkSqmz7ITGmhbuVJ7d3/xtt9JQuYLtWydArisaONeRwY7LGXjiHB7FmgUO7K Wvgw== X-Gm-Message-State: ALoCoQkPLC//DUPf2DaAooxQbb9Xrd4+SySt43rDCW18V1ETSmeOwc6YqDEg4cdwz7u1UOMPqZGq X-Received: by 10.182.98.230 with SMTP id el6mr6078586obb.10.1392480482315; Sat, 15 Feb 2014 08:08:02 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.42.138 with SMTP id c10ls391964qga.63.gmail; Sat, 15 Feb 2014 08:08:02 -0800 (PST) X-Received: by 10.52.104.68 with SMTP id gc4mr8251043vdb.2.1392480482207; Sat, 15 Feb 2014 08:08:02 -0800 (PST) Received: from mail-vc0-f177.google.com (mail-vc0-f177.google.com [209.85.220.177]) by mx.google.com with ESMTPS id p9si2992165vdv.109.2014.02.15.08.08.02 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 15 Feb 2014 08:08:02 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.177 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.177; Received: by mail-vc0-f177.google.com with SMTP id if11so10087456vcb.22 for ; Sat, 15 Feb 2014 08:08:02 -0800 (PST) X-Received: by 10.52.168.39 with SMTP id zt7mr4726014vdb.42.1392480482104; Sat, 15 Feb 2014 08:08:02 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp25586vcz; Sat, 15 Feb 2014 08:08:01 -0800 (PST) X-Received: by 10.180.77.200 with SMTP id u8mr6583826wiw.48.1392480466215; Sat, 15 Feb 2014 08:07:46 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id s17si3865847wiv.58.2014.02.15.08.07.43 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sat, 15 Feb 2014 08:07:46 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::1 as permitted sender) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1WEhm2-0006gk-8m; Sat, 15 Feb 2014 16:07:26 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Alexander Graf , Michael Matz , Claudio Fontana , Dirk Mueller , Laurent Desnogues , kvmarm@lists.cs.columbia.edu, Richard Henderson , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Christoffer Dall , Will Newton , Peter Crosthwaite , Rob Herring Subject: [PATCH v3 30/31] target-arm: Fix VFP enables for AArch32 EL0 under AArch64 EL1 Date: Sat, 15 Feb 2014 16:07:23 +0000 Message-Id: <1392480444-25565-31-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1392480444-25565-1-git-send-email-peter.maydell@linaro.org> References: <1392480444-25565-1-git-send-email-peter.maydell@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.177 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , The current A32/T32 decoder bases its "is VFP/Neon enabled?" check on the FPSCR.EN bit. This is correct if EL1 is AArch32, but for an AArch64 EL1 the logic is different: it must act as if FPSCR.EN is always set. Instead, trapping must happen according to CPACR bits for cp10/cp11; these cover all of FP/Neon, including the FPSCR/FPSID/MVFR register accesses which FPSCR.EN does not affect. Add support for CPACR checks (which are also required for ARMv7, but were unimplemented because Linux happens not to use them) and make sure they generate exceptions with the correct syndrome. We actually return incorrect syndrome information for cases where FP is disabled but the specific instruction bit pattern is unallocated: strictly these should be the Uncategorized exception, not a "SIMD disabled" exception. This should be mostly harmless, and the structure of the A32/T32 VFP/Neon decoder makes it painful to put the 'FP disabled?' checks in the right places. Signed-off-by: Peter Maydell --- target-arm/cpu.h | 10 +++++++++- target-arm/translate.c | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 6b7b1d0..085529f 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -1269,6 +1269,8 @@ static inline int cpu_mmu_index (CPUARMState *env) #define ARM_TBFLAG_CONDEXEC_MASK (0xff << ARM_TBFLAG_CONDEXEC_SHIFT) #define ARM_TBFLAG_BSWAP_CODE_SHIFT 16 #define ARM_TBFLAG_BSWAP_CODE_MASK (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT) +#define ARM_TBFLAG_CPACR_FPEN_SHIFT 17 +#define ARM_TBFLAG_CPACR_FPEN_MASK (1 << ARM_TBFLAG_CPACR_FPEN_SHIFT) /* Bit usage when in AArch64 state */ #define ARM_TBFLAG_AA64_EL_SHIFT 0 @@ -1293,6 +1295,8 @@ static inline int cpu_mmu_index (CPUARMState *env) (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT) #define ARM_TBFLAG_BSWAP_CODE(F) \ (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT) +#define ARM_TBFLAG_CPACR_FPEN(F) \ + (((F) & ARM_TBFLAG_CPACR_FPEN_MASK) >> ARM_TBFLAG_CPACR_FPEN_SHIFT) #define ARM_TBFLAG_AA64_EL(F) \ (((F) & ARM_TBFLAG_AA64_EL_MASK) >> ARM_TBFLAG_AA64_EL_SHIFT) #define ARM_TBFLAG_AA64_FPEN(F) \ @@ -1326,9 +1330,13 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, if (privmode) { *flags |= ARM_TBFLAG_PRIV_MASK; } - if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) { + if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30) + || arm_el_is_aa64(env, 1)) { *flags |= ARM_TBFLAG_VFPEN_MASK; } + if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) { + *flags |= ARM_TBFLAG_CPACR_FPEN_MASK; + } } *cs_base = 0; diff --git a/target-arm/translate.c b/target-arm/translate.c index 30eafc3..a15c237 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -2951,6 +2951,12 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) if (!arm_feature(env, ARM_FEATURE_VFP)) return 1; + if (!s->cpacr_fpen) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb)); + return 0; + } + if (!s->vfp_enabled) { /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */ if ((insn & 0x0fe00fff) != 0x0ee00a10) @@ -4228,6 +4234,12 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn) TCGv_i32 tmp2; TCGv_i64 tmp64; + if (!s->cpacr_fpen) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb)); + return 0; + } + if (!s->vfp_enabled) return 1; VFP_DREG_D(rd, insn); @@ -4950,6 +4962,12 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5; TCGv_i64 tmp64; + if (!s->cpacr_fpen) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb)); + return 0; + } + if (!s->vfp_enabled) return 1; q = (insn & (1 << 6)) != 0; @@ -10660,6 +10678,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, #if !defined(CONFIG_USER_ONLY) dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0); #endif + dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags); dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags); dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags); dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);