From patchwork Mon Jun 17 14:33:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 167046 Delivered-To: patch@linaro.org Received: by 2002:ac9:6410:0:0:0:0:0 with SMTP id r16csp1096282ock; Mon, 17 Jun 2019 07:49:40 -0700 (PDT) X-Google-Smtp-Source: APXvYqxnJHRC8/D04nyfCwXgsBLDdgwJXhNEAeK8ngRiXoM34BeDCR0G+BIHXp5rxHnIsriBpWUN X-Received: by 2002:a17:906:3948:: with SMTP id g8mr64370939eje.168.1560782980836; Mon, 17 Jun 2019 07:49:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560782980; cv=none; d=google.com; s=arc-20160816; b=JuAMmsXtdGYEDZ4w0F37E+69CeBPXGbgJVKVI2v6K0helfkBxqWsnepV+Md904JMuM s9hyhm+xoGJ8q8xAjw7J/pXCsQ5frumtGyGa7gbyZd06Pq9043rKxSJmT/kJBSIMueD+ 480qa16YOWOchbDNbrNExIjvB4xmMy3MqVoOX30jGhWlk+GVfq/kfq1Y235n/vvOLzA7 mkcj5r93l4P/IVTtyYkLXVZ7O9AYA2XrQuZcIUQ0dq8n+yTHszC6zvuXo1GphvvhpAmH +vVSnTx5PT8PjEw0g3L7tQ00Y2kovxQ5g67mTTYKuluM/hJtkjiqps3x1OEbq0Rhd6GH wyZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=5kyplZ9y5jGQlctb0ystayBsPFLBex7wmEn4fkno4/4=; b=Kn3yeZQ9013BzZWlUjGTFnObmuYzg5E+WkPmkA9yO/89b/O64w+IpBfthIWbYr0D9G 6Yk+jSZeqHKA1aKTSRRtv/fSElj3anccozxPwIbQRx1biPwvbrO/USnOw01eMWMbHWGW R/Sr59OJrKob7iZuV7dbkk26eddY8JdpGKXlgnOpBosShHCXDzq1bc6hpOvClPkkm4Wu +NcIEmsOaLq0U3ackZ/GHUihz1TnPY6nEwuRAhPT+2UGdNDFt+BALpqfIAPGZSG4qQYX 5of6YeUR6LmvRgORwiYoOxdb94iwyaKrQgVQtRsFJPzmFRYtzkc5Tfus3y5Pec70NilE 1OVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=x5aGOuOp; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id y47si9012901edb.94.2019.06.17.07.49.40 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 17 Jun 2019 07:49:40 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=x5aGOuOp; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:48162 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hcswz-0001Gz-TN for patch@linaro.org; Mon, 17 Jun 2019 10:49:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:46597) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hcsiG-0003SR-6O for qemu-devel@nongnu.org; Mon, 17 Jun 2019 10:34:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hcsiE-000800-Am for qemu-devel@nongnu.org; Mon, 17 Jun 2019 10:34:24 -0400 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]:46863) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hcsiE-0007yl-1Y for qemu-devel@nongnu.org; Mon, 17 Jun 2019 10:34:22 -0400 Received: by mail-wr1-x429.google.com with SMTP id n4so10191715wrw.13 for ; Mon, 17 Jun 2019 07:34:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=5kyplZ9y5jGQlctb0ystayBsPFLBex7wmEn4fkno4/4=; b=x5aGOuOpvI+iuvYvGPX/pSzlQgFpCSCLmv1u+UqQBllf4e5QmNFe7ioVdLoRihJWQZ 8+sfrDHNvobDO2EULQmfLOq44evqnsarcig4Z4zZcaxs4DbeCKHZIKXcp0marlkY9DWu px31tDhA993QdIkRy/r36aJhHxhFMNzQF/HWO8mh3NBUlrTmqZ5E6bDRZrllxGuGNZ6/ rXsxNpTSTccLG+yLZwM80oAT0GwjPzyOPxGQaKoUQxG7Voie/Z/652y9rvDXmvB64bdx NYLIWm30wN+BjWi627f69nTmBXAFJEbcfM9TGry/TUln5zJX1np2aemc+XdRTfE7wgtk NICg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5kyplZ9y5jGQlctb0ystayBsPFLBex7wmEn4fkno4/4=; b=rWpoo0qUuQ+34L21KSrRZ0iTt+vRmYTjdCyeNdxM/HkieGsX9XfCK8UcqDXCXUr9Y3 VaryPF3qRKNJ4E6MavQVaTHne5OnRmvDOP+1tgf4NazoEAQwHb/pPghMBOmi5yv57ucw rsTGWxNSD/vLFD1J9d6cIo5Xv1ei0eO0Zck0zWunNpGXa/9uOVZHqYbhET0Fe1w+Gf+r Dmn95Yg+VsTZ75H54J2aqCtMbbVrcXvVYbECVI3lPCBK7QolBBFYGYI1N7N8aY1wcg0M JFnidG4gDsznjNlfQBpvGir9a4DZqAAHhAtIAGtNPlPBCEd2kk7QlXeqEHNnk7lILrP9 +zEw== X-Gm-Message-State: APjAAAVOLgeeIYZXQnF0PeNdI5K3wmJXfjO6m5QTdjkwALOYgRlavGPY okZNc3k/ZzYHlSeTfBnfH2GRJhJhsLI8pg== X-Received: by 2002:adf:de02:: with SMTP id b2mr538941wrm.349.1560782060231; Mon, 17 Jun 2019 07:34:20 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id a67sm13819985wmh.40.2019.06.17.07.34.19 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 17 Jun 2019 07:34:19 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 17 Jun 2019 15:33:53 +0100 Message-Id: <20190617143412.5734-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190617143412.5734-1-peter.maydell@linaro.org> References: <20190617143412.5734-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::429 Subject: [Qemu-devel] [PULL 05/24] target/arm: Allow VFP and Neon to be disabled via a CPU property X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Allow VFP and neon to be disabled via a CPU property. As with the "pmu" property, we only allow these features to be removed from CPUs which have it by default, not added to CPUs which don't have it. The primary motivation here is to be able to optionally create Cortex-M33 CPUs with no FPU, but we provide switches for both VFP and Neon because the two interact: * AArch64 can't have one without the other * Some ID register fields only change if both are disabled Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Message-id: 20190517174046.11146-2-peter.maydell@linaro.org --- target/arm/cpu.h | 4 ++ target/arm/cpu.c | 150 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 148 insertions(+), 6 deletions(-) -- 2.20.1 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 92298624215..cf2496aeeec 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -786,6 +786,10 @@ struct ARMCPU { bool has_el3; /* CPU has PMU (Performance Monitor Unit) */ bool has_pmu; + /* CPU has VFP */ + bool has_vfp; + /* CPU has Neon */ + bool has_neon; /* CPU has memory protection unit */ bool has_mpu; diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 2335659a852..af879d5311e 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -763,6 +763,12 @@ static Property arm_cpu_cfgend_property = static Property arm_cpu_has_pmu_property = DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true); +static Property arm_cpu_has_vfp_property = + DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true); + +static Property arm_cpu_has_neon_property = + DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true); + static Property arm_cpu_has_mpu_property = DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); @@ -803,6 +809,13 @@ void arm_cpu_post_init(Object *obj) if (arm_feature(&cpu->env, ARM_FEATURE_M)) { set_feature(&cpu->env, ARM_FEATURE_PMSA); } + /* Similarly for the VFP feature bits */ + if (arm_feature(&cpu->env, ARM_FEATURE_VFP4)) { + set_feature(&cpu->env, ARM_FEATURE_VFP3); + } + if (arm_feature(&cpu->env, ARM_FEATURE_VFP3)) { + set_feature(&cpu->env, ARM_FEATURE_VFP); + } if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) || arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) { @@ -847,6 +860,27 @@ void arm_cpu_post_init(Object *obj) &error_abort); } + /* + * Allow user to turn off VFP and Neon support, but only for TCG -- + * KVM does not currently allow us to lie to the guest about its + * ID/feature registers, so the guest always sees what the host has. + */ + if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) { + cpu->has_vfp = true; + if (!kvm_enabled()) { + qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property, + &error_abort); + } + } + + if (arm_feature(&cpu->env, ARM_FEATURE_NEON)) { + cpu->has_neon = true; + if (!kvm_enabled()) { + qdev_property_add_static(DEVICE(obj), &arm_cpu_has_neon_property, + &error_abort); + } + } + if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) { qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property, &error_abort); @@ -956,6 +990,116 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) return; } + if (arm_feature(env, ARM_FEATURE_AARCH64) && + cpu->has_vfp != cpu->has_neon) { + /* + * This is an architectural requirement for AArch64; AArch32 is + * more flexible and permits VFP-no-Neon and Neon-no-VFP. + */ + error_setg(errp, + "AArch64 CPUs must have both VFP and Neon or neither"); + return; + } + + if (!cpu->has_vfp) { + uint64_t t; + uint32_t u; + + unset_feature(env, ARM_FEATURE_VFP); + unset_feature(env, ARM_FEATURE_VFP3); + unset_feature(env, ARM_FEATURE_VFP4); + + t = cpu->isar.id_aa64isar1; + t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0); + cpu->isar.id_aa64isar1 = t; + + t = cpu->isar.id_aa64pfr0; + t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf); + cpu->isar.id_aa64pfr0 = t; + + u = cpu->isar.id_isar6; + u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0); + cpu->isar.id_isar6 = u; + + u = cpu->isar.mvfr0; + u = FIELD_DP32(u, MVFR0, FPSP, 0); + u = FIELD_DP32(u, MVFR0, FPDP, 0); + u = FIELD_DP32(u, MVFR0, FPTRAP, 0); + u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0); + u = FIELD_DP32(u, MVFR0, FPSQRT, 0); + u = FIELD_DP32(u, MVFR0, FPSHVEC, 0); + u = FIELD_DP32(u, MVFR0, FPROUND, 0); + cpu->isar.mvfr0 = u; + + u = cpu->isar.mvfr1; + u = FIELD_DP32(u, MVFR1, FPFTZ, 0); + u = FIELD_DP32(u, MVFR1, FPDNAN, 0); + u = FIELD_DP32(u, MVFR1, FPHP, 0); + cpu->isar.mvfr1 = u; + + u = cpu->isar.mvfr2; + u = FIELD_DP32(u, MVFR2, FPMISC, 0); + cpu->isar.mvfr2 = u; + } + + if (!cpu->has_neon) { + uint64_t t; + uint32_t u; + + unset_feature(env, ARM_FEATURE_NEON); + + t = cpu->isar.id_aa64isar0; + t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0); + cpu->isar.id_aa64isar0 = t; + + t = cpu->isar.id_aa64isar1; + t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0); + cpu->isar.id_aa64isar1 = t; + + t = cpu->isar.id_aa64pfr0; + t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf); + cpu->isar.id_aa64pfr0 = t; + + u = cpu->isar.id_isar5; + u = FIELD_DP32(u, ID_ISAR5, RDM, 0); + u = FIELD_DP32(u, ID_ISAR5, VCMA, 0); + cpu->isar.id_isar5 = u; + + u = cpu->isar.id_isar6; + u = FIELD_DP32(u, ID_ISAR6, DP, 0); + u = FIELD_DP32(u, ID_ISAR6, FHM, 0); + cpu->isar.id_isar6 = u; + + u = cpu->isar.mvfr1; + u = FIELD_DP32(u, MVFR1, SIMDLS, 0); + u = FIELD_DP32(u, MVFR1, SIMDINT, 0); + u = FIELD_DP32(u, MVFR1, SIMDSP, 0); + u = FIELD_DP32(u, MVFR1, SIMDHP, 0); + u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0); + cpu->isar.mvfr1 = u; + + u = cpu->isar.mvfr2; + u = FIELD_DP32(u, MVFR2, SIMDMISC, 0); + cpu->isar.mvfr2 = u; + } + + if (!cpu->has_neon && !cpu->has_vfp) { + uint64_t t; + uint32_t u; + + t = cpu->isar.id_aa64isar0; + t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0); + cpu->isar.id_aa64isar0 = t; + + t = cpu->isar.id_aa64isar1; + t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0); + cpu->isar.id_aa64isar1 = t; + + u = cpu->isar.mvfr0; + u = FIELD_DP32(u, MVFR0, SIMDREG, 0); + cpu->isar.mvfr0 = u; + } + /* Some features automatically imply others: */ if (arm_feature(env, ARM_FEATURE_V8)) { if (arm_feature(env, ARM_FEATURE_M)) { @@ -1016,12 +1160,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) if (arm_feature(env, ARM_FEATURE_V5)) { set_feature(env, ARM_FEATURE_V4T); } - if (arm_feature(env, ARM_FEATURE_VFP4)) { - set_feature(env, ARM_FEATURE_VFP3); - } - if (arm_feature(env, ARM_FEATURE_VFP3)) { - set_feature(env, ARM_FEATURE_VFP); - } if (arm_feature(env, ARM_FEATURE_LPAE)) { set_feature(env, ARM_FEATURE_V7MP); set_feature(env, ARM_FEATURE_PXN);