From nobody Mon Feb 9 20:31:53 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1622827419; cv=none; d=zohomail.com; s=zohoarc; b=gcOwWDwyGUgVWyLYZajks1VQFxhkjaWLoskBha5ZvTKLTcktcWR9L/TrXXIg8QH9fREy1uxabiTBB1mPPB5P0ouuk1oX0D/6+J++/wReunqyBX05fA/IJRu2FEM55A6eUsQa8G3O8FjzHGjpeQTlJKnY5CYDueamNzxRhu8u/BA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1622827419; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=DAHUANG/vqqFP+x4dLlbQOPag/TtMMrlsBRBzfaoKto=; b=J8hN41X+Ql2nN73+JFSCCD3zkQf7sh7wpTSF07RDglrOogRr05fPLF4S+JMFtwTPAV2OoIoyFyj1gXohxzd6kRvY9MTI2a4SJs/OMBaSvVsAXlOFzz3q/lNRi14ZC4IetIDtWy4juq5O10bZGtZ0V+qRaMGxJL8oiH/gWcK7Tz4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1622827418953127.42773892015055; Fri, 4 Jun 2021 10:23:38 -0700 (PDT) Received: from localhost ([::1]:33848 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpDXj-00012z-Qc for importer@patchew.org; Fri, 04 Jun 2021 13:23:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33838) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpCkx-0000OL-0x for qemu-devel@nongnu.org; Fri, 04 Jun 2021 12:33:11 -0400 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]:41719) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lpCkh-0002De-VW for qemu-devel@nongnu.org; Fri, 04 Jun 2021 12:33:10 -0400 Received: by mail-wr1-x431.google.com with SMTP id h8so9890415wrz.8 for ; Fri, 04 Jun 2021 09:32:55 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id r7sm4615381wmq.23.2021.06.04.09.32.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Jun 2021 09:32:51 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id CD5EF20013; Fri, 4 Jun 2021 16:53:23 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DAHUANG/vqqFP+x4dLlbQOPag/TtMMrlsBRBzfaoKto=; b=t3Bo5nS5YYhppyuoNE30Y56mzdpN+u8Zlwcal0nsKvWNE5o1bwSgMMB2LJPsDmm3Gq exVJ7Elt3n16uUm+T3hJlMbkYq9LLbboE56GXHC5cER+3pTO4Ye/58alchXm8kvfRUW+ exTQokNHAvAMOts3Pd3zNadmaQbNWqqF3mHhgfdXQmEZLGPZZx5Jt5NKs8JcYl4FBsxm 6k38NpH5eMO69jNhEinbwioep71YWxNVK0FKrKqwwQIGWuxhpIeaWF3+d2KpDGUAeXqj ydIgQ2cicPCVQgnI/f4g91O/H6TQo6itCpEEoUi77x5YiCGjlQbg3bkF1QMpajpjz29n 8mwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DAHUANG/vqqFP+x4dLlbQOPag/TtMMrlsBRBzfaoKto=; b=EpKVUsZ2Ea51QPctQQxHh5qUYNt+LYf2ptOnSYYVkCTyrO1UgjoElpgSskYwS3plzd aYtIFHN2A9uDNjnCS6wuQxDYnFtUk6w++kpVms5wHmXmm2zUGjR6e11R899UofIckqPl LIFUfauCPxd+qbf86EoBQCfdmqLwNm7avIq2hM7/TWrqXZkdA22igqjCcxl1iUCpf3zV KG3CcvQamDEKL0pV+beFXyaxzZ6Q5OcRxHfMwQ73O4DTLdK0rp5KyntKiZL39etZoPb0 yM35at0hoRe5WQz7gyRmglncTuZLl8fX3yxJDjGkjJltIwAvtEwdTB4xZ2IgO+9n6Qlo wBuQ== X-Gm-Message-State: AOAM530En+CbNZKaI4kQmI/wQI9Duo29zyy2IPU8qIweEcOjeuxT7LgS p0kw8h58Q/aOBODTBQwDPIg2mQ== X-Google-Smtp-Source: ABdhPJzHZUT9c11GW3nKUE/fm4sYIUBtDKCdCxqVJxyU34DdZ/Wm1EcDFGaQmr4yGv2mbMOSsNaRpA== X-Received: by 2002:a5d:414e:: with SMTP id c14mr4619104wrq.81.1622824374611; Fri, 04 Jun 2021 09:32:54 -0700 (PDT) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [PATCH v16 90/99] XXX target/arm: experiment refactoring cpu "max" Date: Fri, 4 Jun 2021 16:53:03 +0100 Message-Id: <20210604155312.15902-91-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210604155312.15902-1-alex.bennee@linaro.org> References: <20210604155312.15902-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: , Cc: Peter Maydell , qemu-arm@nongnu.org, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Claudio Fontana Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) From: Claudio Fontana XXX Someone who really understands which properties should be added where should review this attentively. What goes into cpu leaf class initialization? What goes into arm_post_init / accel_cpu? What goes into arm_cpu_finalize_features / aarch64_cpu_finalize_features? Should there be shift of more code into finalize_features? Signed-off-by: Claudio Fontana Signed-off-by: Alex Benn=C3=A9e --- target/arm/cpu.h | 3 + target/arm/cpu64.c | 175 ++---------------------- target/arm/kvm/kvm-cpu.c | 4 +- target/arm/tcg/tcg-cpu-models.c | 63 +-------- target/arm/tcg/tcg-cpu.c | 228 +++++++++++++++++++++++++++++++- 5 files changed, 241 insertions(+), 232 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 847d3628e9..daa3e5f8d0 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1015,6 +1015,9 @@ struct ARMCPU { =20 /* Generic timer counter frequency, in Hz */ uint64_t gt_cntfrq_hz; + + /* MAX features requested via cpu=3D"max" */ + bool max_features; }; =20 unsigned int gt_cntfrq_period_ns(ARMCPU *cpu); diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index ecce8c4308..9595587ee0 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -247,10 +247,15 @@ static void aarch64_a72_initfn(Object *obj) define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); } =20 -/* -cpu max: if KVM is enabled, like -cpu host (best possible with this ho= st); - * otherwise, a CPU with as many features enabled as our emulation support= s. - * The version of '-cpu max' for qemu-system-arm is defined in cpu.c; - * this only needs to handle 64 bits. +/* + * -cpu max: if KVM is enabled, like -cpu host (best possible with this ho= st), + * plus some "max"-only properties, see f.e. cpu_sve_add_props_m= ax(). + * + * if TCG is enabled, a CPU with as many features enabled as our + * emulation supports. + * + * The version of '-cpu max' for qemu-system-arm is defined in + * tcg/tcg-cpu-models.c, while this version only handles 64bit. */ static void aarch64_max_initfn(Object *obj) { @@ -259,170 +264,12 @@ static void aarch64_max_initfn(Object *obj) if (kvm_enabled()) { kvm_arm_set_cpu_features_from_host(cpu); } else if (tcg_enabled()) { - uint64_t t; - uint32_t u; aarch64_a57_initfn(obj); - - /* - * Reset MIDR so the guest doesn't mistake our 'max' CPU type for = a real - * one and try to apply errata workarounds or use impdef features = we - * don't provide. - * An IMPLEMENTER field of 0 means "reserved for software use"; - * ARCHITECTURE must be 0xf indicating "v7 or later, check ID regi= sters - * to see which features are present"; - * the VARIANT, PARTNUM and REVISION fields are all implementation - * defined and we choose to define PARTNUM just in case guest - * code needs to distinguish this QEMU CPU from other software - * implementations, though this shouldn't be needed. - */ - t =3D FIELD_DP64(0, MIDR_EL1, IMPLEMENTER, 0); - t =3D FIELD_DP64(t, MIDR_EL1, ARCHITECTURE, 0xf); - t =3D FIELD_DP64(t, MIDR_EL1, PARTNUM, 'Q'); - t =3D FIELD_DP64(t, MIDR_EL1, VARIANT, 0); - t =3D FIELD_DP64(t, MIDR_EL1, REVISION, 0); - cpu->midr =3D t; - - t =3D cpu->isar.id_aa64isar0; - t =3D FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */ - t =3D FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */ - t =3D FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); - t =3D FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR0, SM3, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR0, SM4, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR0, DP, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR0, FHM, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */ - t =3D FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */ - t =3D FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); - cpu->isar.id_aa64isar0 =3D t; - - t =3D cpu->isar.id_aa64isar1; - t =3D FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); - t =3D FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR1, SB, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1); - t =3D FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */ - t =3D FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); - cpu->isar.id_aa64isar1 =3D t; - - t =3D cpu->isar.id_aa64pfr0; - t =3D FIELD_DP64(t, ID_AA64PFR0, SVE, 1); - t =3D FIELD_DP64(t, ID_AA64PFR0, FP, 1); - t =3D FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); - t =3D FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); - t =3D FIELD_DP64(t, ID_AA64PFR0, DIT, 1); - cpu->isar.id_aa64pfr0 =3D t; - - t =3D cpu->isar.id_aa64pfr1; - t =3D FIELD_DP64(t, ID_AA64PFR1, BT, 1); - t =3D FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); - /* - * Begin with full support for MTE. This will be downgraded to MTE= =3D0 - * during realize if the board provides no tag memory, much like - * we do for EL2 with the virtualization=3Don property. - */ - t =3D FIELD_DP64(t, ID_AA64PFR1, MTE, 2); - cpu->isar.id_aa64pfr1 =3D t; - - t =3D cpu->isar.id_aa64mmfr0; - t =3D FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits= */ - cpu->isar.id_aa64mmfr0 =3D t; - - t =3D cpu->isar.id_aa64mmfr1; - t =3D FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */ - t =3D FIELD_DP64(t, ID_AA64MMFR1, LO, 1); - t =3D FIELD_DP64(t, ID_AA64MMFR1, VH, 1); - t =3D FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ - t =3D FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */ - t =3D FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */ - cpu->isar.id_aa64mmfr1 =3D t; - - t =3D cpu->isar.id_aa64mmfr2; - t =3D FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); - t =3D FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */ - t =3D FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */ - cpu->isar.id_aa64mmfr2 =3D t; - - t =3D cpu->isar.id_aa64zfr0; - t =3D FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1); - t =3D FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* PMULL */ - t =3D FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); - t =3D FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1); - t =3D FIELD_DP64(t, ID_AA64ZFR0, SM4, 1); - t =3D FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); - t =3D FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); - t =3D FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); - cpu->isar.id_aa64zfr0 =3D t; - - /* Replicate the same data to the 32-bit id registers. */ - u =3D cpu->isar.id_isar5; - u =3D FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */ - u =3D FIELD_DP32(u, ID_ISAR5, SHA1, 1); - u =3D FIELD_DP32(u, ID_ISAR5, SHA2, 1); - u =3D FIELD_DP32(u, ID_ISAR5, CRC32, 1); - u =3D FIELD_DP32(u, ID_ISAR5, RDM, 1); - u =3D FIELD_DP32(u, ID_ISAR5, VCMA, 1); - cpu->isar.id_isar5 =3D u; - - u =3D cpu->isar.id_isar6; - u =3D FIELD_DP32(u, ID_ISAR6, JSCVT, 1); - u =3D FIELD_DP32(u, ID_ISAR6, DP, 1); - u =3D FIELD_DP32(u, ID_ISAR6, FHM, 1); - u =3D FIELD_DP32(u, ID_ISAR6, SB, 1); - u =3D FIELD_DP32(u, ID_ISAR6, SPECRES, 1); - u =3D FIELD_DP32(u, ID_ISAR6, I8MM, 1); - cpu->isar.id_isar6 =3D u; - - u =3D cpu->isar.id_pfr0; - u =3D FIELD_DP32(u, ID_PFR0, DIT, 1); - cpu->isar.id_pfr0 =3D u; - - u =3D cpu->isar.id_pfr2; - u =3D FIELD_DP32(u, ID_PFR2, SSBS, 1); - cpu->isar.id_pfr2 =3D u; - - u =3D cpu->isar.id_mmfr3; - u =3D FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */ - cpu->isar.id_mmfr3 =3D u; - - u =3D cpu->isar.id_mmfr4; - u =3D FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */ - u =3D FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ - u =3D FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */ - u =3D FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */ - cpu->isar.id_mmfr4 =3D u; - - t =3D cpu->isar.id_aa64dfr0; - t =3D FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */ - cpu->isar.id_aa64dfr0 =3D t; - - u =3D cpu->isar.id_dfr0; - u =3D FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */ - cpu->isar.id_dfr0 =3D u; - - u =3D cpu->isar.mvfr1; - u =3D FIELD_DP32(u, MVFR1, FPHP, 3); /* v8.2-FP16 */ - u =3D FIELD_DP32(u, MVFR1, SIMDHP, 2); /* v8.2-FP16 */ - cpu->isar.mvfr1 =3D u; - -#ifdef CONFIG_USER_ONLY - /* For usermode -cpu max we can use a larger and more efficient DCZ - * blocksize since we don't have to follow what the hardware does. - */ - cpu->ctr =3D 0x80038003; /* 32 byte I and D cacheline size, VIPT i= cache */ - cpu->dcz_blocksize =3D 7; /* 512 bytes */ -#endif - - cpu_pauth_add_props(obj); } - cpu_sve_add_props(obj); cpu_sve_add_props_max(obj); + + cpu->max_features =3D true; } =20 static const ARMCPUInfo aarch64_cpus[] =3D { diff --git a/target/arm/kvm/kvm-cpu.c b/target/arm/kvm/kvm-cpu.c index 09aede9319..1157888f85 100644 --- a/target/arm/kvm/kvm-cpu.c +++ b/target/arm/kvm/kvm-cpu.c @@ -88,9 +88,7 @@ static void host_cpu_instance_init(Object *obj) ARMCPU *cpu =3D ARM_CPU(obj); =20 kvm_arm_set_cpu_features_from_host(cpu); - if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - cpu_sve_add_props(obj); - } + cpu_sve_add_props(obj); arm_cpu_post_init(obj); } =20 diff --git a/target/arm/tcg/tcg-cpu-models.c b/target/arm/tcg/tcg-cpu-model= s.c index 975869f276..1be953ad1a 100644 --- a/target/arm/tcg/tcg-cpu-models.c +++ b/target/arm/tcg/tcg-cpu-models.c @@ -872,68 +872,7 @@ static void arm_max_initfn(Object *obj) ARMCPU *cpu =3D ARM_CPU(obj); =20 cortex_a15_initfn(obj); - - /* old-style VFP short-vector support */ - cpu->isar.mvfr0 =3D FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1); - -#ifdef CONFIG_USER_ONLY - /* - * We don't set these in system emulation mode for the moment, - * since we don't correctly set (all of) the ID registers to - * advertise them. - */ - set_feature(&cpu->env, ARM_FEATURE_V8); - { - uint32_t t; - - t =3D cpu->isar.id_isar5; - t =3D FIELD_DP32(t, ID_ISAR5, AES, 2); - t =3D FIELD_DP32(t, ID_ISAR5, SHA1, 1); - t =3D FIELD_DP32(t, ID_ISAR5, SHA2, 1); - t =3D FIELD_DP32(t, ID_ISAR5, CRC32, 1); - t =3D FIELD_DP32(t, ID_ISAR5, RDM, 1); - t =3D FIELD_DP32(t, ID_ISAR5, VCMA, 1); - cpu->isar.id_isar5 =3D t; - - t =3D cpu->isar.id_isar6; - t =3D FIELD_DP32(t, ID_ISAR6, JSCVT, 1); - t =3D FIELD_DP32(t, ID_ISAR6, DP, 1); - t =3D FIELD_DP32(t, ID_ISAR6, FHM, 1); - t =3D FIELD_DP32(t, ID_ISAR6, SB, 1); - t =3D FIELD_DP32(t, ID_ISAR6, SPECRES, 1); - t =3D FIELD_DP32(t, ID_ISAR6, I8MM, 1); - cpu->isar.id_isar6 =3D t; - - t =3D cpu->isar.mvfr1; - t =3D FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */ - t =3D FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */ - cpu->isar.mvfr1 =3D t; - - t =3D cpu->isar.mvfr2; - t =3D FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */ - t =3D FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */ - cpu->isar.mvfr2 =3D t; - - t =3D cpu->isar.id_mmfr3; - t =3D FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */ - cpu->isar.id_mmfr3 =3D t; - - t =3D cpu->isar.id_mmfr4; - t =3D FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */ - t =3D FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ - t =3D FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */ - t =3D FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */ - cpu->isar.id_mmfr4 =3D t; - - t =3D cpu->isar.id_pfr0; - t =3D FIELD_DP32(t, ID_PFR0, DIT, 1); - cpu->isar.id_pfr0 =3D t; - - t =3D cpu->isar.id_pfr2; - t =3D FIELD_DP32(t, ID_PFR2, SSBS, 1); - cpu->isar.id_pfr2 =3D t; - } -#endif /* CONFIG_USER_ONLY */ + cpu->max_features =3D true; } #endif /* !TARGET_AARCH64 */ =20 diff --git a/target/arm/tcg/tcg-cpu.c b/target/arm/tcg/tcg-cpu.c index db677bc71c..675f36be27 100644 --- a/target/arm/tcg/tcg-cpu.c +++ b/target/arm/tcg/tcg-cpu.c @@ -26,6 +26,10 @@ #include "internals.h" #include "exec/exec-all.h" =20 +#ifdef TARGET_AARCH64 +#include "tcg/cpu-pauth.h" +#endif + void arm_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -228,16 +232,234 @@ static struct TCGCPUOps arm_tcg_ops =3D { #endif /* !CONFIG_USER_ONLY */ }; =20 -static void tcg_cpu_instance_init(CPUState *cs) +#ifdef TARGET_AARCH64 +static void tcg_cpu_max_instance_init(CPUState *cs) { + uint64_t t; + uint32_t u; + Object *obj =3D OBJECT(cs); ARMCPU *cpu =3D ARM_CPU(cs); =20 /* - * this would be the place to move TCG-specific props - * in future refactoring of cpu properties. + * Reset MIDR so the guest doesn't mistake our 'max' CPU type for a re= al + * one and try to apply errata workarounds or use impdef features we + * don't provide. + * An IMPLEMENTER field of 0 means "reserved for software use"; + * ARCHITECTURE must be 0xf indicating "v7 or later, check ID registers + * to see which features are present"; + * the VARIANT, PARTNUM and REVISION fields are all implementation + * defined and we choose to define PARTNUM just in case guest + * code needs to distinguish this QEMU CPU from other software + * implementations, though this shouldn't be needed. + */ + t =3D FIELD_DP64(0, MIDR_EL1, IMPLEMENTER, 0); + t =3D FIELD_DP64(t, MIDR_EL1, ARCHITECTURE, 0xf); + t =3D FIELD_DP64(t, MIDR_EL1, PARTNUM, 'Q'); + t =3D FIELD_DP64(t, MIDR_EL1, VARIANT, 0); + t =3D FIELD_DP64(t, MIDR_EL1, REVISION, 0); + cpu->midr =3D t; + + t =3D cpu->isar.id_aa64isar0; + t =3D FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */ + t =3D FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */ + t =3D FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); + t =3D FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR0, SM3, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR0, SM4, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR0, DP, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR0, FHM, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */ + t =3D FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); + cpu->isar.id_aa64isar0 =3D t; + + t =3D cpu->isar.id_aa64isar1; + t =3D FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); + t =3D FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR1, SB, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1); + t =3D FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */ + cpu->isar.id_aa64isar1 =3D t; + + t =3D cpu->isar.id_aa64pfr0; + t =3D FIELD_DP64(t, ID_AA64PFR0, SVE, 1); + t =3D FIELD_DP64(t, ID_AA64PFR0, FP, 1); + t =3D FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); + t =3D FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); + t =3D FIELD_DP64(t, ID_AA64PFR0, DIT, 1); + cpu->isar.id_aa64pfr0 =3D t; + + t =3D cpu->isar.id_aa64pfr1; + t =3D FIELD_DP64(t, ID_AA64PFR1, BT, 1); + t =3D FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); + /* + * Begin with full support for MTE. This will be downgraded to MTE=3D0 + * during realize if the board provides no tag memory, much like + * we do for EL2 with the virtualization=3Don property. + */ + t =3D FIELD_DP64(t, ID_AA64PFR1, MTE, 2); + cpu->isar.id_aa64pfr1 =3D t; + + t =3D cpu->isar.id_aa64mmfr0; + t =3D FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */ + cpu->isar.id_aa64mmfr0 =3D t; + + t =3D cpu->isar.id_aa64mmfr1; + t =3D FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */ + t =3D FIELD_DP64(t, ID_AA64MMFR1, LO, 1); + t =3D FIELD_DP64(t, ID_AA64MMFR1, VH, 1); + t =3D FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ + t =3D FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */ + t =3D FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */ + cpu->isar.id_aa64mmfr1 =3D t; + + t =3D cpu->isar.id_aa64mmfr2; + t =3D FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); + t =3D FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */ + t =3D FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */ + cpu->isar.id_aa64mmfr2 =3D t; + + /* Replicate the same data to the 32-bit id registers. */ + u =3D cpu->isar.id_isar5; + u =3D FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */ + u =3D FIELD_DP32(u, ID_ISAR5, SHA1, 1); + u =3D FIELD_DP32(u, ID_ISAR5, SHA2, 1); + u =3D FIELD_DP32(u, ID_ISAR5, CRC32, 1); + u =3D FIELD_DP32(u, ID_ISAR5, RDM, 1); + u =3D FIELD_DP32(u, ID_ISAR5, VCMA, 1); + cpu->isar.id_isar5 =3D u; + + u =3D cpu->isar.id_isar6; + u =3D FIELD_DP32(u, ID_ISAR6, JSCVT, 1); + u =3D FIELD_DP32(u, ID_ISAR6, DP, 1); + u =3D FIELD_DP32(u, ID_ISAR6, FHM, 1); + u =3D FIELD_DP32(u, ID_ISAR6, SB, 1); + u =3D FIELD_DP32(u, ID_ISAR6, SPECRES, 1); + cpu->isar.id_isar6 =3D u; + + u =3D cpu->isar.id_pfr0; + u =3D FIELD_DP32(u, ID_PFR0, DIT, 1); + cpu->isar.id_pfr0 =3D u; + + u =3D cpu->isar.id_pfr2; + u =3D FIELD_DP32(u, ID_PFR2, SSBS, 1); + cpu->isar.id_pfr2 =3D u; + + u =3D cpu->isar.id_mmfr3; + u =3D FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */ + cpu->isar.id_mmfr3 =3D u; + + u =3D cpu->isar.id_mmfr4; + u =3D FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */ + u =3D FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ + u =3D FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */ + u =3D FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */ + cpu->isar.id_mmfr4 =3D u; + + t =3D cpu->isar.id_aa64dfr0; + t =3D FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */ + cpu->isar.id_aa64dfr0 =3D t; + + u =3D cpu->isar.id_dfr0; + u =3D FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */ + cpu->isar.id_dfr0 =3D u; + + u =3D cpu->isar.mvfr1; + u =3D FIELD_DP32(u, MVFR1, FPHP, 3); /* v8.2-FP16 */ + u =3D FIELD_DP32(u, MVFR1, SIMDHP, 2); /* v8.2-FP16 */ + cpu->isar.mvfr1 =3D u; + +#ifdef CONFIG_USER_ONLY + /* + * For usermode -cpu max we can use a larger and more efficient DCZ + * blocksize since we don't have to follow what the hardware does. */ + cpu->ctr =3D 0x80038003; /* 32 byte I and D cacheline size, VIPT icach= e */ + cpu->dcz_blocksize =3D 7; /* 512 bytes */ +#endif + cpu_pauth_add_props(obj); +} + +#else /* !TARGET_AARCH64 */ +static void tcg_cpu_max_instance_init(CPUState *cs) +{ + ARMCPU *cpu =3D ARM_CPU(cs); + + /* old-style VFP short-vector support */ + cpu->isar.mvfr0 =3D FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1); + +#ifdef CONFIG_USER_ONLY + /* + * We don't set these in system emulation mode for the moment, + * since we don't correctly set (all of) the ID registers to + * advertise them. + */ + set_feature(&cpu->env, ARM_FEATURE_V8); + { + uint32_t t; + + t =3D cpu->isar.id_isar5; + t =3D FIELD_DP32(t, ID_ISAR5, AES, 2); + t =3D FIELD_DP32(t, ID_ISAR5, SHA1, 1); + t =3D FIELD_DP32(t, ID_ISAR5, SHA2, 1); + t =3D FIELD_DP32(t, ID_ISAR5, CRC32, 1); + t =3D FIELD_DP32(t, ID_ISAR5, RDM, 1); + t =3D FIELD_DP32(t, ID_ISAR5, VCMA, 1); + cpu->isar.id_isar5 =3D t; + + t =3D cpu->isar.id_isar6; + t =3D FIELD_DP32(t, ID_ISAR6, JSCVT, 1); + t =3D FIELD_DP32(t, ID_ISAR6, DP, 1); + t =3D FIELD_DP32(t, ID_ISAR6, FHM, 1); + t =3D FIELD_DP32(t, ID_ISAR6, SB, 1); + t =3D FIELD_DP32(t, ID_ISAR6, SPECRES, 1); + cpu->isar.id_isar6 =3D t; + + t =3D cpu->isar.mvfr1; + t =3D FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */ + t =3D FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */ + cpu->isar.mvfr1 =3D t; + + t =3D cpu->isar.mvfr2; + t =3D FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */ + t =3D FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */ + cpu->isar.mvfr2 =3D t; + + t =3D cpu->isar.id_mmfr3; + t =3D FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */ + cpu->isar.id_mmfr3 =3D t; + + t =3D cpu->isar.id_mmfr4; + t =3D FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */ + t =3D FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ + t =3D FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */ + t =3D FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */ + cpu->isar.id_mmfr4 =3D t; + + t =3D cpu->isar.id_pfr0; + t =3D FIELD_DP32(t, ID_PFR0, DIT, 1); + cpu->isar.id_pfr0 =3D t; + + t =3D cpu->isar.id_pfr2; + t =3D FIELD_DP32(t, ID_PFR2, SSBS, 1); + cpu->isar.id_pfr2 =3D t; + } +#endif /* CONFIG_USER_ONLY */ +} +#endif /* TARGET_AARCH64 */ + +static void tcg_cpu_instance_init(CPUState *cs) +{ + ARMCPU *cpu =3D ARM_CPU(cs); =20 cpu->psci_version =3D 2; /* TCG implements PSCI 0.2 */ + if (cpu->max_features) { + tcg_cpu_max_instance_init(cs); + } } =20 static void tcg_cpu_reset(CPUState *cs) --=20 2.20.1