Merge branch 'master' of gitee.com:src-openeuler/qemu into fix-usb
This commit is contained in:
commit
27947f2b8c
52
qemu.spec
52
qemu.spec
@ -1,6 +1,6 @@
|
|||||||
Name: qemu
|
Name: qemu
|
||||||
Version: 4.1.0
|
Version: 4.1.0
|
||||||
Release: 20
|
Release: 22
|
||||||
Epoch: 2
|
Epoch: 2
|
||||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||||
License: GPLv2 and BSD and MIT and CC-BY
|
License: GPLv2 and BSD and MIT and CC-BY
|
||||||
@ -204,7 +204,29 @@ Patch0191: test-tpm-pass-optional-machine-options-to-swtpm-test.patch
|
|||||||
Patch0192: test-tpm-tis-Get-prepared-to-share-tests-between-ISA.patch
|
Patch0192: test-tpm-tis-Get-prepared-to-share-tests-between-ISA.patch
|
||||||
Patch0193: test-tpm-tis-Add-Sysbus-TPM-TIS-device-test.patch
|
Patch0193: test-tpm-tis-Add-Sysbus-TPM-TIS-device-test.patch
|
||||||
Patch0194: build-smt-processor-structure-to-support-smt-topolog.patch
|
Patch0194: build-smt-processor-structure-to-support-smt-topolog.patch
|
||||||
Patch0195: hw-usb-core-fix-buffer-overflow.patch
|
Patch0195: target-arm-Add-isar_feature-tests-for-PAN-ATS1E1.patch
|
||||||
|
Patch0196: target-arm-Add-ID_AA64MMFR2_EL1.patch
|
||||||
|
Patch0197: target-arm-Add-and-use-FIELD-definitions-for-ID_AA64.patch
|
||||||
|
Patch0198: target-arm-Use-FIELD-macros-for-clearing-ID_DFR0-PER.patch
|
||||||
|
Patch0199: target-arm-Define-an-aa32_pmu_8_1-isar-feature-test-.patch
|
||||||
|
Patch0200: target-arm-Add-_aa64_-and-_any_-versions-of-pmu_8_1-.patch
|
||||||
|
Patch0201: target-arm-Stop-assuming-DBGDIDR-always-exists.patch
|
||||||
|
Patch0202: target-arm-Move-DBGDIDR-into-ARMISARegisters.patch
|
||||||
|
Patch0203: target-arm-Enable-ARMv8.2-ATS1E1-in-cpu-max.patch
|
||||||
|
Patch0204: target-arm-Test-correct-register-in-aa32_pan-and-aa3.patch
|
||||||
|
Patch0205: target-arm-Read-debug-related-ID-registers-from-KVM.patch
|
||||||
|
Patch0206: target-arm-monitor-Introduce-qmp_query_cpu_model_exp.patch
|
||||||
|
Patch0207: target-arm-monitor-query-cpu-model-expansion-crashed.patch
|
||||||
|
Patch0208: target-arm-convert-isar-regs-to-array.patch
|
||||||
|
Patch0209: target-arm-parse-cpu-feature-related-options.patch
|
||||||
|
Patch0210: target-arm-register-CPU-features-for-property.patch
|
||||||
|
Patch0211: target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch
|
||||||
|
Patch0212: target-arm-introduce-CPU-feature-dependency-mechanis.patch
|
||||||
|
Patch0213: target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch
|
||||||
|
Patch0214: target-arm-Add-CPU-features-to-query-cpu-model-expan.patch
|
||||||
|
Patch0215: target-arm-Update-ID-fields.patch
|
||||||
|
Patch0216: target-arm-Add-more-CPU-features.patch
|
||||||
|
Patch0217: hw-usb-core-fix-buffer-overflow.patch
|
||||||
|
|
||||||
BuildRequires: flex
|
BuildRequires: flex
|
||||||
BuildRequires: bison
|
BuildRequires: bison
|
||||||
@ -554,6 +576,32 @@ getent passwd qemu >/dev/null || \
|
|||||||
* Fri Aug 21 2020 Huawei Technologies Co., Ltd <lijiajie11@huawei.com>
|
* Fri Aug 21 2020 Huawei Technologies Co., Ltd <lijiajie11@huawei.com>
|
||||||
- hw/usb/core.c: fix buffer overflow in do_token_setup function
|
- hw/usb/core.c: fix buffer overflow in do_token_setup function
|
||||||
|
|
||||||
|
* Wed Aug 19 2020 Huawei Technologies Co., Ltd <liangpeng10@huawei.com>
|
||||||
|
- target-arm-convert-isar-regs-to-array.patch
|
||||||
|
- target-arm-parse-cpu-feature-related-options.patch
|
||||||
|
- target-arm-register-CPU-features-for-property.patch
|
||||||
|
- target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch
|
||||||
|
- target-arm-introduce-CPU-feature-dependency-mechanis.patch
|
||||||
|
- target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch
|
||||||
|
- target-arm-Add-CPU-features-to-query-cpu-model-expan.patch
|
||||||
|
- target-arm-Update-ID-fields.patch
|
||||||
|
- target-arm-Add-more-CPU-features.patch
|
||||||
|
|
||||||
|
* Wed Aug 19 2020 Huawei Technologies Co., Ltd <liangpeng10@huawei.com>
|
||||||
|
- target-arm-Add-isar_feature-tests-for-PAN-ATS1E1.patch
|
||||||
|
- target-arm-Add-ID_AA64MMFR2_EL1.patch
|
||||||
|
- target-arm-Add-and-use-FIELD-definitions-for-ID_AA64.patch
|
||||||
|
- target-arm-Use-FIELD-macros-for-clearing-ID_DFR0-PER.patch
|
||||||
|
- target-arm-Define-an-aa32_pmu_8_1-isar-feature-test-.patch
|
||||||
|
- target-arm-Add-_aa64_-and-_any_-versions-of-pmu_8_1-.patch
|
||||||
|
- target-arm-Stop-assuming-DBGDIDR-always-exists.patch
|
||||||
|
- target-arm-Move-DBGDIDR-into-ARMISARegisters.patch
|
||||||
|
- target-arm-Enable-ARMv8.2-ATS1E1-in-cpu-max.patch
|
||||||
|
- target-arm-Test-correct-register-in-aa32_pan-and-aa3.patch
|
||||||
|
- target-arm-Read-debug-related-ID-registers-from-KVM.patch
|
||||||
|
- target-arm-monitor-Introduce-qmp_query_cpu_model_exp.patch
|
||||||
|
- target-arm-monitor-query-cpu-model-expansion-crashed.patch
|
||||||
|
|
||||||
* Tue Aug 18 2020 Huawei Technologies Co., Ltd <fanhenglong@huawei.com>
|
* Tue Aug 18 2020 Huawei Technologies Co., Ltd <fanhenglong@huawei.com>
|
||||||
- hw/acpi/aml-build.c: build smt processor structure to support smt topology
|
- hw/acpi/aml-build.c: build smt processor structure to support smt topology
|
||||||
|
|
||||||
|
|||||||
89
target-arm-Add-CPU-features-to-query-cpu-model-expan.patch
Normal file
89
target-arm-Add-CPU-features-to-query-cpu-model-expan.patch
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From 274d25bdb2df13a26ad6d2a8a06fcc281a22f642 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
Date: Thu, 6 Aug 2020 16:14:58 +0800
|
||||||
|
Subject: [PATCH 7/9] target/arm: Add CPU features to query-cpu-model-expansion
|
||||||
|
|
||||||
|
Add CPU features to the result of query-cpu-model-expansion so that
|
||||||
|
other applications (such as libvirt) can know the supported CPU
|
||||||
|
features.
|
||||||
|
|
||||||
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||||
|
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 27 +++++++++++++++++++++++++++
|
||||||
|
target/arm/cpu.h | 2 ++
|
||||||
|
target/arm/monitor.c | 2 ++
|
||||||
|
3 files changed, 31 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index db46afba..dcf9f49e 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -25,6 +25,8 @@
|
||||||
|
#include "qemu/module.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
|
#include "qapi/visitor.h"
|
||||||
|
+#include "qapi/qmp/qdict.h"
|
||||||
|
+#include "qom/qom-qobject.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "internals.h"
|
||||||
|
#include "exec/exec-all.h"
|
||||||
|
@@ -1403,6 +1405,31 @@ static const CPUFeatureDep feature_dependencies[] = {
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
+void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features)
|
||||||
|
+{
|
||||||
|
+ Object *obj = OBJECT(cpu);
|
||||||
|
+ const char *name;
|
||||||
|
+ ObjectProperty *prop;
|
||||||
|
+ bool is_32bit = !arm_feature(&cpu->env, ARM_FEATURE_AARCH64);
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(cpu_features); ++i) {
|
||||||
|
+ if (is_32bit != cpu_features[i].is_32bit) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ name = cpu_features[i].name;
|
||||||
|
+ prop = object_property_find(obj, name, NULL);
|
||||||
|
+ if (prop) {
|
||||||
|
+ QObject *value;
|
||||||
|
+
|
||||||
|
+ assert(prop->get);
|
||||||
|
+ value = object_property_get_qobject(obj, name, &error_abort);
|
||||||
|
+ qdict_put_obj(features, name, value);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||||
|
void *opaque, Error **errp)
|
||||||
|
{
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 7bb481fb..068c3fa2 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -3692,4 +3692,6 @@ static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
|
||||||
|
#define cpu_isar_feature(name, cpu) \
|
||||||
|
({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
|
||||||
|
|
||||||
|
+void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
|
||||||
|
index e2b1d117..7c2ff3c0 100644
|
||||||
|
--- a/target/arm/monitor.c
|
||||||
|
+++ b/target/arm/monitor.c
|
||||||
|
@@ -219,6 +219,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ arm_cpu_features_to_dict(ARM_CPU(obj), qdict_out);
|
||||||
|
+
|
||||||
|
if (!qdict_size(qdict_out)) {
|
||||||
|
qobject_unref(qdict_out);
|
||||||
|
} else {
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
87
target-arm-Add-ID_AA64MMFR2_EL1.patch
Normal file
87
target-arm-Add-ID_AA64MMFR2_EL1.patch
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
From 3451fb922aa7b0fe532e508ca13d4ab4b3ec75bf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Date: Sat, 8 Feb 2020 12:58:13 +0000
|
||||||
|
Subject: [PATCH 02/13] target/arm: Add ID_AA64MMFR2_EL1
|
||||||
|
|
||||||
|
Add definitions for all of the fields, up to ARMv8.5.
|
||||||
|
Convert the existing RESERVED register to a full register.
|
||||||
|
Query KVM for the value of the register for the host.
|
||||||
|
|
||||||
|
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Message-id: 20200208125816.14954-18-richard.henderson@linaro.org
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
---
|
||||||
|
target/arm/cpu.h | 17 +++++++++++++++++
|
||||||
|
target/arm/helper.c | 4 ++--
|
||||||
|
target/arm/kvm64.c | 2 ++
|
||||||
|
3 files changed, 21 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index fe310828..3e65bc50 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -866,6 +866,7 @@ struct ARMCPU {
|
||||||
|
uint64_t id_aa64pfr1;
|
||||||
|
uint64_t id_aa64mmfr0;
|
||||||
|
uint64_t id_aa64mmfr1;
|
||||||
|
+ uint64_t id_aa64mmfr2;
|
||||||
|
} isar;
|
||||||
|
uint32_t midr;
|
||||||
|
uint32_t revidr;
|
||||||
|
@@ -1762,6 +1763,22 @@ FIELD(ID_AA64MMFR1, PAN, 20, 4)
|
||||||
|
FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
|
||||||
|
FIELD(ID_AA64MMFR1, XNX, 28, 4)
|
||||||
|
|
||||||
|
+FIELD(ID_AA64MMFR2, CNP, 0, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, UAO, 4, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, LSM, 8, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, IESB, 12, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, VARANGE, 16, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, CCIDX, 20, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, NV, 24, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, ST, 28, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, AT, 32, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, IDS, 36, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, FWB, 40, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, TTL, 48, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, BBM, 52, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, EVT, 56, 4)
|
||||||
|
+FIELD(ID_AA64MMFR2, E0PD, 60, 4)
|
||||||
|
+
|
||||||
|
FIELD(ID_DFR0, COPDBG, 0, 4)
|
||||||
|
FIELD(ID_DFR0, COPSDBG, 4, 4)
|
||||||
|
FIELD(ID_DFR0, MMAPDBG, 8, 4)
|
||||||
|
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||||
|
index b74c23a9..c50b1ba1 100644
|
||||||
|
--- a/target/arm/helper.c
|
||||||
|
+++ b/target/arm/helper.c
|
||||||
|
@@ -6182,10 +6182,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
.resetvalue = cpu->isar.id_aa64mmfr1 },
|
||||||
|
- { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||||
|
+ { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = 0 },
|
||||||
|
+ .resetvalue = cpu->isar.id_aa64mmfr2 },
|
||||||
|
{ .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
|
||||||
|
index 4f0bf000..b794108a 100644
|
||||||
|
--- a/target/arm/kvm64.c
|
||||||
|
+++ b/target/arm/kvm64.c
|
||||||
|
@@ -541,6 +541,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 7, 0));
|
||||||
|
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 7, 1));
|
||||||
|
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 7, 2));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that if AArch32 support is not present in the host,
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
166
target-arm-Add-_aa64_-and-_any_-versions-of-pmu_8_1-.patch
Normal file
166
target-arm-Add-_aa64_-and-_any_-versions-of-pmu_8_1-.patch
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
From 515975da851ca9567053bcf0487fde4447dfdc4f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 14 Feb 2020 17:51:04 +0000
|
||||||
|
Subject: [PATCH 06/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1
|
||||||
|
isar checks
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Add the 64-bit version of the "is this a v8.1 PMUv3?"
|
||||||
|
ID register check function, and the _any_ version that
|
||||||
|
checks for either AArch32 or AArch64 support. We'll use
|
||||||
|
this in a later commit.
|
||||||
|
|
||||||
|
We don't (yet) do any isar_feature checks on ID_AA64DFR1_EL1,
|
||||||
|
but we move id_aa64dfr1 into the ARMISARegisters struct with
|
||||||
|
id_aa64dfr0, for consistency.
|
||||||
|
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Message-id: 20200214175116.9164-10-peter.maydell@linaro.org
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 3 ++-
|
||||||
|
target/arm/cpu.h | 15 +++++++++++++--
|
||||||
|
target/arm/cpu64.c | 8 ++++----
|
||||||
|
target/arm/helper.c | 12 +++++++-----
|
||||||
|
4 files changed, 26 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index 7e9b85a2..bb2edf4e 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1522,7 +1522,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
|
cpu);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
- cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
|
||||||
|
+ cpu->isar.id_aa64dfr0 =
|
||||||
|
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
|
||||||
|
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
|
||||||
|
cpu->pmceid0 = 0;
|
||||||
|
cpu->pmceid1 = 0;
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 2d8d27e8..230130be 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -868,6 +868,8 @@ struct ARMCPU {
|
||||||
|
uint64_t id_aa64mmfr0;
|
||||||
|
uint64_t id_aa64mmfr1;
|
||||||
|
uint64_t id_aa64mmfr2;
|
||||||
|
+ uint64_t id_aa64dfr0;
|
||||||
|
+ uint64_t id_aa64dfr1;
|
||||||
|
} isar;
|
||||||
|
uint32_t midr;
|
||||||
|
uint32_t revidr;
|
||||||
|
@@ -884,8 +886,6 @@ struct ARMCPU {
|
||||||
|
uint32_t id_mmfr2;
|
||||||
|
uint32_t id_mmfr3;
|
||||||
|
uint32_t id_mmfr4;
|
||||||
|
- uint64_t id_aa64dfr0;
|
||||||
|
- uint64_t id_aa64dfr1;
|
||||||
|
uint64_t id_aa64afr0;
|
||||||
|
uint64_t id_aa64afr1;
|
||||||
|
uint32_t dbgdidr;
|
||||||
|
@@ -3657,6 +3657,17 @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
|
||||||
|
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
|
||||||
|
+{
|
||||||
|
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
|
||||||
|
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
|
||||||
|
+{
|
||||||
|
+ return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Forward to the above feature tests given an ARMCPU pointer.
|
||||||
|
*/
|
||||||
|
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||||
|
index afdabbeb..aa96548f 100644
|
||||||
|
--- a/target/arm/cpu64.c
|
||||||
|
+++ b/target/arm/cpu64.c
|
||||||
|
@@ -137,7 +137,7 @@ static void aarch64_a57_initfn(Object *obj)
|
||||||
|
cpu->isar.id_isar5 = 0x00011121;
|
||||||
|
cpu->isar.id_isar6 = 0;
|
||||||
|
cpu->isar.id_aa64pfr0 = 0x00002222;
|
||||||
|
- cpu->id_aa64dfr0 = 0x10305106;
|
||||||
|
+ cpu->isar.id_aa64dfr0 = 0x10305106;
|
||||||
|
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||||
|
cpu->isar.id_aa64mmfr0 = 0x00001124;
|
||||||
|
cpu->dbgdidr = 0x3516d000;
|
||||||
|
@@ -191,7 +191,7 @@ static void aarch64_a53_initfn(Object *obj)
|
||||||
|
cpu->isar.id_isar5 = 0x00011121;
|
||||||
|
cpu->isar.id_isar6 = 0;
|
||||||
|
cpu->isar.id_aa64pfr0 = 0x00002222;
|
||||||
|
- cpu->id_aa64dfr0 = 0x10305106;
|
||||||
|
+ cpu->isar.id_aa64dfr0 = 0x10305106;
|
||||||
|
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||||
|
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
|
||||||
|
cpu->dbgdidr = 0x3516d000;
|
||||||
|
@@ -244,7 +244,7 @@ static void aarch64_a72_initfn(Object *obj)
|
||||||
|
cpu->isar.id_isar4 = 0x00011142;
|
||||||
|
cpu->isar.id_isar5 = 0x00011121;
|
||||||
|
cpu->isar.id_aa64pfr0 = 0x00002222;
|
||||||
|
- cpu->id_aa64dfr0 = 0x10305106;
|
||||||
|
+ cpu->isar.id_aa64dfr0 = 0x10305106;
|
||||||
|
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||||
|
cpu->isar.id_aa64mmfr0 = 0x00001124;
|
||||||
|
cpu->dbgdidr = 0x3516d000;
|
||||||
|
@@ -276,7 +276,7 @@ static void aarch64_kunpeng_920_initfn(Object *obj)
|
||||||
|
cpu->midr = 0x480fd010;
|
||||||
|
cpu->ctr = 0x84448004;
|
||||||
|
cpu->isar.id_aa64pfr0 = 0x11001111;
|
||||||
|
- cpu->id_aa64dfr0 = 0x110305408;
|
||||||
|
+ cpu->isar.id_aa64dfr0 = 0x110305408;
|
||||||
|
cpu->isar.id_aa64isar0 = 0x10211120;
|
||||||
|
cpu->isar.id_aa64mmfr0 = 0x101125;
|
||||||
|
}
|
||||||
|
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||||
|
index 3f06ca19..a71f4ef6 100644
|
||||||
|
--- a/target/arm/helper.c
|
||||||
|
+++ b/target/arm/helper.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
#include "hw/semihosting/semihost.h"
|
||||||
|
#include "sysemu/cpus.h"
|
||||||
|
#include "sysemu/kvm.h"
|
||||||
|
+#include "sysemu/tcg.h"
|
||||||
|
#include "qemu/range.h"
|
||||||
|
#include "qapi/qapi-commands-machine-target.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
|
@@ -5611,9 +5612,10 @@ static void define_debug_regs(ARMCPU *cpu)
|
||||||
|
* check that if they both exist then they agree.
|
||||||
|
*/
|
||||||
|
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
|
||||||
|
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
|
||||||
|
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
|
||||||
|
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
|
||||||
|
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
|
||||||
|
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
|
||||||
|
+ == ctx_cmps);
|
||||||
|
}
|
||||||
|
|
||||||
|
define_one_arm_cp_reg(cpu, &dbgdidr);
|
||||||
|
@@ -6112,11 +6114,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
|
{ .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = cpu->id_aa64dfr0 },
|
||||||
|
+ .resetvalue = cpu->isar.id_aa64dfr0 },
|
||||||
|
{ .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = cpu->id_aa64dfr1 },
|
||||||
|
+ .resetvalue = cpu->isar.id_aa64dfr1 },
|
||||||
|
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
76
target-arm-Add-and-use-FIELD-definitions-for-ID_AA64.patch
Normal file
76
target-arm-Add-and-use-FIELD-definitions-for-ID_AA64.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
From 4001f3040937094660eab44dbb49b86817317ea9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 14 Feb 2020 17:51:01 +0000
|
||||||
|
Subject: [PATCH 03/13] target/arm: Add and use FIELD definitions for
|
||||||
|
ID_AA64DFR0_EL1
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Add FIELD() definitions for the ID_AA64DFR0_EL1 and use them
|
||||||
|
where we currently have hard-coded bit values.
|
||||||
|
|
||||||
|
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Message-id: 20200214175116.9164-7-peter.maydell@linaro.org
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 2 +-
|
||||||
|
target/arm/cpu.h | 10 ++++++++++
|
||||||
|
target/arm/helper.c | 6 +++---
|
||||||
|
3 files changed, 14 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index 811e5c63..dbd05e01 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1522,7 +1522,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
|
cpu);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
- cpu->id_aa64dfr0 &= ~0xf00;
|
||||||
|
+ cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
|
||||||
|
cpu->id_dfr0 &= ~(0xf << 24);
|
||||||
|
cpu->pmceid0 = 0;
|
||||||
|
cpu->pmceid1 = 0;
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 3e65bc50..91cc02b4 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -1779,6 +1779,16 @@ FIELD(ID_AA64MMFR2, BBM, 52, 4)
|
||||||
|
FIELD(ID_AA64MMFR2, EVT, 56, 4)
|
||||||
|
FIELD(ID_AA64MMFR2, E0PD, 60, 4)
|
||||||
|
|
||||||
|
+FIELD(ID_AA64DFR0, DEBUGVER, 0, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, TRACEVER, 4, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, PMUVER, 8, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, BRPS, 12, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, WRPS, 20, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, CTX_CMPS, 28, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, PMSVER, 32, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)
|
||||||
|
+
|
||||||
|
FIELD(ID_DFR0, COPDBG, 0, 4)
|
||||||
|
FIELD(ID_DFR0, COPSDBG, 4, 4)
|
||||||
|
FIELD(ID_DFR0, MMAPDBG, 8, 4)
|
||||||
|
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||||
|
index c50b1ba1..419be640 100644
|
||||||
|
--- a/target/arm/helper.c
|
||||||
|
+++ b/target/arm/helper.c
|
||||||
|
@@ -5611,9 +5611,9 @@ static void define_debug_regs(ARMCPU *cpu)
|
||||||
|
* check that if they both exist then they agree.
|
||||||
|
*/
|
||||||
|
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
- assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
|
||||||
|
- assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
|
||||||
|
- assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps);
|
||||||
|
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
|
||||||
|
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
|
||||||
|
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
|
||||||
|
}
|
||||||
|
|
||||||
|
define_one_arm_cp_reg(cpu, &dbgdidr);
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
77
target-arm-Add-isar_feature-tests-for-PAN-ATS1E1.patch
Normal file
77
target-arm-Add-isar_feature-tests-for-PAN-ATS1E1.patch
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
From 6f18e959eabf9c752659eb3851f193bf343346c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Date: Sat, 8 Feb 2020 12:57:59 +0000
|
||||||
|
Subject: [PATCH 01/13] target/arm: Add isar_feature tests for PAN + ATS1E1
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Include definitions for all of the bits in ID_MMFR3.
|
||||||
|
We already have a definition for ID_AA64MMFR1.PAN.
|
||||||
|
|
||||||
|
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
|
||||||
|
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Message-id: 20200208125816.14954-4-richard.henderson@linaro.org
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
---
|
||||||
|
target/arm/cpu.h | 29 +++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 29 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 86eb79cd..fe310828 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -1680,6 +1680,15 @@ FIELD(ID_ISAR6, FHM, 8, 4)
|
||||||
|
FIELD(ID_ISAR6, SB, 12, 4)
|
||||||
|
FIELD(ID_ISAR6, SPECRES, 16, 4)
|
||||||
|
|
||||||
|
+FIELD(ID_MMFR3, CMAINTVA, 0, 4)
|
||||||
|
+FIELD(ID_MMFR3, CMAINTSW, 4, 4)
|
||||||
|
+FIELD(ID_MMFR3, BPMAINT, 8, 4)
|
||||||
|
+FIELD(ID_MMFR3, MAINTBCST, 12, 4)
|
||||||
|
+FIELD(ID_MMFR3, PAN, 16, 4)
|
||||||
|
+FIELD(ID_MMFR3, COHWALK, 20, 4)
|
||||||
|
+FIELD(ID_MMFR3, CMEMSZ, 24, 4)
|
||||||
|
+FIELD(ID_MMFR3, SUPERSEC, 28, 4)
|
||||||
|
+
|
||||||
|
FIELD(ID_MMFR4, SPECSEI, 0, 4)
|
||||||
|
FIELD(ID_MMFR4, AC2, 4, 4)
|
||||||
|
FIELD(ID_MMFR4, XNX, 8, 4)
|
||||||
|
@@ -3445,6 +3454,16 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
|
||||||
|
return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
|
||||||
|
+{
|
||||||
|
+ return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) != 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
|
||||||
|
+{
|
||||||
|
+ return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* 64-bit feature tests via id registers.
|
||||||
|
*/
|
||||||
|
@@ -3589,6 +3608,16 @@ static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
|
||||||
|
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline bool isar_feature_aa64_pan(const ARMISARegisters *id)
|
||||||
|
+{
|
||||||
|
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
|
||||||
|
+{
|
||||||
|
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
|
||||||
|
{
|
||||||
|
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
30
target-arm-Add-more-CPU-features.patch
Normal file
30
target-arm-Add-more-CPU-features.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 3eee1e4ff1ca342e760f759c727abc41780d0afa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
Date: Tue, 11 Aug 2020 10:28:10 +0800
|
||||||
|
Subject: [PATCH 9/9] target/arm: Add more CPU features
|
||||||
|
|
||||||
|
Add i8mm, bf16, and dgh CPU features for AArch64.
|
||||||
|
|
||||||
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||||
|
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index dcf9f49e..7ae2d3da 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1132,6 +1132,9 @@ static struct CPUFeatureInfo cpu_features[] = {
|
||||||
|
FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true),
|
||||||
|
FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true),
|
||||||
|
FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("i8mm", ID_AA64ISAR1, I8MM, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("bf16", ID_AA64ISAR1, BF16, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("dgh", ID_AA64ISAR1, DGH, false, 1, 0, false),
|
||||||
|
|
||||||
|
FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true),
|
||||||
|
FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true),
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
160
target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch
Normal file
160
target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
From 79a60f0eeb56faf5d162ca566d1cd9988c3e4d60 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
Date: Thu, 6 Aug 2020 16:14:40 +0800
|
||||||
|
Subject: [PATCH 4/9] target/arm: Allow ID registers to synchronize to KVM
|
||||||
|
|
||||||
|
There are 2 steps to synchronize the values of system registers from
|
||||||
|
CPU state to KVM:
|
||||||
|
1. write to the values of system registers from CPU state to
|
||||||
|
(index,value) list by write_cpustate_to_list;
|
||||||
|
2. write the values in (index,value) list to KVM by
|
||||||
|
write_list_to_kvmstate;
|
||||||
|
|
||||||
|
In step 1, the values of constant system registers are not allowed to
|
||||||
|
write to (index,value) list. However, a constant system register is
|
||||||
|
CONSTANT for guest but not for QEMU, which means, QEMU can set/modify
|
||||||
|
the value of constant system registers that is different from phsical
|
||||||
|
registers when startup. But if KVM is enabled, guest can not read the
|
||||||
|
values of the system registers which QEMU set unless they can be written
|
||||||
|
to (index,value) list. And why not try to write to KVM if kvm_sync is
|
||||||
|
true?
|
||||||
|
|
||||||
|
At the moment we call write_cpustate_to_list, all ID registers are
|
||||||
|
contant, including ID_PFR1_EL1 and ID_AA64PFR0_EL1 because GIC has been
|
||||||
|
initialized. Hence, let's give all ID registers a chance to write to
|
||||||
|
KVM. If the write is successful, then write to (index,value) list.
|
||||||
|
|
||||||
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||||
|
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
---
|
||||||
|
target/arm/helper.c | 31 ++++++++++++++++++++-----------
|
||||||
|
target/arm/kvm.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
target/arm/kvm_arm.h | 3 +++
|
||||||
|
3 files changed, 61 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||||
|
index 459af431..97b6b861 100644
|
||||||
|
--- a/target/arm/helper.c
|
||||||
|
+++ b/target/arm/helper.c
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
#include "arm_ldst.h"
|
||||||
|
#include "exec/cpu_ldst.h"
|
||||||
|
#endif
|
||||||
|
+#include "kvm_arm.h"
|
||||||
|
|
||||||
|
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
|
||||||
|
|
||||||
|
@@ -267,30 +268,38 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
|
||||||
|
ok = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- if (ri->type & ARM_CP_NO_RAW) {
|
||||||
|
+ /*
|
||||||
|
+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
|
||||||
|
+ * where 1<=crm<8, 0<=op2<8. Let's give ID registers a chance to
|
||||||
|
+ * synchronize to kvm.
|
||||||
|
+ */
|
||||||
|
+ if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync &&
|
||||||
|
+ ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && ri->crm > 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
newval = read_raw_cp_reg(&cpu->env, ri);
|
||||||
|
if (kvm_sync) {
|
||||||
|
- /*
|
||||||
|
- * Only sync if the previous list->cpustate sync succeeded.
|
||||||
|
- * Rather than tracking the success/failure state for every
|
||||||
|
- * item in the list, we just recheck "does the raw write we must
|
||||||
|
- * have made in write_list_to_cpustate() read back OK" here.
|
||||||
|
- */
|
||||||
|
- uint64_t oldval = cpu->cpreg_values[i];
|
||||||
|
+ /* Only sync if we can sync to KVM successfully. */
|
||||||
|
+ uint64_t oldval;
|
||||||
|
+ uint64_t kvmval;
|
||||||
|
|
||||||
|
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
if (oldval == newval) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- write_raw_cp_reg(&cpu->env, ri, oldval);
|
||||||
|
- if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
|
||||||
|
+ if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
|
||||||
|
+ kvmval != newval) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- write_raw_cp_reg(&cpu->env, ri, newval);
|
||||||
|
+ kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
|
||||||
|
}
|
||||||
|
cpu->cpreg_values[i] = newval;
|
||||||
|
}
|
||||||
|
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
|
||||||
|
index 4f131f68..229b17ce 100644
|
||||||
|
--- a/target/arm/kvm.c
|
||||||
|
+++ b/target/arm/kvm.c
|
||||||
|
@@ -457,6 +457,44 @@ out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target)
|
||||||
|
+{
|
||||||
|
+ uint32_t v32;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ switch (regidx & KVM_REG_SIZE_MASK) {
|
||||||
|
+ case KVM_REG_SIZE_U32:
|
||||||
|
+ ret = kvm_get_one_reg(CPU(cpu), regidx, &v32);
|
||||||
|
+ if (ret == 0) {
|
||||||
|
+ *target = v32;
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+ case KVM_REG_SIZE_U64:
|
||||||
|
+ return kvm_get_one_reg(CPU(cpu), regidx, target);
|
||||||
|
+ default:
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source)
|
||||||
|
+{
|
||||||
|
+ uint32_t v32;
|
||||||
|
+
|
||||||
|
+ switch (regidx & KVM_REG_SIZE_MASK) {
|
||||||
|
+ case KVM_REG_SIZE_U32:
|
||||||
|
+ v32 = *source;
|
||||||
|
+ if (v32 != *source) {
|
||||||
|
+ error_report("the value of source is too large");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return kvm_set_one_reg(CPU(cpu), regidx, &v32);
|
||||||
|
+ case KVM_REG_SIZE_U64:
|
||||||
|
+ return kvm_set_one_reg(CPU(cpu), regidx, source);
|
||||||
|
+ default:
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
bool write_kvmstate_to_list(ARMCPU *cpu)
|
||||||
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
|
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
|
||||||
|
index 0de5f83e..9b7104d6 100644
|
||||||
|
--- a/target/arm/kvm_arm.h
|
||||||
|
+++ b/target/arm/kvm_arm.h
|
||||||
|
@@ -400,4 +400,7 @@ static inline const char *its_class_name(void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target);
|
||||||
|
+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
248
target-arm-Define-an-aa32_pmu_8_1-isar-feature-test-.patch
Normal file
248
target-arm-Define-an-aa32_pmu_8_1-isar-feature-test-.patch
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
From 2eded1a4deeb5dd8d28414e54948bcf773f6b540 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 14 Feb 2020 17:51:03 +0000
|
||||||
|
Subject: [PATCH 05/13] target/arm: Define an aa32_pmu_8_1 isar feature test
|
||||||
|
function
|
||||||
|
|
||||||
|
Instead of open-coding a check on the ID_DFR0 PerfMon ID register
|
||||||
|
field, create a standardly-named isar_feature for "does AArch32 have
|
||||||
|
a v8.1 PMUv3" and use it.
|
||||||
|
|
||||||
|
This entails moving the id_dfr0 field into the ARMISARegisters struct.
|
||||||
|
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Message-id: 20200214175116.9164-9-peter.maydell@linaro.org
|
||||||
|
---
|
||||||
|
hw/intc/armv7m_nvic.c | 2 +-
|
||||||
|
target/arm/cpu.c | 26 +++++++++++++-------------
|
||||||
|
target/arm/cpu.h | 9 ++++++++-
|
||||||
|
target/arm/cpu64.c | 6 +++---
|
||||||
|
target/arm/helper.c | 5 ++---
|
||||||
|
5 files changed, 27 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
|
||||||
|
index 9f8f0d3f..0741db7b 100644
|
||||||
|
--- a/hw/intc/armv7m_nvic.c
|
||||||
|
+++ b/hw/intc/armv7m_nvic.c
|
||||||
|
@@ -1223,7 +1223,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
|
||||||
|
case 0xd44: /* PFR1. */
|
||||||
|
return cpu->id_pfr1;
|
||||||
|
case 0xd48: /* DFR0. */
|
||||||
|
- return cpu->id_dfr0;
|
||||||
|
+ return cpu->isar.id_dfr0;
|
||||||
|
case 0xd4c: /* AFR0. */
|
||||||
|
return cpu->id_afr0;
|
||||||
|
case 0xd50: /* MMFR0. */
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index 6ad211b1..7e9b85a2 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1523,7 +1523,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
|
||||||
|
- cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
|
||||||
|
+ cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
|
||||||
|
cpu->pmceid0 = 0;
|
||||||
|
cpu->pmceid1 = 0;
|
||||||
|
}
|
||||||
|
@@ -1761,7 +1761,7 @@ static void arm1136_r2_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00050078;
|
||||||
|
cpu->id_pfr0 = 0x111;
|
||||||
|
cpu->id_pfr1 = 0x1;
|
||||||
|
- cpu->id_dfr0 = 0x2;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x2;
|
||||||
|
cpu->id_afr0 = 0x3;
|
||||||
|
cpu->id_mmfr0 = 0x01130003;
|
||||||
|
cpu->id_mmfr1 = 0x10030302;
|
||||||
|
@@ -1793,7 +1793,7 @@ static void arm1136_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00050078;
|
||||||
|
cpu->id_pfr0 = 0x111;
|
||||||
|
cpu->id_pfr1 = 0x1;
|
||||||
|
- cpu->id_dfr0 = 0x2;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x2;
|
||||||
|
cpu->id_afr0 = 0x3;
|
||||||
|
cpu->id_mmfr0 = 0x01130003;
|
||||||
|
cpu->id_mmfr1 = 0x10030302;
|
||||||
|
@@ -1826,7 +1826,7 @@ static void arm1176_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00050078;
|
||||||
|
cpu->id_pfr0 = 0x111;
|
||||||
|
cpu->id_pfr1 = 0x11;
|
||||||
|
- cpu->id_dfr0 = 0x33;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x33;
|
||||||
|
cpu->id_afr0 = 0;
|
||||||
|
cpu->id_mmfr0 = 0x01130003;
|
||||||
|
cpu->id_mmfr1 = 0x10030302;
|
||||||
|
@@ -1856,7 +1856,7 @@ static void arm11mpcore_initfn(Object *obj)
|
||||||
|
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
|
||||||
|
cpu->id_pfr0 = 0x111;
|
||||||
|
cpu->id_pfr1 = 0x1;
|
||||||
|
- cpu->id_dfr0 = 0;
|
||||||
|
+ cpu->isar.id_dfr0 = 0;
|
||||||
|
cpu->id_afr0 = 0x2;
|
||||||
|
cpu->id_mmfr0 = 0x01100103;
|
||||||
|
cpu->id_mmfr1 = 0x10020302;
|
||||||
|
@@ -1888,7 +1888,7 @@ static void cortex_m3_initfn(Object *obj)
|
||||||
|
cpu->pmsav7_dregion = 8;
|
||||||
|
cpu->id_pfr0 = 0x00000030;
|
||||||
|
cpu->id_pfr1 = 0x00000200;
|
||||||
|
- cpu->id_dfr0 = 0x00100000;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x00100000;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
cpu->id_mmfr0 = 0x00000030;
|
||||||
|
cpu->id_mmfr1 = 0x00000000;
|
||||||
|
@@ -1919,7 +1919,7 @@ static void cortex_m4_initfn(Object *obj)
|
||||||
|
cpu->isar.mvfr2 = 0x00000000;
|
||||||
|
cpu->id_pfr0 = 0x00000030;
|
||||||
|
cpu->id_pfr1 = 0x00000200;
|
||||||
|
- cpu->id_dfr0 = 0x00100000;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x00100000;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
cpu->id_mmfr0 = 0x00000030;
|
||||||
|
cpu->id_mmfr1 = 0x00000000;
|
||||||
|
@@ -1952,7 +1952,7 @@ static void cortex_m33_initfn(Object *obj)
|
||||||
|
cpu->isar.mvfr2 = 0x00000040;
|
||||||
|
cpu->id_pfr0 = 0x00000030;
|
||||||
|
cpu->id_pfr1 = 0x00000210;
|
||||||
|
- cpu->id_dfr0 = 0x00200000;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x00200000;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
cpu->id_mmfr0 = 0x00101F40;
|
||||||
|
cpu->id_mmfr1 = 0x00000000;
|
||||||
|
@@ -2003,7 +2003,7 @@ static void cortex_r5_initfn(Object *obj)
|
||||||
|
cpu->midr = 0x411fc153; /* r1p3 */
|
||||||
|
cpu->id_pfr0 = 0x0131;
|
||||||
|
cpu->id_pfr1 = 0x001;
|
||||||
|
- cpu->id_dfr0 = 0x010400;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x010400;
|
||||||
|
cpu->id_afr0 = 0x0;
|
||||||
|
cpu->id_mmfr0 = 0x0210030;
|
||||||
|
cpu->id_mmfr1 = 0x00000000;
|
||||||
|
@@ -2058,7 +2058,7 @@ static void cortex_a8_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00c50078;
|
||||||
|
cpu->id_pfr0 = 0x1031;
|
||||||
|
cpu->id_pfr1 = 0x11;
|
||||||
|
- cpu->id_dfr0 = 0x400;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x400;
|
||||||
|
cpu->id_afr0 = 0;
|
||||||
|
cpu->id_mmfr0 = 0x31100003;
|
||||||
|
cpu->id_mmfr1 = 0x20000000;
|
||||||
|
@@ -2131,7 +2131,7 @@ static void cortex_a9_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00c50078;
|
||||||
|
cpu->id_pfr0 = 0x1031;
|
||||||
|
cpu->id_pfr1 = 0x11;
|
||||||
|
- cpu->id_dfr0 = 0x000;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x000;
|
||||||
|
cpu->id_afr0 = 0;
|
||||||
|
cpu->id_mmfr0 = 0x00100103;
|
||||||
|
cpu->id_mmfr1 = 0x20000000;
|
||||||
|
@@ -2196,7 +2196,7 @@ static void cortex_a7_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00c50078;
|
||||||
|
cpu->id_pfr0 = 0x00001131;
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
- cpu->id_dfr0 = 0x02010555;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x02010555;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
cpu->id_mmfr0 = 0x10101105;
|
||||||
|
cpu->id_mmfr1 = 0x40000000;
|
||||||
|
@@ -2242,7 +2242,7 @@ static void cortex_a15_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00c50078;
|
||||||
|
cpu->id_pfr0 = 0x00001131;
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
- cpu->id_dfr0 = 0x02010555;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x02010555;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
cpu->id_mmfr0 = 0x10201105;
|
||||||
|
cpu->id_mmfr1 = 0x20000000;
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 91cc02b4..2d8d27e8 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -860,6 +860,7 @@ struct ARMCPU {
|
||||||
|
uint32_t mvfr0;
|
||||||
|
uint32_t mvfr1;
|
||||||
|
uint32_t mvfr2;
|
||||||
|
+ uint32_t id_dfr0;
|
||||||
|
uint64_t id_aa64isar0;
|
||||||
|
uint64_t id_aa64isar1;
|
||||||
|
uint64_t id_aa64pfr0;
|
||||||
|
@@ -875,7 +876,6 @@ struct ARMCPU {
|
||||||
|
uint32_t reset_sctlr;
|
||||||
|
uint32_t id_pfr0;
|
||||||
|
uint32_t id_pfr1;
|
||||||
|
- uint32_t id_dfr0;
|
||||||
|
uint64_t pmceid0;
|
||||||
|
uint64_t pmceid1;
|
||||||
|
uint32_t id_afr0;
|
||||||
|
@@ -3491,6 +3491,13 @@ static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
|
||||||
|
return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
|
||||||
|
+{
|
||||||
|
+ /* 0xf means "non-standard IMPDEF PMU" */
|
||||||
|
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
|
||||||
|
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* 64-bit feature tests via id registers.
|
||||||
|
*/
|
||||||
|
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||||
|
index 15f4ee92..afdabbeb 100644
|
||||||
|
--- a/target/arm/cpu64.c
|
||||||
|
+++ b/target/arm/cpu64.c
|
||||||
|
@@ -123,7 +123,7 @@ static void aarch64_a57_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00c50838;
|
||||||
|
cpu->id_pfr0 = 0x00000131;
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
- cpu->id_dfr0 = 0x03010066;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x03010066;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
cpu->id_mmfr0 = 0x10101105;
|
||||||
|
cpu->id_mmfr1 = 0x40000000;
|
||||||
|
@@ -177,7 +177,7 @@ static void aarch64_a53_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00c50838;
|
||||||
|
cpu->id_pfr0 = 0x00000131;
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
- cpu->id_dfr0 = 0x03010066;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x03010066;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
cpu->id_mmfr0 = 0x10101105;
|
||||||
|
cpu->id_mmfr1 = 0x40000000;
|
||||||
|
@@ -231,7 +231,7 @@ static void aarch64_a72_initfn(Object *obj)
|
||||||
|
cpu->reset_sctlr = 0x00c50838;
|
||||||
|
cpu->id_pfr0 = 0x00000131;
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
- cpu->id_dfr0 = 0x03010066;
|
||||||
|
+ cpu->isar.id_dfr0 = 0x03010066;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
cpu->id_mmfr0 = 0x10201105;
|
||||||
|
cpu->id_mmfr1 = 0x40000000;
|
||||||
|
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||||
|
index 419be640..3f06ca19 100644
|
||||||
|
--- a/target/arm/helper.c
|
||||||
|
+++ b/target/arm/helper.c
|
||||||
|
@@ -5907,7 +5907,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
|
{ .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = cpu->id_dfr0 },
|
||||||
|
+ .resetvalue = cpu->isar.id_dfr0 },
|
||||||
|
{ .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
@@ -6050,8 +6050,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
|
} else {
|
||||||
|
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
|
||||||
|
}
|
||||||
|
- if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
|
||||||
|
- FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
|
||||||
|
+ if (cpu_isar_feature(aa32_pmu_8_1, cpu)) {
|
||||||
|
ARMCPRegInfo v81_pmu_regs[] = {
|
||||||
|
{ .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
|
||||||
|
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
57
target-arm-Enable-ARMv8.2-ATS1E1-in-cpu-max.patch
Normal file
57
target-arm-Enable-ARMv8.2-ATS1E1-in-cpu-max.patch
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
From 69eedbfc873ded9bf35439b813e9f6a7431dc727 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Date: Sat, 8 Feb 2020 12:58:12 +0000
|
||||||
|
Subject: [PATCH 09/13] target/arm: Enable ARMv8.2-ATS1E1 in -cpu max
|
||||||
|
|
||||||
|
This includes enablement of ARMv8.1-PAN.
|
||||||
|
|
||||||
|
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Message-id: 20200208125816.14954-17-richard.henderson@linaro.org
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 4 ++++
|
||||||
|
target/arm/cpu64.c | 5 +++++
|
||||||
|
2 files changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index a23c71db..119bd275 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -2484,6 +2484,10 @@ static void arm_max_initfn(Object *obj)
|
||||||
|
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
|
||||||
|
cpu->isar.mvfr2 = t;
|
||||||
|
|
||||||
|
+ t = cpu->id_mmfr3;
|
||||||
|
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
|
||||||
|
+ cpu->id_mmfr3 = t;
|
||||||
|
+
|
||||||
|
t = cpu->id_mmfr4;
|
||||||
|
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
|
||||||
|
cpu->id_mmfr4 = t;
|
||||||
|
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||||
|
index 7ad8b5e2..a0d07fd7 100644
|
||||||
|
--- a/target/arm/cpu64.c
|
||||||
|
+++ b/target/arm/cpu64.c
|
||||||
|
@@ -362,6 +362,7 @@ static void aarch64_max_initfn(Object *obj)
|
||||||
|
t = cpu->isar.id_aa64mmfr1;
|
||||||
|
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
|
||||||
|
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
|
||||||
|
+ t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
|
||||||
|
cpu->isar.id_aa64mmfr1 = t;
|
||||||
|
|
||||||
|
/* Replicate the same data to the 32-bit id registers. */
|
||||||
|
@@ -382,6 +383,10 @@ static void aarch64_max_initfn(Object *obj)
|
||||||
|
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
|
||||||
|
cpu->isar.id_isar6 = u;
|
||||||
|
|
||||||
|
+ u = cpu->id_mmfr3;
|
||||||
|
+ u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
|
||||||
|
+ cpu->id_mmfr3 = u;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
|
||||||
|
* so do not set MVFR1.FPHP. Strictly speaking this is not legal,
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
158
target-arm-Move-DBGDIDR-into-ARMISARegisters.patch
Normal file
158
target-arm-Move-DBGDIDR-into-ARMISARegisters.patch
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
From df641941e6fd7fef78e5c77c9a809a7a8e148589 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 14 Feb 2020 17:51:06 +0000
|
||||||
|
Subject: [PATCH 08/13] target/arm: Move DBGDIDR into ARMISARegisters
|
||||||
|
|
||||||
|
We're going to want to read the DBGDIDR register from KVM in
|
||||||
|
a subsequent commit, which means it needs to be in the
|
||||||
|
ARMISARegisters sub-struct. Move it.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Message-id: 20200214175116.9164-12-peter.maydell@linaro.org
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 8 ++++----
|
||||||
|
target/arm/cpu.h | 2 +-
|
||||||
|
target/arm/cpu64.c | 6 +++---
|
||||||
|
target/arm/helper.c | 2 +-
|
||||||
|
target/arm/internals.h | 6 +++---
|
||||||
|
5 files changed, 12 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index bb2edf4e..a23c71db 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -2070,7 +2070,7 @@ static void cortex_a8_initfn(Object *obj)
|
||||||
|
cpu->isar.id_isar2 = 0x21232031;
|
||||||
|
cpu->isar.id_isar3 = 0x11112131;
|
||||||
|
cpu->isar.id_isar4 = 0x00111142;
|
||||||
|
- cpu->dbgdidr = 0x15141000;
|
||||||
|
+ cpu->isar.dbgdidr = 0x15141000;
|
||||||
|
cpu->clidr = (1 << 27) | (2 << 24) | 3;
|
||||||
|
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
|
||||||
|
cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
|
||||||
|
@@ -2143,7 +2143,7 @@ static void cortex_a9_initfn(Object *obj)
|
||||||
|
cpu->isar.id_isar2 = 0x21232041;
|
||||||
|
cpu->isar.id_isar3 = 0x11112131;
|
||||||
|
cpu->isar.id_isar4 = 0x00111142;
|
||||||
|
- cpu->dbgdidr = 0x35141000;
|
||||||
|
+ cpu->isar.dbgdidr = 0x35141000;
|
||||||
|
cpu->clidr = (1 << 27) | (1 << 24) | 3;
|
||||||
|
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
|
||||||
|
cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
|
||||||
|
@@ -2211,7 +2211,7 @@ static void cortex_a7_initfn(Object *obj)
|
||||||
|
cpu->isar.id_isar2 = 0x21232041;
|
||||||
|
cpu->isar.id_isar3 = 0x11112131;
|
||||||
|
cpu->isar.id_isar4 = 0x10011142;
|
||||||
|
- cpu->dbgdidr = 0x3515f005;
|
||||||
|
+ cpu->isar.dbgdidr = 0x3515f005;
|
||||||
|
cpu->clidr = 0x0a200023;
|
||||||
|
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
|
||||||
|
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
|
||||||
|
@@ -2254,7 +2254,7 @@ static void cortex_a15_initfn(Object *obj)
|
||||||
|
cpu->isar.id_isar2 = 0x21232041;
|
||||||
|
cpu->isar.id_isar3 = 0x11112131;
|
||||||
|
cpu->isar.id_isar4 = 0x10011142;
|
||||||
|
- cpu->dbgdidr = 0x3515f021;
|
||||||
|
+ cpu->isar.dbgdidr = 0x3515f021;
|
||||||
|
cpu->clidr = 0x0a200023;
|
||||||
|
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
|
||||||
|
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 4b1ae32b..3040aa40 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -861,6 +861,7 @@ struct ARMCPU {
|
||||||
|
uint32_t mvfr1;
|
||||||
|
uint32_t mvfr2;
|
||||||
|
uint32_t id_dfr0;
|
||||||
|
+ uint32_t dbgdidr;
|
||||||
|
uint64_t id_aa64isar0;
|
||||||
|
uint64_t id_aa64isar1;
|
||||||
|
uint64_t id_aa64pfr0;
|
||||||
|
@@ -888,7 +889,6 @@ struct ARMCPU {
|
||||||
|
uint32_t id_mmfr4;
|
||||||
|
uint64_t id_aa64afr0;
|
||||||
|
uint64_t id_aa64afr1;
|
||||||
|
- uint32_t dbgdidr;
|
||||||
|
uint32_t clidr;
|
||||||
|
uint64_t mp_affinity; /* MP ID without feature bits */
|
||||||
|
/* The elements of this array are the CCSIDR values for each cache,
|
||||||
|
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||||
|
index aa96548f..7ad8b5e2 100644
|
||||||
|
--- a/target/arm/cpu64.c
|
||||||
|
+++ b/target/arm/cpu64.c
|
||||||
|
@@ -140,7 +140,7 @@ static void aarch64_a57_initfn(Object *obj)
|
||||||
|
cpu->isar.id_aa64dfr0 = 0x10305106;
|
||||||
|
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||||
|
cpu->isar.id_aa64mmfr0 = 0x00001124;
|
||||||
|
- cpu->dbgdidr = 0x3516d000;
|
||||||
|
+ cpu->isar.dbgdidr = 0x3516d000;
|
||||||
|
cpu->clidr = 0x0a200023;
|
||||||
|
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
|
||||||
|
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
|
||||||
|
@@ -194,7 +194,7 @@ static void aarch64_a53_initfn(Object *obj)
|
||||||
|
cpu->isar.id_aa64dfr0 = 0x10305106;
|
||||||
|
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||||
|
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
|
||||||
|
- cpu->dbgdidr = 0x3516d000;
|
||||||
|
+ cpu->isar.dbgdidr = 0x3516d000;
|
||||||
|
cpu->clidr = 0x0a200023;
|
||||||
|
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
|
||||||
|
cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
|
||||||
|
@@ -247,7 +247,7 @@ static void aarch64_a72_initfn(Object *obj)
|
||||||
|
cpu->isar.id_aa64dfr0 = 0x10305106;
|
||||||
|
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||||
|
cpu->isar.id_aa64mmfr0 = 0x00001124;
|
||||||
|
- cpu->dbgdidr = 0x3516d000;
|
||||||
|
+ cpu->isar.dbgdidr = 0x3516d000;
|
||||||
|
cpu->clidr = 0x0a200023;
|
||||||
|
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
|
||||||
|
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
|
||||||
|
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||||
|
index c1ff4b6b..60ff7c0f 100644
|
||||||
|
--- a/target/arm/helper.c
|
||||||
|
+++ b/target/arm/helper.c
|
||||||
|
@@ -5597,7 +5597,7 @@ static void define_debug_regs(ARMCPU *cpu)
|
||||||
|
ARMCPRegInfo dbgdidr = {
|
||||||
|
.name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
|
||||||
|
.access = PL0_R, .accessfn = access_tda,
|
||||||
|
- .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr,
|
||||||
|
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Note that all these register fields hold "number of Xs minus 1". */
|
||||||
|
diff --git a/target/arm/internals.h b/target/arm/internals.h
|
||||||
|
index a72d0a6c..1d01ecc4 100644
|
||||||
|
--- a/target/arm/internals.h
|
||||||
|
+++ b/target/arm/internals.h
|
||||||
|
@@ -867,7 +867,7 @@ static inline int arm_num_brps(ARMCPU *cpu)
|
||||||
|
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
|
||||||
|
} else {
|
||||||
|
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, BRPS) + 1;
|
||||||
|
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -881,7 +881,7 @@ static inline int arm_num_wrps(ARMCPU *cpu)
|
||||||
|
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
|
||||||
|
} else {
|
||||||
|
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, WRPS) + 1;
|
||||||
|
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -895,7 +895,7 @@ static inline int arm_num_ctx_cmps(ARMCPU *cpu)
|
||||||
|
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
|
||||||
|
} else {
|
||||||
|
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, CTX_CMPS) + 1;
|
||||||
|
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
131
target-arm-Read-debug-related-ID-registers-from-KVM.patch
Normal file
131
target-arm-Read-debug-related-ID-registers-from-KVM.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
From 9cda8af5af9e95e7b0ff683d0fb661c1ffcba8d8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 14 Feb 2020 17:51:07 +0000
|
||||||
|
Subject: [PATCH 11/13] target/arm: Read debug-related ID registers from KVM
|
||||||
|
|
||||||
|
Now we have isar_feature test functions that look at fields in the
|
||||||
|
ID_AA64DFR0_EL1 and ID_DFR0 ID registers, add the code that reads
|
||||||
|
these register values from KVM so that the checks behave correctly
|
||||||
|
when we're using KVM.
|
||||||
|
|
||||||
|
No isar_feature function tests ID_AA64DFR1_EL1 or DBGDIDR yet, but we
|
||||||
|
add it to maintain the invariant that every field in the
|
||||||
|
ARMISARegisters struct is populated for a KVM CPU and can be relied
|
||||||
|
on. This requirement isn't actually written down yet, so add a note
|
||||||
|
to the relevant comment.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Message-id: 20200214175116.9164-13-peter.maydell@linaro.org
|
||||||
|
---
|
||||||
|
target/arm/cpu.h | 5 +++++
|
||||||
|
target/arm/kvm32.c | 8 ++++++++
|
||||||
|
target/arm/kvm64.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 49 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index a78c30c3..56d8cd8c 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -848,6 +848,11 @@ struct ARMCPU {
|
||||||
|
* prefix means a constant register.
|
||||||
|
* Some of these registers are split out into a substructure that
|
||||||
|
* is shared with the translators to control the ISA.
|
||||||
|
+ *
|
||||||
|
+ * Note that if you add an ID register to the ARMISARegisters struct
|
||||||
|
+ * you need to also update the 32-bit and 64-bit versions of the
|
||||||
|
+ * kvm_arm_get_host_cpu_features() function to correctly populate the
|
||||||
|
+ * field by reading the value from the KVM vCPU.
|
||||||
|
*/
|
||||||
|
struct ARMISARegisters {
|
||||||
|
uint32_t id_isar0;
|
||||||
|
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
|
||||||
|
index 2247148e..e984d52d 100644
|
||||||
|
--- a/target/arm/kvm32.c
|
||||||
|
+++ b/target/arm/kvm32.c
|
||||||
|
@@ -93,6 +93,9 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
ahcf->isar.id_isar6 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
|
||||||
|
+ ARM_CP15_REG32(0, 0, 1, 2));
|
||||||
|
+
|
||||||
|
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0,
|
||||||
|
KVM_REG_ARM | KVM_REG_SIZE_U32 |
|
||||||
|
KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0);
|
||||||
|
@@ -121,6 +124,11 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
ahcf->isar.id_mmfr4 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * There is no way to read DBGDIDR, because currently 32-bit KVM
|
||||||
|
+ * doesn't implement debug at all. Leave it at zero.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
kvm_arm_destroy_scratch_host_vcpu(fdarray);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
|
||||||
|
index 276d1466..2a88b8df 100644
|
||||||
|
--- a/target/arm/kvm64.c
|
||||||
|
+++ b/target/arm/kvm64.c
|
||||||
|
@@ -533,6 +533,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
} else {
|
||||||
|
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1,
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 4, 1));
|
||||||
|
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 5, 0));
|
||||||
|
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 5, 1));
|
||||||
|
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0,
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 6, 0));
|
||||||
|
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
|
||||||
|
@@ -551,6 +555,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
* than skipping the reads and leaving 0, as we must avoid
|
||||||
|
* considering the values in every case.
|
||||||
|
*/
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 1, 2));
|
||||||
|
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 1, 4));
|
||||||
|
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
|
||||||
|
@@ -582,6 +588,36 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 3, 1));
|
||||||
|
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2,
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 3, 2));
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * DBGDIDR is a bit complicated because the kernel doesn't
|
||||||
|
+ * provide an accessor for it in 64-bit mode, which is what this
|
||||||
|
+ * scratch VM is in, and there's no architected "64-bit sysreg
|
||||||
|
+ * which reads the same as the 32-bit register" the way there is
|
||||||
|
+ * for other ID registers. Instead we synthesize a value from the
|
||||||
|
+ * AArch64 ID_AA64DFR0, the same way the kernel code in
|
||||||
|
+ * arch/arm64/kvm/sys_regs.c:trap_dbgidr() does.
|
||||||
|
+ * We only do this if the CPU supports AArch32 at EL1.
|
||||||
|
+ */
|
||||||
|
+ if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) {
|
||||||
|
+ int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS);
|
||||||
|
+ int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS);
|
||||||
|
+ int ctx_cmps =
|
||||||
|
+ FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS);
|
||||||
|
+ int version = 6; /* ARMv8 debug architecture */
|
||||||
|
+ bool has_el3 =
|
||||||
|
+ !!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3);
|
||||||
|
+ uint32_t dbgdidr = 0;
|
||||||
|
+
|
||||||
|
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps);
|
||||||
|
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, BRPS, brps);
|
||||||
|
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, CTX_CMPS, ctx_cmps);
|
||||||
|
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, VERSION, version);
|
||||||
|
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, NSUHD_IMP, has_el3);
|
||||||
|
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, SE_IMP, has_el3);
|
||||||
|
+ dbgdidr |= (1 << 15); /* RES1 bit */
|
||||||
|
+ ahcf->isar.dbgdidr = dbgdidr;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
kvm_arm_destroy_scratch_host_vcpu(fdarray);
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
186
target-arm-Stop-assuming-DBGDIDR-always-exists.patch
Normal file
186
target-arm-Stop-assuming-DBGDIDR-always-exists.patch
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
From 1d4d4cda9637ec09f8cf30785f68b58cd46815c8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 14 Feb 2020 17:51:05 +0000
|
||||||
|
Subject: [PATCH 07/13] target/arm: Stop assuming DBGDIDR always exists
|
||||||
|
|
||||||
|
The AArch32 DBGDIDR defines properties like the number of
|
||||||
|
breakpoints, watchpoints and context-matching comparators. On an
|
||||||
|
AArch64 CPU, the register may not even exist if AArch32 is not
|
||||||
|
supported at EL1.
|
||||||
|
|
||||||
|
Currently we hard-code use of DBGDIDR to identify the number of
|
||||||
|
breakpoints etc; this works for all our TCG CPUs, but will break if
|
||||||
|
we ever add an AArch64-only CPU. We also have an assert() that the
|
||||||
|
AArch32 and AArch64 registers match, which currently works only by
|
||||||
|
luck for KVM because we don't populate either of these ID registers
|
||||||
|
from the KVM vCPU and so they are both zero.
|
||||||
|
|
||||||
|
Clean this up so we have functions for finding the number
|
||||||
|
of breakpoints, watchpoints and context comparators which look
|
||||||
|
in the appropriate ID register.
|
||||||
|
|
||||||
|
This allows us to drop the "check that AArch64 and AArch32 agree
|
||||||
|
on the number of breakpoints etc" asserts:
|
||||||
|
* we no longer look at the AArch32 versions unless that's the
|
||||||
|
right place to be looking
|
||||||
|
* it's valid to have a CPU (eg AArch64-only) where they don't match
|
||||||
|
* we shouldn't have been asserting the validity of ID registers
|
||||||
|
in a codepath used with KVM anyway
|
||||||
|
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Message-id: 20200214175116.9164-11-peter.maydell@linaro.org
|
||||||
|
---
|
||||||
|
target/arm/cpu.h | 7 +++++++
|
||||||
|
target/arm/debug_helper.c | 6 +++---
|
||||||
|
target/arm/helper.c | 21 +++++---------------
|
||||||
|
target/arm/internals.h | 42 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 57 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 230130be..4b1ae32b 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -1798,6 +1798,13 @@ FIELD(ID_DFR0, MPROFDBG, 20, 4)
|
||||||
|
FIELD(ID_DFR0, PERFMON, 24, 4)
|
||||||
|
FIELD(ID_DFR0, TRACEFILT, 28, 4)
|
||||||
|
|
||||||
|
+FIELD(DBGDIDR, SE_IMP, 12, 1)
|
||||||
|
+FIELD(DBGDIDR, NSUHD_IMP, 14, 1)
|
||||||
|
+FIELD(DBGDIDR, VERSION, 16, 4)
|
||||||
|
+FIELD(DBGDIDR, CTX_CMPS, 20, 4)
|
||||||
|
+FIELD(DBGDIDR, BRPS, 24, 4)
|
||||||
|
+FIELD(DBGDIDR, WRPS, 28, 4)
|
||||||
|
+
|
||||||
|
FIELD(MVFR0, SIMDREG, 0, 4)
|
||||||
|
FIELD(MVFR0, FPSP, 4, 4)
|
||||||
|
FIELD(MVFR0, FPDP, 8, 4)
|
||||||
|
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
|
||||||
|
index dde80273..3f8f667d 100644
|
||||||
|
--- a/target/arm/debug_helper.c
|
||||||
|
+++ b/target/arm/debug_helper.c
|
||||||
|
@@ -16,8 +16,8 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
|
||||||
|
{
|
||||||
|
CPUARMState *env = &cpu->env;
|
||||||
|
uint64_t bcr = env->cp15.dbgbcr[lbn];
|
||||||
|
- int brps = extract32(cpu->dbgdidr, 24, 4);
|
||||||
|
- int ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
|
||||||
|
+ int brps = arm_num_brps(cpu);
|
||||||
|
+ int ctx_cmps = arm_num_ctx_cmps(cpu);
|
||||||
|
int bt;
|
||||||
|
uint32_t contextidr;
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
|
||||||
|
* case DBGWCR<n>_EL1.LBN must indicate that breakpoint).
|
||||||
|
* We choose the former.
|
||||||
|
*/
|
||||||
|
- if (lbn > brps || lbn < (brps - ctx_cmps)) {
|
||||||
|
+ if (lbn >= brps || lbn < (brps - ctx_cmps)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||||
|
index a71f4ef6..c1ff4b6b 100644
|
||||||
|
--- a/target/arm/helper.c
|
||||||
|
+++ b/target/arm/helper.c
|
||||||
|
@@ -5601,23 +5601,12 @@ static void define_debug_regs(ARMCPU *cpu)
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Note that all these register fields hold "number of Xs minus 1". */
|
||||||
|
- brps = extract32(cpu->dbgdidr, 24, 4);
|
||||||
|
- wrps = extract32(cpu->dbgdidr, 28, 4);
|
||||||
|
- ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
|
||||||
|
+ brps = arm_num_brps(cpu);
|
||||||
|
+ wrps = arm_num_wrps(cpu);
|
||||||
|
+ ctx_cmps = arm_num_ctx_cmps(cpu);
|
||||||
|
|
||||||
|
assert(ctx_cmps <= brps);
|
||||||
|
|
||||||
|
- /* The DBGDIDR and ID_AA64DFR0_EL1 define various properties
|
||||||
|
- * of the debug registers such as number of breakpoints;
|
||||||
|
- * check that if they both exist then they agree.
|
||||||
|
- */
|
||||||
|
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
|
||||||
|
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
|
||||||
|
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
|
||||||
|
- == ctx_cmps);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
define_one_arm_cp_reg(cpu, &dbgdidr);
|
||||||
|
define_arm_cp_regs(cpu, debug_cp_reginfo);
|
||||||
|
|
||||||
|
@@ -5625,7 +5614,7 @@ static void define_debug_regs(ARMCPU *cpu)
|
||||||
|
define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; i < brps + 1; i++) {
|
||||||
|
+ for (i = 0; i < brps; i++) {
|
||||||
|
ARMCPRegInfo dbgregs[] = {
|
||||||
|
{ .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
|
||||||
|
@@ -5644,7 +5633,7 @@ static void define_debug_regs(ARMCPU *cpu)
|
||||||
|
define_arm_cp_regs(cpu, dbgregs);
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; i < wrps + 1; i++) {
|
||||||
|
+ for (i = 0; i < wrps; i++) {
|
||||||
|
ARMCPRegInfo dbgregs[] = {
|
||||||
|
{ .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
|
||||||
|
diff --git a/target/arm/internals.h b/target/arm/internals.h
|
||||||
|
index 232d9638..a72d0a6c 100644
|
||||||
|
--- a/target/arm/internals.h
|
||||||
|
+++ b/target/arm/internals.h
|
||||||
|
@@ -857,6 +857,48 @@ static inline uint32_t arm_debug_exception_fsr(CPUARMState *env)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * arm_num_brps: Return number of implemented breakpoints.
|
||||||
|
+ * Note that the ID register BRPS field is "number of bps - 1",
|
||||||
|
+ * and we return the actual number of breakpoints.
|
||||||
|
+ */
|
||||||
|
+static inline int arm_num_brps(ARMCPU *cpu)
|
||||||
|
+{
|
||||||
|
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
|
||||||
|
+ } else {
|
||||||
|
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, BRPS) + 1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * arm_num_wrps: Return number of implemented watchpoints.
|
||||||
|
+ * Note that the ID register WRPS field is "number of wps - 1",
|
||||||
|
+ * and we return the actual number of watchpoints.
|
||||||
|
+ */
|
||||||
|
+static inline int arm_num_wrps(ARMCPU *cpu)
|
||||||
|
+{
|
||||||
|
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
|
||||||
|
+ } else {
|
||||||
|
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, WRPS) + 1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * arm_num_ctx_cmps: Return number of implemented context comparators.
|
||||||
|
+ * Note that the ID register CTX_CMPS field is "number of cmps - 1",
|
||||||
|
+ * and we return the actual number of comparators.
|
||||||
|
+ */
|
||||||
|
+static inline int arm_num_ctx_cmps(ARMCPU *cpu)
|
||||||
|
+{
|
||||||
|
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
|
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
|
||||||
|
+ } else {
|
||||||
|
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, CTX_CMPS) + 1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Note make_memop_idx reserves 4 bits for mmu_idx, and MO_BSWAP is bit 3.
|
||||||
|
* Thus a TCGMemOpIdx, without any MO_ALIGN bits, fits in 8 bits.
|
||||||
|
*/
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
453
target-arm-Test-correct-register-in-aa32_pan-and-aa3.patch
Normal file
453
target-arm-Test-correct-register-in-aa32_pan-and-aa3.patch
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
From 2bc630dc858bd0c010b7c375ebf1e8f4b4e0e346 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 14 Feb 2020 17:51:13 +0000
|
||||||
|
Subject: [PATCH 10/13] target/arm: Test correct register in aa32_pan and
|
||||||
|
aa32_ats1e1 checks
|
||||||
|
|
||||||
|
The isar_feature_aa32_pan and isar_feature_aa32_ats1e1 functions
|
||||||
|
are supposed to be testing fields in ID_MMFR3; but a cut-and-paste
|
||||||
|
error meant we were looking at MVFR0 instead.
|
||||||
|
|
||||||
|
Fix the functions to look at the right register; this requires
|
||||||
|
us to move at least id_mmfr3 to the ARMISARegisters struct; we
|
||||||
|
choose to move all the ID_MMFRn registers for consistency.
|
||||||
|
|
||||||
|
Fixes: 3d6ad6bb466f
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Message-id: 20200214175116.9164-19-peter.maydell@linaro.org
|
||||||
|
---
|
||||||
|
hw/intc/armv7m_nvic.c | 8 ++--
|
||||||
|
target/arm/cpu.c | 96 +++++++++++++++++++++----------------------
|
||||||
|
target/arm/cpu.h | 14 +++----
|
||||||
|
target/arm/cpu64.c | 28 ++++++-------
|
||||||
|
target/arm/helper.c | 12 +++---
|
||||||
|
target/arm/kvm32.c | 17 ++++++++
|
||||||
|
target/arm/kvm64.c | 10 +++++
|
||||||
|
7 files changed, 106 insertions(+), 79 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
|
||||||
|
index 0741db7b..f7ef6ad1 100644
|
||||||
|
--- a/hw/intc/armv7m_nvic.c
|
||||||
|
+++ b/hw/intc/armv7m_nvic.c
|
||||||
|
@@ -1227,13 +1227,13 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
|
||||||
|
case 0xd4c: /* AFR0. */
|
||||||
|
return cpu->id_afr0;
|
||||||
|
case 0xd50: /* MMFR0. */
|
||||||
|
- return cpu->id_mmfr0;
|
||||||
|
+ return cpu->isar.id_mmfr0;
|
||||||
|
case 0xd54: /* MMFR1. */
|
||||||
|
- return cpu->id_mmfr1;
|
||||||
|
+ return cpu->isar.id_mmfr1;
|
||||||
|
case 0xd58: /* MMFR2. */
|
||||||
|
- return cpu->id_mmfr2;
|
||||||
|
+ return cpu->isar.id_mmfr2;
|
||||||
|
case 0xd5c: /* MMFR3. */
|
||||||
|
- return cpu->id_mmfr3;
|
||||||
|
+ return cpu->isar.id_mmfr3;
|
||||||
|
case 0xd60: /* ISAR0. */
|
||||||
|
return cpu->isar.id_isar0;
|
||||||
|
case 0xd64: /* ISAR1. */
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index 119bd275..c3728e3d 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1764,9 +1764,9 @@ static void arm1136_r2_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x1;
|
||||||
|
cpu->isar.id_dfr0 = 0x2;
|
||||||
|
cpu->id_afr0 = 0x3;
|
||||||
|
- cpu->id_mmfr0 = 0x01130003;
|
||||||
|
- cpu->id_mmfr1 = 0x10030302;
|
||||||
|
- cpu->id_mmfr2 = 0x01222110;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x01130003;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x10030302;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01222110;
|
||||||
|
cpu->isar.id_isar0 = 0x00140011;
|
||||||
|
cpu->isar.id_isar1 = 0x12002111;
|
||||||
|
cpu->isar.id_isar2 = 0x11231111;
|
||||||
|
@@ -1796,9 +1796,9 @@ static void arm1136_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x1;
|
||||||
|
cpu->isar.id_dfr0 = 0x2;
|
||||||
|
cpu->id_afr0 = 0x3;
|
||||||
|
- cpu->id_mmfr0 = 0x01130003;
|
||||||
|
- cpu->id_mmfr1 = 0x10030302;
|
||||||
|
- cpu->id_mmfr2 = 0x01222110;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x01130003;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x10030302;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01222110;
|
||||||
|
cpu->isar.id_isar0 = 0x00140011;
|
||||||
|
cpu->isar.id_isar1 = 0x12002111;
|
||||||
|
cpu->isar.id_isar2 = 0x11231111;
|
||||||
|
@@ -1829,9 +1829,9 @@ static void arm1176_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x11;
|
||||||
|
cpu->isar.id_dfr0 = 0x33;
|
||||||
|
cpu->id_afr0 = 0;
|
||||||
|
- cpu->id_mmfr0 = 0x01130003;
|
||||||
|
- cpu->id_mmfr1 = 0x10030302;
|
||||||
|
- cpu->id_mmfr2 = 0x01222100;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x01130003;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x10030302;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01222100;
|
||||||
|
cpu->isar.id_isar0 = 0x0140011;
|
||||||
|
cpu->isar.id_isar1 = 0x12002111;
|
||||||
|
cpu->isar.id_isar2 = 0x11231121;
|
||||||
|
@@ -1859,9 +1859,9 @@ static void arm11mpcore_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x1;
|
||||||
|
cpu->isar.id_dfr0 = 0;
|
||||||
|
cpu->id_afr0 = 0x2;
|
||||||
|
- cpu->id_mmfr0 = 0x01100103;
|
||||||
|
- cpu->id_mmfr1 = 0x10020302;
|
||||||
|
- cpu->id_mmfr2 = 0x01222000;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x01100103;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x10020302;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01222000;
|
||||||
|
cpu->isar.id_isar0 = 0x00100011;
|
||||||
|
cpu->isar.id_isar1 = 0x12002111;
|
||||||
|
cpu->isar.id_isar2 = 0x11221011;
|
||||||
|
@@ -1891,10 +1891,10 @@ static void cortex_m3_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x00000200;
|
||||||
|
cpu->isar.id_dfr0 = 0x00100000;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
- cpu->id_mmfr0 = 0x00000030;
|
||||||
|
- cpu->id_mmfr1 = 0x00000000;
|
||||||
|
- cpu->id_mmfr2 = 0x00000000;
|
||||||
|
- cpu->id_mmfr3 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x00000030;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x00000000;
|
||||||
|
cpu->isar.id_isar0 = 0x01141110;
|
||||||
|
cpu->isar.id_isar1 = 0x02111000;
|
||||||
|
cpu->isar.id_isar2 = 0x21112231;
|
||||||
|
@@ -1922,10 +1922,10 @@ static void cortex_m4_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x00000200;
|
||||||
|
cpu->isar.id_dfr0 = 0x00100000;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
- cpu->id_mmfr0 = 0x00000030;
|
||||||
|
- cpu->id_mmfr1 = 0x00000000;
|
||||||
|
- cpu->id_mmfr2 = 0x00000000;
|
||||||
|
- cpu->id_mmfr3 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x00000030;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x00000000;
|
||||||
|
cpu->isar.id_isar0 = 0x01141110;
|
||||||
|
cpu->isar.id_isar1 = 0x02111000;
|
||||||
|
cpu->isar.id_isar2 = 0x21112231;
|
||||||
|
@@ -1955,10 +1955,10 @@ static void cortex_m33_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x00000210;
|
||||||
|
cpu->isar.id_dfr0 = 0x00200000;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
- cpu->id_mmfr0 = 0x00101F40;
|
||||||
|
- cpu->id_mmfr1 = 0x00000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01000000;
|
||||||
|
- cpu->id_mmfr3 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x00101F40;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01000000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x00000000;
|
||||||
|
cpu->isar.id_isar0 = 0x01101110;
|
||||||
|
cpu->isar.id_isar1 = 0x02212000;
|
||||||
|
cpu->isar.id_isar2 = 0x20232232;
|
||||||
|
@@ -2006,10 +2006,10 @@ static void cortex_r5_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x001;
|
||||||
|
cpu->isar.id_dfr0 = 0x010400;
|
||||||
|
cpu->id_afr0 = 0x0;
|
||||||
|
- cpu->id_mmfr0 = 0x0210030;
|
||||||
|
- cpu->id_mmfr1 = 0x00000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01200000;
|
||||||
|
- cpu->id_mmfr3 = 0x0211;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x0210030;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x00000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01200000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x0211;
|
||||||
|
cpu->isar.id_isar0 = 0x02101111;
|
||||||
|
cpu->isar.id_isar1 = 0x13112111;
|
||||||
|
cpu->isar.id_isar2 = 0x21232141;
|
||||||
|
@@ -2061,10 +2061,10 @@ static void cortex_a8_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x11;
|
||||||
|
cpu->isar.id_dfr0 = 0x400;
|
||||||
|
cpu->id_afr0 = 0;
|
||||||
|
- cpu->id_mmfr0 = 0x31100003;
|
||||||
|
- cpu->id_mmfr1 = 0x20000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01202000;
|
||||||
|
- cpu->id_mmfr3 = 0x11;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x31100003;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x20000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01202000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x11;
|
||||||
|
cpu->isar.id_isar0 = 0x00101111;
|
||||||
|
cpu->isar.id_isar1 = 0x12112111;
|
||||||
|
cpu->isar.id_isar2 = 0x21232031;
|
||||||
|
@@ -2134,10 +2134,10 @@ static void cortex_a9_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x11;
|
||||||
|
cpu->isar.id_dfr0 = 0x000;
|
||||||
|
cpu->id_afr0 = 0;
|
||||||
|
- cpu->id_mmfr0 = 0x00100103;
|
||||||
|
- cpu->id_mmfr1 = 0x20000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01230000;
|
||||||
|
- cpu->id_mmfr3 = 0x00002111;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x00100103;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x20000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01230000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x00002111;
|
||||||
|
cpu->isar.id_isar0 = 0x00101111;
|
||||||
|
cpu->isar.id_isar1 = 0x13112111;
|
||||||
|
cpu->isar.id_isar2 = 0x21232041;
|
||||||
|
@@ -2199,10 +2199,10 @@ static void cortex_a7_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
cpu->isar.id_dfr0 = 0x02010555;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
- cpu->id_mmfr0 = 0x10101105;
|
||||||
|
- cpu->id_mmfr1 = 0x40000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01240000;
|
||||||
|
- cpu->id_mmfr3 = 0x02102211;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x10101105;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x40000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01240000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x02102211;
|
||||||
|
/* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
|
||||||
|
* table 4-41 gives 0x02101110, which includes the arm div insns.
|
||||||
|
*/
|
||||||
|
@@ -2245,10 +2245,10 @@ static void cortex_a15_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
cpu->isar.id_dfr0 = 0x02010555;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
- cpu->id_mmfr0 = 0x10201105;
|
||||||
|
- cpu->id_mmfr1 = 0x20000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01240000;
|
||||||
|
- cpu->id_mmfr3 = 0x02102211;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x10201105;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x20000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01240000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x02102211;
|
||||||
|
cpu->isar.id_isar0 = 0x02101110;
|
||||||
|
cpu->isar.id_isar1 = 0x13112111;
|
||||||
|
cpu->isar.id_isar2 = 0x21232041;
|
||||||
|
@@ -2484,13 +2484,13 @@ static void arm_max_initfn(Object *obj)
|
||||||
|
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
|
||||||
|
cpu->isar.mvfr2 = t;
|
||||||
|
|
||||||
|
- t = cpu->id_mmfr3;
|
||||||
|
+ t = cpu->isar.id_mmfr3;
|
||||||
|
t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
|
||||||
|
- cpu->id_mmfr3 = t;
|
||||||
|
+ cpu->isar.id_mmfr3 = t;
|
||||||
|
|
||||||
|
- t = cpu->id_mmfr4;
|
||||||
|
+ t = cpu->isar.id_mmfr4;
|
||||||
|
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
|
||||||
|
- cpu->id_mmfr4 = t;
|
||||||
|
+ cpu->isar.id_mmfr4 = t;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 3040aa40..a78c30c3 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -857,6 +857,11 @@ struct ARMCPU {
|
||||||
|
uint32_t id_isar4;
|
||||||
|
uint32_t id_isar5;
|
||||||
|
uint32_t id_isar6;
|
||||||
|
+ uint32_t id_mmfr0;
|
||||||
|
+ uint32_t id_mmfr1;
|
||||||
|
+ uint32_t id_mmfr2;
|
||||||
|
+ uint32_t id_mmfr3;
|
||||||
|
+ uint32_t id_mmfr4;
|
||||||
|
uint32_t mvfr0;
|
||||||
|
uint32_t mvfr1;
|
||||||
|
uint32_t mvfr2;
|
||||||
|
@@ -882,11 +887,6 @@ struct ARMCPU {
|
||||||
|
uint64_t pmceid0;
|
||||||
|
uint64_t pmceid1;
|
||||||
|
uint32_t id_afr0;
|
||||||
|
- uint32_t id_mmfr0;
|
||||||
|
- uint32_t id_mmfr1;
|
||||||
|
- uint32_t id_mmfr2;
|
||||||
|
- uint32_t id_mmfr3;
|
||||||
|
- uint32_t id_mmfr4;
|
||||||
|
uint64_t id_aa64afr0;
|
||||||
|
uint64_t id_aa64afr1;
|
||||||
|
uint32_t clidr;
|
||||||
|
@@ -3490,12 +3490,12 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
|
||||||
|
|
||||||
|
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
|
||||||
|
{
|
||||||
|
- return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) != 0;
|
||||||
|
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
|
||||||
|
{
|
||||||
|
- return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
|
||||||
|
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
|
||||||
|
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||||
|
index a0d07fd7..d450b8c8 100644
|
||||||
|
--- a/target/arm/cpu64.c
|
||||||
|
+++ b/target/arm/cpu64.c
|
||||||
|
@@ -125,10 +125,10 @@ static void aarch64_a57_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
cpu->isar.id_dfr0 = 0x03010066;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
- cpu->id_mmfr0 = 0x10101105;
|
||||||
|
- cpu->id_mmfr1 = 0x40000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01260000;
|
||||||
|
- cpu->id_mmfr3 = 0x02102211;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x10101105;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x40000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01260000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x02102211;
|
||||||
|
cpu->isar.id_isar0 = 0x02101110;
|
||||||
|
cpu->isar.id_isar1 = 0x13112111;
|
||||||
|
cpu->isar.id_isar2 = 0x21232042;
|
||||||
|
@@ -179,10 +179,10 @@ static void aarch64_a53_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
cpu->isar.id_dfr0 = 0x03010066;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
- cpu->id_mmfr0 = 0x10101105;
|
||||||
|
- cpu->id_mmfr1 = 0x40000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01260000;
|
||||||
|
- cpu->id_mmfr3 = 0x02102211;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x10101105;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x40000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01260000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x02102211;
|
||||||
|
cpu->isar.id_isar0 = 0x02101110;
|
||||||
|
cpu->isar.id_isar1 = 0x13112111;
|
||||||
|
cpu->isar.id_isar2 = 0x21232042;
|
||||||
|
@@ -233,10 +233,10 @@ static void aarch64_a72_initfn(Object *obj)
|
||||||
|
cpu->id_pfr1 = 0x00011011;
|
||||||
|
cpu->isar.id_dfr0 = 0x03010066;
|
||||||
|
cpu->id_afr0 = 0x00000000;
|
||||||
|
- cpu->id_mmfr0 = 0x10201105;
|
||||||
|
- cpu->id_mmfr1 = 0x40000000;
|
||||||
|
- cpu->id_mmfr2 = 0x01260000;
|
||||||
|
- cpu->id_mmfr3 = 0x02102211;
|
||||||
|
+ cpu->isar.id_mmfr0 = 0x10201105;
|
||||||
|
+ cpu->isar.id_mmfr1 = 0x40000000;
|
||||||
|
+ cpu->isar.id_mmfr2 = 0x01260000;
|
||||||
|
+ cpu->isar.id_mmfr3 = 0x02102211;
|
||||||
|
cpu->isar.id_isar0 = 0x02101110;
|
||||||
|
cpu->isar.id_isar1 = 0x13112111;
|
||||||
|
cpu->isar.id_isar2 = 0x21232042;
|
||||||
|
@@ -383,9 +383,9 @@ static void aarch64_max_initfn(Object *obj)
|
||||||
|
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
|
||||||
|
cpu->isar.id_isar6 = u;
|
||||||
|
|
||||||
|
- u = cpu->id_mmfr3;
|
||||||
|
+ u = cpu->isar.id_mmfr3;
|
||||||
|
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
|
||||||
|
- cpu->id_mmfr3 = u;
|
||||||
|
+ cpu->isar.id_mmfr3 = u;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
|
||||||
|
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||||
|
index 60ff7c0f..49cd7a7e 100644
|
||||||
|
--- a/target/arm/helper.c
|
||||||
|
+++ b/target/arm/helper.c
|
||||||
|
@@ -5906,19 +5906,19 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
|
{ .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = cpu->id_mmfr0 },
|
||||||
|
+ .resetvalue = cpu->isar.id_mmfr0 },
|
||||||
|
{ .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = cpu->id_mmfr1 },
|
||||||
|
+ .resetvalue = cpu->isar.id_mmfr1 },
|
||||||
|
{ .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = cpu->id_mmfr2 },
|
||||||
|
+ .resetvalue = cpu->isar.id_mmfr2 },
|
||||||
|
{ .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = cpu->id_mmfr3 },
|
||||||
|
+ .resetvalue = cpu->isar.id_mmfr3 },
|
||||||
|
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
@@ -5946,7 +5946,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
|
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
- .resetvalue = cpu->id_mmfr4 },
|
||||||
|
+ .resetvalue = cpu->isar.id_mmfr4 },
|
||||||
|
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
|
||||||
|
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
|
||||||
|
.access = PL1_R, .type = ARM_CP_CONST,
|
||||||
|
@@ -6426,7 +6426,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
|
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
|
||||||
|
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
|
||||||
|
/* TTCBR2 is introduced with ARMv8.2-A32HPD. */
|
||||||
|
- if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) {
|
||||||
|
+ if (FIELD_EX32(cpu->isar.id_mmfr4, ID_MMFR4, HPDS) != 0) {
|
||||||
|
define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
|
||||||
|
index ee158830..2247148e 100644
|
||||||
|
--- a/target/arm/kvm32.c
|
||||||
|
+++ b/target/arm/kvm32.c
|
||||||
|
@@ -104,6 +104,23 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
* Fortunately there is not yet anything in there that affects migration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
|
||||||
|
+ ARM_CP15_REG32(0, 0, 1, 4));
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
|
||||||
|
+ ARM_CP15_REG32(0, 0, 1, 5));
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
|
||||||
|
+ ARM_CP15_REG32(0, 0, 1, 6));
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
|
||||||
|
+ ARM_CP15_REG32(0, 0, 1, 7));
|
||||||
|
+ if (read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
|
||||||
|
+ ARM_CP15_REG32(0, 0, 2, 6))) {
|
||||||
|
+ /*
|
||||||
|
+ * Older kernels don't support reading ID_MMFR4 (a new in v8
|
||||||
|
+ * register); assume it's zero.
|
||||||
|
+ */
|
||||||
|
+ ahcf->isar.id_mmfr4 = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
kvm_arm_destroy_scratch_host_vcpu(fdarray);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
|
||||||
|
index b794108a..276d1466 100644
|
||||||
|
--- a/target/arm/kvm64.c
|
||||||
|
+++ b/target/arm/kvm64.c
|
||||||
|
@@ -551,6 +551,14 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
* than skipping the reads and leaving 0, as we must avoid
|
||||||
|
* considering the values in every case.
|
||||||
|
*/
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 1, 4));
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 1, 5));
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 1, 6));
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 1, 7));
|
||||||
|
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 2, 0));
|
||||||
|
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
|
||||||
|
@@ -563,6 +571,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 2, 4));
|
||||||
|
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5,
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 2, 5));
|
||||||
|
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
|
||||||
|
+ ARM64_SYS_REG(3, 0, 0, 2, 6));
|
||||||
|
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6,
|
||||||
|
ARM64_SYS_REG(3, 0, 0, 2, 7));
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
84
target-arm-Update-ID-fields.patch
Normal file
84
target-arm-Update-ID-fields.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
From 47c76d73a435884b66ce6417cb853893099be5eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
Date: Tue, 11 Aug 2020 10:18:57 +0800
|
||||||
|
Subject: [PATCH 8/9] target/arm: Update ID fields
|
||||||
|
|
||||||
|
Update definitions for ID fields, up to ARMv8.6.
|
||||||
|
|
||||||
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||||
|
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
---
|
||||||
|
target/arm/cpu.h | 17 +++++++++++++++++
|
||||||
|
1 file changed, 17 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||||
|
index 068c3fa2..eb875e11 100644
|
||||||
|
--- a/target/arm/cpu.h
|
||||||
|
+++ b/target/arm/cpu.h
|
||||||
|
@@ -1691,6 +1691,8 @@ FIELD(ID_ISAR6, DP, 4, 4)
|
||||||
|
FIELD(ID_ISAR6, FHM, 8, 4)
|
||||||
|
FIELD(ID_ISAR6, SB, 12, 4)
|
||||||
|
FIELD(ID_ISAR6, SPECRES, 16, 4)
|
||||||
|
+FIELD(ID_ISAR6, BF16, 20, 4)
|
||||||
|
+FIELD(ID_ISAR6, I8MM, 24, 4)
|
||||||
|
|
||||||
|
FIELD(ID_MMFR3, CMAINTVA, 0, 4)
|
||||||
|
FIELD(ID_MMFR3, CMAINTSW, 4, 4)
|
||||||
|
@@ -1736,6 +1738,9 @@ FIELD(ID_AA64ISAR1, GPI, 28, 4)
|
||||||
|
FIELD(ID_AA64ISAR1, FRINTTS, 32, 4)
|
||||||
|
FIELD(ID_AA64ISAR1, SB, 36, 4)
|
||||||
|
FIELD(ID_AA64ISAR1, SPECRES, 40, 4)
|
||||||
|
+FIELD(ID_AA64ISAR1, BF16, 44, 4)
|
||||||
|
+FIELD(ID_AA64ISAR1, DGH, 48, 4)
|
||||||
|
+FIELD(ID_AA64ISAR1, I8MM, 52, 4)
|
||||||
|
|
||||||
|
FIELD(ID_AA64PFR0, EL0, 0, 4)
|
||||||
|
FIELD(ID_AA64PFR0, EL1, 4, 4)
|
||||||
|
@@ -1746,11 +1751,18 @@ FIELD(ID_AA64PFR0, ADVSIMD, 20, 4)
|
||||||
|
FIELD(ID_AA64PFR0, GIC, 24, 4)
|
||||||
|
FIELD(ID_AA64PFR0, RAS, 28, 4)
|
||||||
|
FIELD(ID_AA64PFR0, SVE, 32, 4)
|
||||||
|
+FIELD(ID_AA64PFR0, SEL2, 36, 4)
|
||||||
|
+FIELD(ID_AA64PFR0, MPAM, 40, 4)
|
||||||
|
+FIELD(ID_AA64PFR0, AMU, 44, 4)
|
||||||
|
+FIELD(ID_AA64PFR0, DIT, 44, 4)
|
||||||
|
+FIELD(ID_AA64PFR0, CSV2, 56, 4)
|
||||||
|
+FIELD(ID_AA64PFR0, CSV3, 60, 4)
|
||||||
|
|
||||||
|
FIELD(ID_AA64PFR1, BT, 0, 4)
|
||||||
|
FIELD(ID_AA64PFR1, SBSS, 4, 4)
|
||||||
|
FIELD(ID_AA64PFR1, MTE, 8, 4)
|
||||||
|
FIELD(ID_AA64PFR1, RAS_FRAC, 12, 4)
|
||||||
|
+FIELD(ID_AA64PFR1, MPAM_FRAC, 16, 4)
|
||||||
|
|
||||||
|
FIELD(ID_AA64MMFR0, PARANGE, 0, 4)
|
||||||
|
FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4)
|
||||||
|
@@ -1764,6 +1776,8 @@ FIELD(ID_AA64MMFR0, TGRAN16_2, 32, 4)
|
||||||
|
FIELD(ID_AA64MMFR0, TGRAN64_2, 36, 4)
|
||||||
|
FIELD(ID_AA64MMFR0, TGRAN4_2, 40, 4)
|
||||||
|
FIELD(ID_AA64MMFR0, EXS, 44, 4)
|
||||||
|
+FIELD(ID_AA64MMFR0, FGT, 56, 4)
|
||||||
|
+FIELD(ID_AA64MMFR0, ECV, 60, 4)
|
||||||
|
|
||||||
|
FIELD(ID_AA64MMFR1, HAFDBS, 0, 4)
|
||||||
|
FIELD(ID_AA64MMFR1, VMIDBITS, 4, 4)
|
||||||
|
@@ -1773,6 +1787,8 @@ FIELD(ID_AA64MMFR1, LO, 16, 4)
|
||||||
|
FIELD(ID_AA64MMFR1, PAN, 20, 4)
|
||||||
|
FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
|
||||||
|
FIELD(ID_AA64MMFR1, XNX, 28, 4)
|
||||||
|
+FIELD(ID_AA64MMFR1, TWED, 32, 4)
|
||||||
|
+FIELD(ID_AA64MMFR1, ETS, 36, 4)
|
||||||
|
|
||||||
|
FIELD(ID_AA64MMFR2, CNP, 0, 4)
|
||||||
|
FIELD(ID_AA64MMFR2, UAO, 4, 4)
|
||||||
|
@@ -1799,6 +1815,7 @@ FIELD(ID_AA64DFR0, CTX_CMPS, 28, 4)
|
||||||
|
FIELD(ID_AA64DFR0, PMSVER, 32, 4)
|
||||||
|
FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
|
||||||
|
FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)
|
||||||
|
+FIELD(ID_AA64DFR0, MUPMU, 48, 4)
|
||||||
|
|
||||||
|
FIELD(ID_DFR0, COPDBG, 0, 4)
|
||||||
|
FIELD(ID_DFR0, COPSDBG, 4, 4)
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
36
target-arm-Use-FIELD-macros-for-clearing-ID_DFR0-PER.patch
Normal file
36
target-arm-Use-FIELD-macros-for-clearing-ID_DFR0-PER.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From f54cdca97bf86f5ca1df8471bc229b89797b287e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Date: Fri, 14 Feb 2020 17:51:02 +0000
|
||||||
|
Subject: [PATCH 04/13] target/arm: Use FIELD macros for clearing ID_DFR0
|
||||||
|
PERFMON field
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
We already define FIELD macros for ID_DFR0, so use them in the
|
||||||
|
one place where we're doing direct bit value manipulation.
|
||||||
|
|
||||||
|
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
Message-id: 20200214175116.9164-8-peter.maydell@linaro.org
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index dbd05e01..6ad211b1 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1523,7 +1523,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
|
||||||
|
- cpu->id_dfr0 &= ~(0xf << 24);
|
||||||
|
+ cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
|
||||||
|
cpu->pmceid0 = 0;
|
||||||
|
cpu->pmceid1 = 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
1908
target-arm-convert-isar-regs-to-array.patch
Normal file
1908
target-arm-convert-isar-regs-to-array.patch
Normal file
File diff suppressed because it is too large
Load Diff
184
target-arm-introduce-CPU-feature-dependency-mechanis.patch
Normal file
184
target-arm-introduce-CPU-feature-dependency-mechanis.patch
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
From da538bb9d1acc22543a2b7b07ae35a62386bf226 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
Date: Thu, 6 Aug 2020 16:14:46 +0800
|
||||||
|
Subject: [PATCH 5/9] target/arm: introduce CPU feature dependency mechanism
|
||||||
|
|
||||||
|
Some CPU features are dependent on other CPU features. For example,
|
||||||
|
ID_AA64PFR0_EL1.FP field and ID_AA64PFR0_EL1.AdvSIMD must have the same
|
||||||
|
value, which means FP and ADVSIMD are dependent on each other, FPHP and
|
||||||
|
ADVSIMDHP are dependent on each other.
|
||||||
|
|
||||||
|
This commit introduces a mechanism for CPU feature dependency in
|
||||||
|
AArch64. We build a directed graph from the CPU feature dependency
|
||||||
|
relationship, each edge from->to means the `to` CPU feature is dependent
|
||||||
|
on the `from` CPU feature. And we will automatically enable/disable CPU
|
||||||
|
feature according to the directed graph.
|
||||||
|
|
||||||
|
For example, a, b, and c CPU features are in relationship a->b->c, which
|
||||||
|
means c is dependent on b and b is dependent on a. If c is enabled by
|
||||||
|
user, then a and b is enabled automatically. And if a is disabled by
|
||||||
|
user, then b and c is disabled automatically.
|
||||||
|
|
||||||
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||||
|
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 129 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index 3f63312c..d5576538 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1306,6 +1306,103 @@ static struct CPUFeatureInfo cpu_features[] = {
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
+typedef struct CPUFeatureDep {
|
||||||
|
+ CPUFeatureInfo from, to;
|
||||||
|
+} CPUFeatureDep;
|
||||||
|
+
|
||||||
|
+static const CPUFeatureDep feature_dependencies[] = {
|
||||||
|
+ {
|
||||||
|
+ .from = FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
|
||||||
|
+ .to = FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
|
||||||
|
+ .to = FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = {
|
||||||
|
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
|
||||||
|
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ .to = {
|
||||||
|
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
|
||||||
|
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = {
|
||||||
|
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
|
||||||
|
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ .to = {
|
||||||
|
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
|
||||||
|
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+
|
||||||
|
+ .from = FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false),
|
||||||
|
+ .to = {
|
||||||
|
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "pmull", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+
|
||||||
|
+ .from = FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
|
||||||
|
+ .to = {
|
||||||
|
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false),
|
||||||
|
+ .to = {
|
||||||
|
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
|
||||||
|
+ .to = FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
|
||||||
|
+ .to = FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
|
||||||
|
+ .to = FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
|
||||||
|
+ .to = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
|
||||||
|
+ .to = {
|
||||||
|
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .from = {
|
||||||
|
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ .to = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||||
|
void *opaque, Error **errp)
|
||||||
|
{
|
||||||
|
@@ -1342,13 +1439,45 @@ static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
+ if (object_property_get_bool(obj, feat->name, NULL)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
|
||||||
|
feat->shift, feat->length,
|
||||||
|
feat->min_value);
|
||||||
|
+ /* Auto enable the features which current feature is dependent on. */
|
||||||
|
+ for (int i = 0; i < ARRAY_SIZE(feature_dependencies); ++i) {
|
||||||
|
+ const CPUFeatureDep *d = &feature_dependencies[i];
|
||||||
|
+ if (strcmp(d->to.name, feat->name) != 0) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ object_property_set_bool(obj, true, d->from.name, &local_err);
|
||||||
|
+ if (local_err) {
|
||||||
|
+ error_propagate(errp, local_err);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
+ if (!object_property_get_bool(obj, feat->name, NULL)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
|
||||||
|
feat->shift, feat->length,
|
||||||
|
feat->ni_value);
|
||||||
|
+ /* Auto disable the features which are dependent on current feature. */
|
||||||
|
+ for (int i = 0; i < ARRAY_SIZE(feature_dependencies); ++i) {
|
||||||
|
+ const CPUFeatureDep *d = &feature_dependencies[i];
|
||||||
|
+ if (strcmp(d->from.name, feat->name) != 0) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ object_property_set_bool(obj, false, d->to.name, &local_err);
|
||||||
|
+ if (local_err) {
|
||||||
|
+ error_propagate(errp, local_err);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
92
target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch
Normal file
92
target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
From 7ed595242f52d0654982d41a9c2a63be2bc3378e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
Date: Thu, 6 Aug 2020 16:14:55 +0800
|
||||||
|
Subject: [PATCH 6/9] target/arm: introduce KVM_CAP_ARM_CPU_FEATURE
|
||||||
|
|
||||||
|
Introduce KVM_CAP_ARM_CPU_FEATURE to check whether KVM supports to set
|
||||||
|
CPU features in ARM.
|
||||||
|
|
||||||
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||||
|
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
---
|
||||||
|
linux-headers/linux/kvm.h | 2 ++
|
||||||
|
target/arm/cpu.c | 5 +++++
|
||||||
|
target/arm/kvm64.c | 14 ++++++++++++++
|
||||||
|
target/arm/kvm_arm.h | 7 +++++++
|
||||||
|
4 files changed, 28 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
||||||
|
index 744e888e..4844edc3 100644
|
||||||
|
--- a/linux-headers/linux/kvm.h
|
||||||
|
+++ b/linux-headers/linux/kvm.h
|
||||||
|
@@ -995,6 +995,8 @@ struct kvm_ppc_resize_hpt {
|
||||||
|
#define KVM_CAP_ARM_PTRAUTH_ADDRESS 171
|
||||||
|
#define KVM_CAP_ARM_PTRAUTH_GENERIC 172
|
||||||
|
|
||||||
|
+#define KVM_CAP_ARM_CPU_FEATURE 555
|
||||||
|
+
|
||||||
|
#ifdef KVM_CAP_IRQ_ROUTING
|
||||||
|
|
||||||
|
struct kvm_irq_routing_irqchip {
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index d5576538..db46afba 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1427,6 +1427,11 @@ static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||||
|
Error *local_err = NULL;
|
||||||
|
bool value;
|
||||||
|
|
||||||
|
+ if (!kvm_arm_cpu_feature_supported()) {
|
||||||
|
+ warn_report("KVM doesn't support to set CPU feature in arm. "
|
||||||
|
+ "Setting to `%s` is ignored.", name);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
if (dev->realized) {
|
||||||
|
qdev_prop_set_after_realize(dev, name, errp);
|
||||||
|
return;
|
||||||
|
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
|
||||||
|
index 06cf31e8..05345556 100644
|
||||||
|
--- a/target/arm/kvm64.c
|
||||||
|
+++ b/target/arm/kvm64.c
|
||||||
|
@@ -644,6 +644,20 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool kvm_arm_cpu_feature_supported(void)
|
||||||
|
+{
|
||||||
|
+ static bool cpu_feature_initialized;
|
||||||
|
+ static bool cpu_feature_supported;
|
||||||
|
+
|
||||||
|
+ if (!cpu_feature_initialized) {
|
||||||
|
+ cpu_feature_supported = kvm_check_extension(kvm_state,
|
||||||
|
+ KVM_CAP_ARM_CPU_FEATURE);
|
||||||
|
+ cpu_feature_initialized = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return cpu_feature_supported;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
|
||||||
|
|
||||||
|
int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
|
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
|
||||||
|
index 9b7104d6..49e80878 100644
|
||||||
|
--- a/target/arm/kvm_arm.h
|
||||||
|
+++ b/target/arm/kvm_arm.h
|
||||||
|
@@ -239,6 +239,13 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
|
||||||
|
*/
|
||||||
|
void kvm_arm_add_vcpu_properties(Object *obj);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * kvm_arm_cpu_feature_supported:
|
||||||
|
+ *
|
||||||
|
+ * Returns true if KVM can set CPU features and false otherwise.
|
||||||
|
+ */
|
||||||
|
+bool kvm_arm_cpu_feature_supported(void);
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* kvm_arm_get_max_vm_ipa_size:
|
||||||
|
* @ms: Machine state handle
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
373
target-arm-monitor-Introduce-qmp_query_cpu_model_exp.patch
Normal file
373
target-arm-monitor-Introduce-qmp_query_cpu_model_exp.patch
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
From c527fa45dd0bb03c7f35b79ff53f127297f96314 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Jones <drjones@redhat.com>
|
||||||
|
Date: Thu, 31 Oct 2019 15:27:26 +0100
|
||||||
|
Subject: [PATCH 12/13] target/arm/monitor: Introduce
|
||||||
|
qmp_query_cpu_model_expansion
|
||||||
|
|
||||||
|
Add support for the query-cpu-model-expansion QMP command to Arm. We
|
||||||
|
do this selectively, only exposing CPU properties which represent
|
||||||
|
optional CPU features which the user may want to enable/disable.
|
||||||
|
Additionally we restrict the list of queryable cpu models to 'max',
|
||||||
|
'host', or the current type when KVM is in use. And, finally, we only
|
||||||
|
implement expansion type 'full', as Arm does not yet have a "base"
|
||||||
|
CPU type. More details and example queries are described in a new
|
||||||
|
document (docs/arm-cpu-features.rst).
|
||||||
|
|
||||||
|
Note, certainly more features may be added to the list of advertised
|
||||||
|
features, e.g. 'vfp' and 'neon'. The only requirement is that we can
|
||||||
|
detect invalid configurations and emit failures at QMP query time.
|
||||||
|
For 'vfp' and 'neon' this will require some refactoring to share a
|
||||||
|
validation function between the QMP query and the CPU realize
|
||||||
|
functions.
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Jones <drjones@redhat.com>
|
||||||
|
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||||
|
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
|
||||||
|
Message-id: 20191031142734.8590-2-drjones@redhat.com
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
---
|
||||||
|
docs/arm-cpu-features.rst | 137 +++++++++++++++++++++++++++++++++++
|
||||||
|
qapi/machine-target.json | 6 +-
|
||||||
|
target/arm/monitor.c | 145 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 285 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 docs/arm-cpu-features.rst
|
||||||
|
|
||||||
|
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..c79dcffb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/docs/arm-cpu-features.rst
|
||||||
|
@@ -0,0 +1,137 @@
|
||||||
|
+================
|
||||||
|
+ARM CPU Features
|
||||||
|
+================
|
||||||
|
+
|
||||||
|
+Examples of probing and using ARM CPU features
|
||||||
|
+
|
||||||
|
+Introduction
|
||||||
|
+============
|
||||||
|
+
|
||||||
|
+CPU features are optional features that a CPU of supporting type may
|
||||||
|
+choose to implement or not. In QEMU, optional CPU features have
|
||||||
|
+corresponding boolean CPU proprieties that, when enabled, indicate
|
||||||
|
+that the feature is implemented, and, conversely, when disabled,
|
||||||
|
+indicate that it is not implemented. An example of an ARM CPU feature
|
||||||
|
+is the Performance Monitoring Unit (PMU). CPU types such as the
|
||||||
|
+Cortex-A15 and the Cortex-A57, which respectively implement ARM
|
||||||
|
+architecture reference manuals ARMv7-A and ARMv8-A, may both optionally
|
||||||
|
+implement PMUs. For example, if a user wants to use a Cortex-A15 without
|
||||||
|
+a PMU, then the `-cpu` parameter should contain `pmu=off` on the QEMU
|
||||||
|
+command line, i.e. `-cpu cortex-a15,pmu=off`.
|
||||||
|
+
|
||||||
|
+As not all CPU types support all optional CPU features, then whether or
|
||||||
|
+not a CPU property exists depends on the CPU type. For example, CPUs
|
||||||
|
+that implement the ARMv8-A architecture reference manual may optionally
|
||||||
|
+support the AArch32 CPU feature, which may be enabled by disabling the
|
||||||
|
+`aarch64` CPU property. A CPU type such as the Cortex-A15, which does
|
||||||
|
+not implement ARMv8-A, will not have the `aarch64` CPU property.
|
||||||
|
+
|
||||||
|
+QEMU's support may be limited for some CPU features, only partially
|
||||||
|
+supporting the feature or only supporting the feature under certain
|
||||||
|
+configurations. For example, the `aarch64` CPU feature, which, when
|
||||||
|
+disabled, enables the optional AArch32 CPU feature, is only supported
|
||||||
|
+when using the KVM accelerator and when running on a host CPU type that
|
||||||
|
+supports the feature.
|
||||||
|
+
|
||||||
|
+CPU Feature Probing
|
||||||
|
+===================
|
||||||
|
+
|
||||||
|
+Determining which CPU features are available and functional for a given
|
||||||
|
+CPU type is possible with the `query-cpu-model-expansion` QMP command.
|
||||||
|
+Below are some examples where `scripts/qmp/qmp-shell` (see the top comment
|
||||||
|
+block in the script for usage) is used to issue the QMP commands.
|
||||||
|
+
|
||||||
|
+(1) Determine which CPU features are available for the `max` CPU type
|
||||||
|
+ (Note, we started QEMU with qemu-system-aarch64, so `max` is
|
||||||
|
+ implementing the ARMv8-A reference manual in this case)::
|
||||||
|
+
|
||||||
|
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max"}
|
||||||
|
+ { "return": {
|
||||||
|
+ "model": { "name": "max", "props": {
|
||||||
|
+ "pmu": true, "aarch64": true
|
||||||
|
+ }}}}
|
||||||
|
+
|
||||||
|
+We see that the `max` CPU type has the `pmu` and `aarch64` CPU features.
|
||||||
|
+We also see that the CPU features are enabled, as they are all `true`.
|
||||||
|
+
|
||||||
|
+(2) Let's try to disable the PMU::
|
||||||
|
+
|
||||||
|
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"pmu":false}}
|
||||||
|
+ { "return": {
|
||||||
|
+ "model": { "name": "max", "props": {
|
||||||
|
+ "pmu": false, "aarch64": true
|
||||||
|
+ }}}}
|
||||||
|
+
|
||||||
|
+We see it worked, as `pmu` is now `false`.
|
||||||
|
+
|
||||||
|
+(3) Let's try to disable `aarch64`, which enables the AArch32 CPU feature::
|
||||||
|
+
|
||||||
|
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"aarch64":false}}
|
||||||
|
+ {"error": {
|
||||||
|
+ "class": "GenericError", "desc":
|
||||||
|
+ "'aarch64' feature cannot be disabled unless KVM is enabled and 32-bit EL1 is supported"
|
||||||
|
+ }}
|
||||||
|
+
|
||||||
|
+It looks like this feature is limited to a configuration we do not
|
||||||
|
+currently have.
|
||||||
|
+
|
||||||
|
+(4) Let's try probing CPU features for the Cortex-A15 CPU type::
|
||||||
|
+
|
||||||
|
+ (QEMU) query-cpu-model-expansion type=full model={"name":"cortex-a15"}
|
||||||
|
+ {"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}}
|
||||||
|
+
|
||||||
|
+Only the `pmu` CPU feature is available.
|
||||||
|
+
|
||||||
|
+A note about CPU feature dependencies
|
||||||
|
+-------------------------------------
|
||||||
|
+
|
||||||
|
+It's possible for features to have dependencies on other features. I.e.
|
||||||
|
+it may be possible to change one feature at a time without error, but
|
||||||
|
+when attempting to change all features at once an error could occur
|
||||||
|
+depending on the order they are processed. It's also possible changing
|
||||||
|
+all at once doesn't generate an error, because a feature's dependencies
|
||||||
|
+are satisfied with other features, but the same feature cannot be changed
|
||||||
|
+independently without error. For these reasons callers should always
|
||||||
|
+attempt to make their desired changes all at once in order to ensure the
|
||||||
|
+collection is valid.
|
||||||
|
+
|
||||||
|
+A note about CPU models and KVM
|
||||||
|
+-------------------------------
|
||||||
|
+
|
||||||
|
+Named CPU models generally do not work with KVM. There are a few cases
|
||||||
|
+that do work, e.g. using the named CPU model `cortex-a57` with KVM on a
|
||||||
|
+seattle host, but mostly if KVM is enabled the `host` CPU type must be
|
||||||
|
+used. This means the guest is provided all the same CPU features as the
|
||||||
|
+host CPU type has. And, for this reason, the `host` CPU type should
|
||||||
|
+enable all CPU features that the host has by default. Indeed it's even
|
||||||
|
+a bit strange to allow disabling CPU features that the host has when using
|
||||||
|
+the `host` CPU type, but in the absence of CPU models it's the best we can
|
||||||
|
+do if we want to launch guests without all the host's CPU features enabled.
|
||||||
|
+
|
||||||
|
+Enabling KVM also affects the `query-cpu-model-expansion` QMP command. The
|
||||||
|
+affect is not only limited to specific features, as pointed out in example
|
||||||
|
+(3) of "CPU Feature Probing", but also to which CPU types may be expanded.
|
||||||
|
+When KVM is enabled, only the `max`, `host`, and current CPU type may be
|
||||||
|
+expanded. This restriction is necessary as it's not possible to know all
|
||||||
|
+CPU types that may work with KVM, but it does impose a small risk of users
|
||||||
|
+experiencing unexpected errors. For example on a seattle, as mentioned
|
||||||
|
+above, the `cortex-a57` CPU type is also valid when KVM is enabled.
|
||||||
|
+Therefore a user could use the `host` CPU type for the current type, but
|
||||||
|
+then attempt to query `cortex-a57`, however that query will fail with our
|
||||||
|
+restrictions. This shouldn't be an issue though as management layers and
|
||||||
|
+users have been preferring the `host` CPU type for use with KVM for quite
|
||||||
|
+some time. Additionally, if the KVM-enabled QEMU instance running on a
|
||||||
|
+seattle host is using the `cortex-a57` CPU type, then querying `cortex-a57`
|
||||||
|
+will work.
|
||||||
|
+
|
||||||
|
+Using CPU Features
|
||||||
|
+==================
|
||||||
|
+
|
||||||
|
+After determining which CPU features are available and supported for a
|
||||||
|
+given CPU type, then they may be selectively enabled or disabled on the
|
||||||
|
+QEMU command line with that CPU type::
|
||||||
|
+
|
||||||
|
+ $ qemu-system-aarch64 -M virt -cpu max,pmu=off
|
||||||
|
+
|
||||||
|
+The example above disables the PMU for the `max` CPU type.
|
||||||
|
+
|
||||||
|
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
|
||||||
|
index 55310a6a..04623224 100644
|
||||||
|
--- a/qapi/machine-target.json
|
||||||
|
+++ b/qapi/machine-target.json
|
||||||
|
@@ -212,7 +212,7 @@
|
||||||
|
##
|
||||||
|
{ 'struct': 'CpuModelExpansionInfo',
|
||||||
|
'data': { 'model': 'CpuModelInfo' },
|
||||||
|
- 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
|
||||||
|
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_ARM)' }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @query-cpu-model-expansion:
|
||||||
|
@@ -237,7 +237,7 @@
|
||||||
|
# query-cpu-model-expansion while using these is not advised.
|
||||||
|
#
|
||||||
|
# Some architectures may not support all expansion types. s390x supports
|
||||||
|
-# "full" and "static".
|
||||||
|
+# "full" and "static". Arm only supports "full".
|
||||||
|
#
|
||||||
|
# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is
|
||||||
|
# not supported, if the model cannot be expanded, if the model contains
|
||||||
|
@@ -251,7 +251,7 @@
|
||||||
|
'data': { 'type': 'CpuModelExpansionType',
|
||||||
|
'model': 'CpuModelInfo' },
|
||||||
|
'returns': 'CpuModelExpansionInfo',
|
||||||
|
- 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
|
||||||
|
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_ARM)' }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @CpuDefinitionInfo:
|
||||||
|
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
|
||||||
|
index 6ec6dd04..560970de 100644
|
||||||
|
--- a/target/arm/monitor.c
|
||||||
|
+++ b/target/arm/monitor.c
|
||||||
|
@@ -23,7 +23,14 @@
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "hw/boards.h"
|
||||||
|
#include "kvm_arm.h"
|
||||||
|
+#include "qapi/error.h"
|
||||||
|
+#include "qapi/visitor.h"
|
||||||
|
+#include "qapi/qobject-input-visitor.h"
|
||||||
|
+#include "qapi/qapi-commands-machine-target.h"
|
||||||
|
#include "qapi/qapi-commands-misc-target.h"
|
||||||
|
+#include "qapi/qmp/qerror.h"
|
||||||
|
+#include "qapi/qmp/qdict.h"
|
||||||
|
+#include "qom/qom-qobject.h"
|
||||||
|
|
||||||
|
static GICCapability *gic_cap_new(int version)
|
||||||
|
{
|
||||||
|
@@ -82,3 +89,141 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * These are cpu model features we want to advertise. The order here
|
||||||
|
+ * matters as this is the order in which qmp_query_cpu_model_expansion
|
||||||
|
+ * will attempt to set them. If there are dependencies between features,
|
||||||
|
+ * then the order that considers those dependencies must be used.
|
||||||
|
+ */
|
||||||
|
+static const char *cpu_model_advertised_features[] = {
|
||||||
|
+ "aarch64", "pmu",
|
||||||
|
+ NULL
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||||
|
+ CpuModelInfo *model,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ CpuModelExpansionInfo *expansion_info;
|
||||||
|
+ const QDict *qdict_in = NULL;
|
||||||
|
+ QDict *qdict_out;
|
||||||
|
+ ObjectClass *oc;
|
||||||
|
+ Object *obj;
|
||||||
|
+ const char *name;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
|
||||||
|
+ error_setg(errp, "The requested expansion type is not supported");
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!kvm_enabled() && !strcmp(model->name, "host")) {
|
||||||
|
+ error_setg(errp, "The CPU type '%s' requires KVM", model->name);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ oc = cpu_class_by_name(TYPE_ARM_CPU, model->name);
|
||||||
|
+ if (!oc) {
|
||||||
|
+ error_setg(errp, "The CPU type '%s' is not a recognized ARM CPU type",
|
||||||
|
+ model->name);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (kvm_enabled()) {
|
||||||
|
+ const char *cpu_type = current_machine->cpu_type;
|
||||||
|
+ int len = strlen(cpu_type) - strlen(ARM_CPU_TYPE_SUFFIX);
|
||||||
|
+ bool supported = false;
|
||||||
|
+
|
||||||
|
+ if (!strcmp(model->name, "host") || !strcmp(model->name, "max")) {
|
||||||
|
+ /* These are kvmarm's recommended cpu types */
|
||||||
|
+ supported = true;
|
||||||
|
+ } else if (strlen(model->name) == len &&
|
||||||
|
+ !strncmp(model->name, cpu_type, len)) {
|
||||||
|
+ /* KVM is enabled and we're using this type, so it works. */
|
||||||
|
+ supported = true;
|
||||||
|
+ }
|
||||||
|
+ if (!supported) {
|
||||||
|
+ error_setg(errp, "We cannot guarantee the CPU type '%s' works "
|
||||||
|
+ "with KVM on this host", model->name);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (model->props) {
|
||||||
|
+ qdict_in = qobject_to(QDict, model->props);
|
||||||
|
+ if (!qdict_in) {
|
||||||
|
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ obj = object_new(object_class_get_name(oc));
|
||||||
|
+
|
||||||
|
+ if (qdict_in) {
|
||||||
|
+ Visitor *visitor;
|
||||||
|
+ Error *err = NULL;
|
||||||
|
+
|
||||||
|
+ visitor = qobject_input_visitor_new(model->props);
|
||||||
|
+ visit_start_struct(visitor, NULL, NULL, 0, &err);
|
||||||
|
+ if (err) {
|
||||||
|
+ visit_free(visitor);
|
||||||
|
+ object_unref(obj);
|
||||||
|
+ error_propagate(errp, err);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ i = 0;
|
||||||
|
+ while ((name = cpu_model_advertised_features[i++]) != NULL) {
|
||||||
|
+ if (qdict_get(qdict_in, name)) {
|
||||||
|
+ object_property_set(obj, visitor, name, &err);
|
||||||
|
+ if (err) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!err) {
|
||||||
|
+ visit_check_struct(visitor, &err);
|
||||||
|
+ }
|
||||||
|
+ visit_end_struct(visitor, NULL);
|
||||||
|
+ visit_free(visitor);
|
||||||
|
+ if (err) {
|
||||||
|
+ object_unref(obj);
|
||||||
|
+ error_propagate(errp, err);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ expansion_info = g_new0(CpuModelExpansionInfo, 1);
|
||||||
|
+ expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
|
||||||
|
+ expansion_info->model->name = g_strdup(model->name);
|
||||||
|
+
|
||||||
|
+ qdict_out = qdict_new();
|
||||||
|
+
|
||||||
|
+ i = 0;
|
||||||
|
+ while ((name = cpu_model_advertised_features[i++]) != NULL) {
|
||||||
|
+ ObjectProperty *prop = object_property_find(obj, name, NULL);
|
||||||
|
+ if (prop) {
|
||||||
|
+ Error *err = NULL;
|
||||||
|
+ QObject *value;
|
||||||
|
+
|
||||||
|
+ assert(prop->get);
|
||||||
|
+ value = object_property_get_qobject(obj, name, &err);
|
||||||
|
+ assert(!err);
|
||||||
|
+
|
||||||
|
+ qdict_put_obj(qdict_out, name, value);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!qdict_size(qdict_out)) {
|
||||||
|
+ qobject_unref(qdict_out);
|
||||||
|
+ } else {
|
||||||
|
+ expansion_info->model->props = QOBJECT(qdict_out);
|
||||||
|
+ expansion_info->model->has_props = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ object_unref(obj);
|
||||||
|
+
|
||||||
|
+ return expansion_info;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
59
target-arm-monitor-query-cpu-model-expansion-crashed.patch
Normal file
59
target-arm-monitor-query-cpu-model-expansion-crashed.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
From 5d75b922480f3fbefe83b5bb5e241e56a16e1e3e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liang Yan <lyan@suse.com>
|
||||||
|
Date: Fri, 7 Feb 2020 14:04:21 +0000
|
||||||
|
Subject: [PATCH 13/13] target/arm/monitor: query-cpu-model-expansion crashed
|
||||||
|
qemu when using machine type none
|
||||||
|
|
||||||
|
Commit e19afd566781 mentioned that target-arm only supports queryable
|
||||||
|
cpu models 'max', 'host', and the current type when KVM is in use.
|
||||||
|
The logic works well until using machine type none.
|
||||||
|
|
||||||
|
For machine type none, cpu_type will be null if cpu option is not
|
||||||
|
set by command line, strlen(cpu_type) will terminate process.
|
||||||
|
So We add a check above it.
|
||||||
|
|
||||||
|
This won't affect i386 and s390x since they do not use current_cpu.
|
||||||
|
|
||||||
|
Signed-off-by: Liang Yan <lyan@suse.com>
|
||||||
|
Message-id: 20200203134251.12986-1-lyan@suse.com
|
||||||
|
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||||
|
Tested-by: Andrew Jones <drjones@redhat.com>
|
||||||
|
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
---
|
||||||
|
target/arm/monitor.c | 15 +++++++++------
|
||||||
|
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
|
||||||
|
index 560970de..e2b1d117 100644
|
||||||
|
--- a/target/arm/monitor.c
|
||||||
|
+++ b/target/arm/monitor.c
|
||||||
|
@@ -131,17 +131,20 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kvm_enabled()) {
|
||||||
|
- const char *cpu_type = current_machine->cpu_type;
|
||||||
|
- int len = strlen(cpu_type) - strlen(ARM_CPU_TYPE_SUFFIX);
|
||||||
|
bool supported = false;
|
||||||
|
|
||||||
|
if (!strcmp(model->name, "host") || !strcmp(model->name, "max")) {
|
||||||
|
/* These are kvmarm's recommended cpu types */
|
||||||
|
supported = true;
|
||||||
|
- } else if (strlen(model->name) == len &&
|
||||||
|
- !strncmp(model->name, cpu_type, len)) {
|
||||||
|
- /* KVM is enabled and we're using this type, so it works. */
|
||||||
|
- supported = true;
|
||||||
|
+ } else if (current_machine->cpu_type) {
|
||||||
|
+ const char *cpu_type = current_machine->cpu_type;
|
||||||
|
+ int len = strlen(cpu_type) - strlen(ARM_CPU_TYPE_SUFFIX);
|
||||||
|
+
|
||||||
|
+ if (strlen(model->name) == len &&
|
||||||
|
+ !strncmp(model->name, cpu_type, len)) {
|
||||||
|
+ /* KVM is enabled and we're using this type, so it works. */
|
||||||
|
+ supported = true;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (!supported) {
|
||||||
|
error_setg(errp, "We cannot guarantee the CPU type '%s' works "
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
124
target-arm-parse-cpu-feature-related-options.patch
Normal file
124
target-arm-parse-cpu-feature-related-options.patch
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
From dca1df05ce3d6b17d03203fc6fd94e23548216c7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
Date: Thu, 6 Aug 2020 16:14:35 +0800
|
||||||
|
Subject: [PATCH 2/9] target/arm: parse cpu feature related options
|
||||||
|
|
||||||
|
The implementation of CPUClass::parse_features only supports CPU
|
||||||
|
features in "feature=value" format. However, libvirt maybe send us a
|
||||||
|
CPU feature string in "+feature/-feature" format. Hence, we need to
|
||||||
|
override CPUClass::parse_features to support CPU feature string in both
|
||||||
|
"feature=value" and "+feature/-feature" format.
|
||||||
|
|
||||||
|
The logic of AArch64CPUClass::parse_features is similar to that of
|
||||||
|
X86CPUClass::parse_features.
|
||||||
|
|
||||||
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||||
|
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
---
|
||||||
|
target/arm/cpu64.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 83 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||||
|
index fe648752..7de20848 100644
|
||||||
|
--- a/target/arm/cpu64.c
|
||||||
|
+++ b/target/arm/cpu64.c
|
||||||
|
@@ -506,6 +506,88 @@ static void arm_cpu_parse_featurestr(const char *typename, char *features,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
|
||||||
|
+{
|
||||||
|
+ GlobalProperty *prop = g_new0(typeof(*prop), 1);
|
||||||
|
+ prop->driver = typename;
|
||||||
|
+ prop->property = g_strdup(name);
|
||||||
|
+ prop->value = g_strdup(val);
|
||||||
|
+ qdev_prop_register_global(prop);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gint compare_string(gconstpointer a, gconstpointer b)
|
||||||
|
+{
|
||||||
|
+ return g_strcmp0(a, b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static GList *plus_features, *minus_features;
|
||||||
|
+
|
||||||
|
+static void aarch64_cpu_parse_features(const char *typename, char *features,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ GList *l;
|
||||||
|
+ char *featurestr; /* Single 'key=value" string being parsed */
|
||||||
|
+ static bool cpu_globals_initialized;
|
||||||
|
+
|
||||||
|
+ if (cpu_globals_initialized) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ cpu_globals_initialized = true;
|
||||||
|
+
|
||||||
|
+ if (!features) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ for (featurestr = strtok(features, ",");
|
||||||
|
+ featurestr;
|
||||||
|
+ featurestr = strtok(NULL, ",")) {
|
||||||
|
+ const char *name;
|
||||||
|
+ const char *val = NULL;
|
||||||
|
+ char *eq = NULL;
|
||||||
|
+
|
||||||
|
+ /* Compatibility syntax: */
|
||||||
|
+ if (featurestr[0] == '+') {
|
||||||
|
+ plus_features = g_list_append(plus_features,
|
||||||
|
+ g_strdup(featurestr + 1));
|
||||||
|
+ continue;
|
||||||
|
+ } else if (featurestr[0] == '-') {
|
||||||
|
+ minus_features = g_list_append(minus_features,
|
||||||
|
+ g_strdup(featurestr + 1));
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ eq = strchr(featurestr, '=');
|
||||||
|
+ name = featurestr;
|
||||||
|
+ if (eq) {
|
||||||
|
+ *eq++ = 0;
|
||||||
|
+ val = eq;
|
||||||
|
+ } else {
|
||||||
|
+ error_setg(errp, "Unsupported property format: %s", name);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (g_list_find_custom(plus_features, name, compare_string)) {
|
||||||
|
+ warn_report("Ambiguous CPU model string. "
|
||||||
|
+ "Don't mix both \"+%s\" and \"%s=%s\"",
|
||||||
|
+ name, name, val);
|
||||||
|
+ }
|
||||||
|
+ if (g_list_find_custom(minus_features, name, compare_string)) {
|
||||||
|
+ warn_report("Ambiguous CPU model string. "
|
||||||
|
+ "Don't mix both \"-%s\" and \"%s=%s\"",
|
||||||
|
+ name, name, val);
|
||||||
|
+ }
|
||||||
|
+ cpu_add_feat_as_prop(typename, name, val);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (l = plus_features; l; l = l->next) {
|
||||||
|
+ cpu_add_feat_as_prop(typename, l->data, "on");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (l = minus_features; l; l = l->next) {
|
||||||
|
+ cpu_add_feat_as_prop(typename, l->data, "off");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
{
|
||||||
|
CPUClass *cc = CPU_CLASS(oc);
|
||||||
|
@@ -517,6 +599,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
cc->gdb_num_core_regs = 34;
|
||||||
|
cc->gdb_core_xml_file = "aarch64-core.xml";
|
||||||
|
cc->gdb_arch_name = aarch64_gdb_arch_name;
|
||||||
|
+ cc->parse_features = aarch64_cpu_parse_features;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aarch64_cpu_instance_init(Object *obj)
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
398
target-arm-register-CPU-features-for-property.patch
Normal file
398
target-arm-register-CPU-features-for-property.patch
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
From f169b1f76cad9f727c701df853b05ad5e8d7f927 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
Date: Thu, 6 Aug 2020 16:14:37 +0800
|
||||||
|
Subject: [PATCH 3/9] target/arm: register CPU features for property
|
||||||
|
|
||||||
|
The Arm architecture specifies a number of ID registers that are
|
||||||
|
characterized as comprising a set of 4-bit ID fields. Each ID field
|
||||||
|
identifies the presence, and possibly the level of support for, a
|
||||||
|
particular feature in an implementation of the architecture. [1]
|
||||||
|
|
||||||
|
For most of the ID fields, there is a minimum presence value, equal to
|
||||||
|
or higher than which means the corresponding CPU feature is implemented.
|
||||||
|
Hence, we can use the minimum presence value to determine whether a CPU
|
||||||
|
feature is enabled and enable a CPU feature.
|
||||||
|
|
||||||
|
To disable a CPU feature, setting the corresponding ID field to 0x0/0xf
|
||||||
|
(for unsigned/signed field) seems as a good idea. However, it maybe
|
||||||
|
lead to some problems. For example, ID_AA64PFR0_EL1.FP is a signed ID
|
||||||
|
field. ID_AA64PFR0_EL1.FP == 0x0 represents the implementation of FP
|
||||||
|
(floating-point) and ID_AA64PFR0_EL1.FP == 0x1 represents the
|
||||||
|
implementation of FPHP (half-precision floating-point). If
|
||||||
|
ID_AA64PFR0_EL1.FP is set to 0xf when FPHP is disabled (which is also
|
||||||
|
disable FP), guest kernel maybe stuck. Hence, we add a ni_value (means
|
||||||
|
not-implemented value) to disable a CPU feature safely.
|
||||||
|
|
||||||
|
[1] D13.1.3 Principles of the ID scheme for fields in ID registers in
|
||||||
|
DDI.0487
|
||||||
|
|
||||||
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||||
|
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||||
|
---
|
||||||
|
target/arm/cpu.c | 343 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 343 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||||
|
index 5bcdad0c..3f63312c 100644
|
||||||
|
--- a/target/arm/cpu.c
|
||||||
|
+++ b/target/arm/cpu.c
|
||||||
|
@@ -1034,6 +1034,347 @@ static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name,
|
||||||
|
visit_type_uint32(v, name, &cpu->init_svtor, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * CPUFeatureInfo:
|
||||||
|
+ * @reg: The ID register where the ID field is in.
|
||||||
|
+ * @name: The name of the CPU feature.
|
||||||
|
+ * @length: The bit length of the ID field.
|
||||||
|
+ * @shift: The bit shift of the ID field in the ID register.
|
||||||
|
+ * @min_value: The minimum value equal to or larger than which means the CPU
|
||||||
|
+ * feature is implemented.
|
||||||
|
+ * @ni_value: Not-implemented value. It will be set to the ID field when
|
||||||
|
+ * disabling the CPU feature. Usually, it's min_value - 1.
|
||||||
|
+ * @sign: Whether the ID field is signed.
|
||||||
|
+ * @is_32bit: Whether the CPU feature is for 32-bit.
|
||||||
|
+ *
|
||||||
|
+ * In ARM, a CPU feature is described by an ID field, which is a 4-bit field in
|
||||||
|
+ * an ID register.
|
||||||
|
+ */
|
||||||
|
+typedef struct CPUFeatureInfo {
|
||||||
|
+ CPUIDReg reg;
|
||||||
|
+ const char *name;
|
||||||
|
+ int length;
|
||||||
|
+ int shift;
|
||||||
|
+ int min_value;
|
||||||
|
+ int ni_value;
|
||||||
|
+ bool sign;
|
||||||
|
+ bool is_32bit;
|
||||||
|
+} CPUFeatureInfo;
|
||||||
|
+
|
||||||
|
+#define FIELD_INFO(feature_name, id_reg, field, s, min_val, ni_val, is32bit) { \
|
||||||
|
+ .reg = id_reg, \
|
||||||
|
+ .length = R_ ## id_reg ## _ ## field ## _LENGTH, \
|
||||||
|
+ .shift = R_ ## id_reg ## _ ## field ## _SHIFT, \
|
||||||
|
+ .sign = s, \
|
||||||
|
+ .min_value = min_val, \
|
||||||
|
+ .ni_value = ni_val, \
|
||||||
|
+ .name = feature_name, \
|
||||||
|
+ .is_32bit = is32bit, \
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct CPUFeatureInfo cpu_features[] = {
|
||||||
|
+ FIELD_INFO("swap", ID_ISAR0, SWAP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("bitcount", ID_ISAR0, BITCOUNT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("bitfield", ID_ISAR0, BITFIELD, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("cmpbranch", ID_ISAR0, CMPBRANCH, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("coproc", ID_ISAR0, COPROC, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("debug", ID_ISAR0, DEBUG, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("device", ID_ISAR0, DIVIDE, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("endian", ID_ISAR1, ENDIAN, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("except", ID_ISAR1, EXCEPT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("except_ar", ID_ISAR1, EXCEPT_AR, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("extend", ID_ISAR1, EXTEND, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("ifthen", ID_ISAR1, IFTHEN, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("immediate", ID_ISAR1, IMMEDIATE, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("interwork", ID_ISAR1, INTERWORK, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("jazelle", ID_ISAR1, JAZELLE, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("loadstore", ID_ISAR2, LOADSTORE, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("memhint", ID_ISAR2, MEMHINT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("multiaccessint", ID_ISAR2, MULTIACCESSINT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("mult", ID_ISAR2, MULT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("mults", ID_ISAR2, MULTS, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("multu", ID_ISAR2, MULTU, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("psr_ar", ID_ISAR2, PSR_AR, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("reversal", ID_ISAR2, REVERSAL, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("saturate", ID_ISAR3, SATURATE, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("simd", ID_ISAR3, SIMD, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("svc", ID_ISAR3, SVC, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("synchprim", ID_ISAR3, SYNCHPRIM, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("tabbranch", ID_ISAR3, TABBRANCH, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("t32copy", ID_ISAR3, T32COPY, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("truenop", ID_ISAR3, TRUENOP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("t32ee", ID_ISAR3, T32EE, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("unpriv", ID_ISAR4, UNPRIV, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("withshifts", ID_ISAR4, WITHSHIFTS, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("writeback", ID_ISAR4, WRITEBACK, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("smc", ID_ISAR4, SMC, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("barrier", ID_ISAR4, BARRIER, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("synchprim_frac", ID_ISAR4, SYNCHPRIM_FRAC, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("psr_m", ID_ISAR4, PSR_M, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("swp_frac", ID_ISAR4, SWP_FRAC, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("sevl", ID_ISAR5, SEVL, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("aes", ID_ISAR5, AES, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("sha1", ID_ISAR5, SHA1, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("sha2", ID_ISAR5, SHA2, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("crc32", ID_ISAR5, CRC32, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("rdm", ID_ISAR5, RDM, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("vcma", ID_ISAR5, VCMA, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("jscvt", ID_ISAR6, JSCVT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("dp", ID_ISAR6, DP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("bpmaint", ID_MMFR3, BPMAINT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("maintbcst", ID_MMFR3, MAINTBCST, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("pan", ID_MMFR3, PAN, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("cohwalk", ID_MMFR3, COHWALK, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("cmemsz", ID_MMFR3, CMEMSZ, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("supersec", ID_MMFR3, SUPERSEC, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("specsei", ID_MMFR4, SPECSEI, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("ac2", ID_MMFR4, AC2, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("xnx", ID_MMFR4, XNX, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("cnp", ID_MMFR4, CNP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("hpds", ID_MMFR4, HPDS, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("lsm", ID_MMFR4, LSM, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("ccidx", ID_MMFR4, CCIDX, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("evt", ID_MMFR4, EVT, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("simdreg", MVFR0, SIMDREG, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fpsp", MVFR0, FPSP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fpdp", MVFR0, FPDP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fptrap", MVFR0, FPTRAP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fpdivide", MVFR0, FPDIVIDE, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fpsqrt", MVFR0, FPSQRT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fpshvec", MVFR0, FPSHVEC, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fpround", MVFR0, FPROUND, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("fpftz", MVFR1, FPFTZ, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fpdnan", MVFR1, FPDNAN, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("simdls", MVFR1, SIMDLS, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("simdint", MVFR1, SIMDINT, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("simdsp", MVFR1, SIMDSP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("simdhp", MVFR1, SIMDHP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fphp", MVFR1, FPHP, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("simdfmac", MVFR1, SIMDFMAC, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("simdmisc", MVFR2, SIMDMISC, false, 1, 0, true),
|
||||||
|
+ FIELD_INFO("fpmisc", MVFR2, FPMISC, false, 1, 0, true),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("debugver", ID_AA64DFR0, DEBUGVER, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tracever", ID_AA64DFR0, TRACEVER, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("pmuver", ID_AA64DFR0, PMUVER, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("brps", ID_AA64DFR0, BRPS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("wrps", ID_AA64DFR0, WRPS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("ctx_cmps", ID_AA64DFR0, CTX_CMPS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("pmsver", ID_AA64DFR0, PMSVER, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("doublelock", ID_AA64DFR0, DOUBLELOCK, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tracefilt", ID_AA64DFR0, TRACEFILT, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("crc32", ID_AA64ISAR0, CRC32, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("atomics", ID_AA64ISAR0, ATOMIC, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("asimdrdm", ID_AA64ISAR0, RDM, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("asimddp", ID_AA64ISAR0, DP, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("asimdfhm", ID_AA64ISAR0, FHM, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("flagm", ID_AA64ISAR0, TS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tlb", ID_AA64ISAR0, TLB, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("rng", ID_AA64ISAR0, RNDR, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("dcpop", ID_AA64ISAR1, DPB, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("papa", ID_AA64ISAR1, APA, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("api", ID_AA64ISAR1, API, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("jscvt", ID_AA64ISAR1, JSCVT, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("fcma", ID_AA64ISAR1, FCMA, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("pacg", ID_AA64ISAR1, GPA, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("gpi", ID_AA64ISAR1, GPI, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("frint", ID_AA64ISAR1, FRINTTS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("sb", ID_AA64ISAR1, SB, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("specres", ID_AA64ISAR1, SPECRES, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("el0", ID_AA64PFR0, EL0, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("el1", ID_AA64PFR0, EL1, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("el2", ID_AA64PFR0, EL2, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("el3", ID_AA64PFR0, EL3, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
|
||||||
|
+ FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
|
||||||
|
+ FIELD_INFO("gic", ID_AA64PFR0, GIC, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("ras", ID_AA64PFR0, RAS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("sve", ID_AA64PFR0, SVE, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("bti", ID_AA64PFR1, BT, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("sbss", ID_AA64PFR1, SBSS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("mte", ID_AA64PFR1, MTE, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("ras_frac", ID_AA64PFR1, RAS_FRAC, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("parange", ID_AA64MMFR0, PARANGE, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("asidbits", ID_AA64MMFR0, ASIDBITS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("bigend", ID_AA64MMFR0, BIGEND, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("snsmem", ID_AA64MMFR0, SNSMEM, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("bigendel0", ID_AA64MMFR0, BIGENDEL0, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tgran16", ID_AA64MMFR0, TGRAN16, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tgran64", ID_AA64MMFR0, TGRAN64, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tgran4", ID_AA64MMFR0, TGRAN4, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tgran16_2", ID_AA64MMFR0, TGRAN16_2, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tgran64_2", ID_AA64MMFR0, TGRAN64_2, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tgran4_2", ID_AA64MMFR0, TGRAN4_2, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("exs", ID_AA64MMFR0, EXS, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("hafdbs", ID_AA64MMFR1, HAFDBS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("vmidbits", ID_AA64MMFR1, VMIDBITS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("vh", ID_AA64MMFR1, VH, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("hpds", ID_AA64MMFR1, HPDS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("lo", ID_AA64MMFR1, LO, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("pan", ID_AA64MMFR1, PAN, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("specsei", ID_AA64MMFR1, SPECSEI, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("xnx", ID_AA64MMFR1, XNX, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("cnp", ID_AA64MMFR2, CNP, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("uao", ID_AA64MMFR2, UAO, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("lsm", ID_AA64MMFR2, LSM, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("iesb", ID_AA64MMFR2, IESB, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("varange", ID_AA64MMFR2, VARANGE, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("ccidx", ID_AA64MMFR2, CCIDX, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("nv", ID_AA64MMFR2, NV, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("st", ID_AA64MMFR2, ST, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("uscat", ID_AA64MMFR2, AT, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("ids", ID_AA64MMFR2, IDS, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("fwb", ID_AA64MMFR2, FWB, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("ttl", ID_AA64MMFR2, TTL, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("bbm", ID_AA64MMFR2, BBM, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("evt", ID_AA64MMFR2, EVT, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("e0pd", ID_AA64MMFR2, E0PD, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ FIELD_INFO("copdbg", ID_DFR0, COPDBG, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("copsdbg", ID_DFR0, COPSDBG, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("mmapdbg", ID_DFR0, MMAPDBG, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("coptrc", ID_DFR0, COPTRC, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("mmaptrc", ID_DFR0, MMAPTRC, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("mprofdbg", ID_DFR0, MPROFDBG, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("perfmon", ID_DFR0, PERFMON, false, 1, 0, false),
|
||||||
|
+ FIELD_INFO("tracefilt", ID_DFR0, TRACEFILT, false, 1, 0, false),
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
|
||||||
|
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
|
||||||
|
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "pmull", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_TS_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR0_TS_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "flagm2", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_DPB_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR1_DPB_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "dcpodp", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH,
|
||||||
|
+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2,
|
||||||
|
+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||||
|
+ void *opaque, Error **errp)
|
||||||
|
+{
|
||||||
|
+ ARMCPU *cpu = ARM_CPU(obj);
|
||||||
|
+ CPUFeatureInfo *feat = opaque;
|
||||||
|
+ int field_value = feat->sign ? sextract64(cpu->isar.regs[feat->reg],
|
||||||
|
+ feat->shift, feat->length) :
|
||||||
|
+ extract64(cpu->isar.regs[feat->reg],
|
||||||
|
+ feat->shift, feat->length);
|
||||||
|
+ bool value = field_value >= feat->min_value;
|
||||||
|
+
|
||||||
|
+ visit_type_bool(v, name, &value, errp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||||
|
+ void *opaque, Error **errp)
|
||||||
|
+{
|
||||||
|
+ DeviceState *dev = DEVICE(obj);
|
||||||
|
+ ARMCPU *cpu = ARM_CPU(obj);
|
||||||
|
+ ARMISARegisters *isar = &cpu->isar;
|
||||||
|
+ CPUFeatureInfo *feat = opaque;
|
||||||
|
+ Error *local_err = NULL;
|
||||||
|
+ bool value;
|
||||||
|
+
|
||||||
|
+ if (dev->realized) {
|
||||||
|
+ qdev_prop_set_after_realize(dev, name, errp);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ visit_type_bool(v, name, &value, &local_err);
|
||||||
|
+ if (local_err) {
|
||||||
|
+ error_propagate(errp, local_err);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (value) {
|
||||||
|
+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
|
||||||
|
+ feat->shift, feat->length,
|
||||||
|
+ feat->min_value);
|
||||||
|
+ } else {
|
||||||
|
+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
|
||||||
|
+ feat->shift, feat->length,
|
||||||
|
+ feat->ni_value);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void arm_cpu_register_feature_props(ARMCPU *cpu)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ int num = ARRAY_SIZE(cpu_features);
|
||||||
|
+ ObjectProperty *op;
|
||||||
|
+ CPUARMState *env = &cpu->env;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < num; i++) {
|
||||||
|
+ if ((arm_feature(env, ARM_FEATURE_AARCH64) && cpu_features[i].is_32bit)
|
||||||
|
+ || (!arm_feature(env, ARM_FEATURE_AARCH64) &&
|
||||||
|
+ cpu_features[i].is_32bit)) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ op = object_property_find(OBJECT(cpu), cpu_features[i].name, NULL);
|
||||||
|
+ if (!op) {
|
||||||
|
+ object_property_add(OBJECT(cpu), cpu_features[i].name, "bool",
|
||||||
|
+ arm_cpu_get_bit_prop,
|
||||||
|
+ arm_cpu_set_bit_prop,
|
||||||
|
+ NULL, &cpu_features[i], &error_abort);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void arm_cpu_post_init(Object *obj)
|
||||||
|
{
|
||||||
|
ARMCPU *cpu = ARM_CPU(obj);
|
||||||
|
@@ -1150,6 +1491,8 @@ void arm_cpu_post_init(Object *obj)
|
||||||
|
|
||||||
|
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
|
||||||
|
&error_abort);
|
||||||
|
+
|
||||||
|
+ arm_cpu_register_feature_props(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arm_cpu_finalizefn(Object *obj)
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user